pipeline: add SWX instruction verifier
authorCristian Dumitrescu <cristian.dumitrescu@intel.com>
Thu, 1 Oct 2020 10:19:55 +0000 (11:19 +0100)
committerDavid Marchand <david.marchand@redhat.com>
Thu, 1 Oct 2020 16:43:08 +0000 (18:43 +0200)
Instruction verifier. Executes at instruction translation time during
SWX pipeline build, i.e. at initialization instead of run-time.

Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
lib/librte_pipeline/rte_swx_pipeline.c

index ef388fe..d51fec8 100644 (file)
@@ -5653,6 +5653,53 @@ instr_jmp_resolve(struct instruction *instructions,
        return 0;
 }
 
+static int
+instr_verify(struct rte_swx_pipeline *p __rte_unused,
+            struct action *a,
+            struct instruction *instr,
+            struct instruction_data *data __rte_unused,
+            uint32_t n_instructions)
+{
+       if (!a) {
+               enum instruction_type type;
+               uint32_t i;
+
+               /* Check that the first instruction is rx. */
+               CHECK(instr[0].type == INSTR_RX, EINVAL);
+
+               /* Check that there is at least one tx instruction. */
+               for (i = 0; i < n_instructions; i++) {
+                       type = instr[i].type;
+
+                       if (instr[i].type == INSTR_TX)
+                               break;
+               }
+               CHECK(i < n_instructions, EINVAL);
+
+               /* Check that the last instruction is either tx or unconditional
+                * jump.
+                */
+               type = instr[n_instructions - 1].type;
+               CHECK((type == INSTR_TX) || (type == INSTR_JMP), EINVAL);
+       }
+
+       if (a) {
+               enum instruction_type type;
+               uint32_t i;
+
+               /* Check that there is at least one return or tx instruction. */
+               for (i = 0; i < n_instructions; i++) {
+                       type = instr[i].type;
+
+                       if ((type == INSTR_RETURN) || (type == INSTR_TX))
+                               break;
+               }
+               CHECK(i < n_instructions, EINVAL);
+       }
+
+       return 0;
+}
+
 static int
 instruction_config(struct rte_swx_pipeline *p,
                   struct action *a,
@@ -5701,6 +5748,10 @@ instruction_config(struct rte_swx_pipeline *p,
        if (err)
                goto error;
 
+       err = instr_verify(p, a, instr, data, n_instructions);
+       if (err)
+               goto error;
+
        err = instr_jmp_resolve(instr, data, n_instructions);
        if (err)
                goto error;