summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuyang Huang <yuyanghuang@google.com>2023-11-29 11:21:11 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2023-11-29 11:21:11 +0000
commitd22e40555060c4064a78a8c4bf7ba392f138d46c (patch)
tree7fc098108cb9df82a1e8ab972d5a6cfeb604ae98
parentfb817eadc9c785a73f2f2a628afa8847c130ab23 (diff)
parent22d2d8295b47f750069eae6ef303213e91ec3b07 (diff)
downloadapf-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.h4
-rw-r--r--v5/apf_interpreter.c60
2 files changed, 57 insertions, 7 deletions
diff --git a/v5/apf.h b/v5/apf.h
index a75ab1b..b0b34af 100644
--- a/v5/apf.h
+++ b/v5/apf.h
@@ -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