diff options
author | Yuyang Huang <yuyanghuang@google.com> | 2023-11-29 11:21:11 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-11-29 11:21:11 +0000 |
commit | d22e40555060c4064a78a8c4bf7ba392f138d46c (patch) | |
tree | 7fc098108cb9df82a1e8ab972d5a6cfeb604ae98 | |
parent | fb817eadc9c785a73f2f2a628afa8847c130ab23 (diff) | |
parent | 22d2d8295b47f750069eae6ef303213e91ec3b07 (diff) | |
download | apf-d22e40555060c4064a78a8c4bf7ba392f138d46c.tar.gz |
Update apf_interperter to support packet transmit am: 22d2d8295b
Original change: https://android-review.googlesource.com/c/platform/hardware/google/apf/+/2850393
Change-Id: I0750ab09ec51083e5370431254bb67c4cd0ba2e8
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | v5/apf.h | 4 | ||||
-rw-r--r-- | v5/apf_interpreter.c | 60 |
2 files changed, 57 insertions, 7 deletions
@@ -186,6 +186,10 @@ // Copy the data from APF data region to output buffer. The source offset is encoded as [Rx + second imm]. // The copy length is encoded in the third imm. "e.g. EDATACOPY [R0 + 5], 5" #define EDATACOPY 42 +// It is executed as a jump, it tells how many bytes of the program regions +// are used to store the data and followed by the actual data bytes. +// "e.g. data 5, abcde" +#define DATA_EXT_OPCODE 43 #define EXTRACT_OPCODE(i) (((i) >> 3) & 31) #define EXTRACT_REGISTER(i) ((i) & 1) diff --git a/v5/apf_interpreter.c b/v5/apf_interpreter.c index f3b9d36..dd1c620 100644 --- a/v5/apf_interpreter.c +++ b/v5/apf_interpreter.c @@ -17,7 +17,7 @@ #include "apf_interpreter.h" // TODO: Remove the dependency of the standard library and make the interpreter self-contained. -#include <string.h> // For memcmp +#include <string.h>// For memcmp #include "apf.h" @@ -52,6 +52,8 @@ int apf_run(uint8_t* const program, const uint32_t program_len, const uint32_t packet_len, const uint32_t filter_age_16384ths) { // Is offset within program bounds? #define IN_PROGRAM_BOUNDS(p) (ENFORCE_UNSIGNED(p) && (p) < program_len) +// Is offset within ram bounds? +#define IN_RAM_BOUNDS(p) (ENFORCE_UNSIGNED(p) && (p) < ram_len) // Is offset within packet bounds? #define IN_PACKET_BOUNDS(p) (ENFORCE_UNSIGNED(p) && (p) < packet_len) // Is access to offset |p| length |size| within data bounds? @@ -62,6 +64,8 @@ int apf_run(uint8_t* const program, const uint32_t program_len, (p) + (size) >= (p)) // catch wraparounds // Accept packet if not within program bounds #define ASSERT_IN_PROGRAM_BOUNDS(p) ASSERT_RETURN(IN_PROGRAM_BOUNDS(p)) +// Accept packet if not within ram bounds +#define ASSERT_IN_RAM_BOUNDS(p) ASSERT_RETURN(IN_RAM_BOUNDS(p)) // Accept packet if not within packet bounds #define ASSERT_IN_PACKET_BOUNDS(p) ASSERT_RETURN(IN_PACKET_BOUNDS(p)) // Accept packet if not within data bounds @@ -96,6 +100,19 @@ int apf_run(uint8_t* const program, const uint32_t program_len, uint8_t* allocated_buffer = NULL; // The length of the output buffer uint32_t allocate_buffer_len = 0; +// Is access to offset |p| length |size| within output buffer bounds? +#define IN_OUTPUT_BOUNDS(p, size) (ENFORCE_UNSIGNED(p) && \ + ENFORCE_UNSIGNED(size) && \ + (p) + (size) <= allocate_buffer_len && \ + (p) >= 0 && \ + (p) + (size) >= (p)) +// Accept packet if not write within allocated output buffer +#define ASSERT_IN_OUTPUT_BOUNDS(p, size) ASSERT_RETURN(IN_OUTPUT_BOUNDS(p, size)) + +// Decode the imm length. +#define DECODE_IMM(value, length) \ + for (uint32_t i = 0; i < (length) && pc < program_len; i++) \ + value = (value << 8) | program[pc++] do { APF_TRACE_HOOK(pc, registers, program, program_len, packet, packet_len, memory, ram_len); @@ -117,9 +134,7 @@ int apf_run(uint8_t* const program, const uint32_t program_len, if (len_field != 0) { const uint32_t imm_len = 1 << (len_field - 1); ASSERT_FORWARD_IN_PROGRAM(pc + imm_len - 1); - uint32_t i; - for (i = 0; i < imm_len; i++) - imm = (imm << 8) | program[pc++]; + DECODE_IMM(imm, imm_len); // Sign extend imm into signed_imm. signed_imm = imm << ((4 - imm_len) * 8); signed_imm >>= (4 - imm_len) * 8; @@ -182,9 +197,7 @@ int apf_run(uint8_t* const program, const uint32_t program_len, } else if (len_field != 0) { uint32_t cmp_imm_len = 1 << (len_field - 1); ASSERT_FORWARD_IN_PROGRAM(pc + cmp_imm_len - 1); - uint32_t i; - for (i = 0; i < cmp_imm_len; i++) - cmp_imm = (cmp_imm << 8) | program[pc++]; + DECODE_IMM(cmp_imm, cmp_imm_len); } switch (opcode) { case JEQ_OPCODE: @@ -311,6 +324,14 @@ int apf_run(uint8_t* const program, const uint32_t program_len, 0 /* dscp */); allocated_buffer = NULL; break; + case DATA_EXT_OPCODE: { + ASSERT_FORWARD_IN_PROGRAM(pc + 1); + uint32_t skip_len = 0; + DECODE_IMM(skip_len, 2); + ASSERT_FORWARD_IN_PROGRAM(pc + skip_len - 1); + pc += skip_len; + break; + } // Unknown extended opcode default: // Bail out @@ -350,6 +371,31 @@ int apf_run(uint8_t* const program, const uint32_t program_len, } break; } + case MEMCOPY_OPCODE: { + ASSERT_RETURN(allocated_buffer != NULL); + ASSERT_RETURN(len_field > 0); + uint32_t src_offs = imm; + uint32_t copy_len = 0; + DECODE_IMM(copy_len, 1); + uint32_t dst_offs = memory[MEMORY_OFFSET_OUTPUT_BUFFER_OFFSET]; + ASSERT_IN_OUTPUT_BOUNDS(dst_offs, copy_len); + // reg_num == 0 copy from packet, reg_num == 1 copy from data. + if (reg_num == 0) { + ASSERT_IN_PACKET_BOUNDS(src_offs); + const uint32_t last_packet_offs = src_offs + copy_len - 1; + ASSERT_RETURN(last_packet_offs >= src_offs); + ASSERT_IN_PACKET_BOUNDS(last_packet_offs); + memmove(allocated_buffer + dst_offs, packet + src_offs, + copy_len); + } else { + ASSERT_IN_RAM_BOUNDS(src_offs + copy_len - 1); + memmove(allocated_buffer + dst_offs, program + src_offs, + copy_len); + } + dst_offs += copy_len; + memory[MEMORY_OFFSET_OUTPUT_BUFFER_OFFSET] = dst_offs; + break; + } // Unknown opcode default: // Bail out |