aboutsummaryrefslogtreecommitdiffstats
path: root/executor/common_kvm_arm64_syzos.h
diff options
context:
space:
mode:
authorAlexander Potapenko <glider@google.com>2025-06-12 16:21:06 +0200
committerAlexander Potapenko <glider@google.com>2025-06-13 12:27:40 +0000
commitda8f6581624d7c8ffd081b7fbc2f14d7b490a820 (patch)
treec5c5dc5e21579e9f276ac8f673be48bb9530e4c0 /executor/common_kvm_arm64_syzos.h
parentab57262741016e70f3ad66e075edd320d15cb9e2 (diff)
executor: arm64: syzos: add SYZOS_API_ERET, SYZOS_API_SVC
We expect these commands to reach some NV coverage
Diffstat (limited to 'executor/common_kvm_arm64_syzos.h')
-rw-r--r--executor/common_kvm_arm64_syzos.h41
1 files changed, 41 insertions, 0 deletions
diff --git a/executor/common_kvm_arm64_syzos.h b/executor/common_kvm_arm64_syzos.h
index 70074bfbf..615192a39 100644
--- a/executor/common_kvm_arm64_syzos.h
+++ b/executor/common_kvm_arm64_syzos.h
@@ -33,6 +33,8 @@ typedef enum {
SYZOS_API_ITS_SETUP = 130,
SYZOS_API_ITS_SEND_CMD = 170,
SYZOS_API_MRS = 190,
+ SYZOS_API_ERET = 230,
+ SYZOS_API_SVC = 290,
SYZOS_API_STOP, // Must be the last one
} syzos_api_id;
@@ -103,6 +105,8 @@ static void guest_handle_mrs(uint64 reg);
static void guest_handle_msr(uint64 reg, uint64 val);
static void guest_handle_smc(struct api_call_smccc* cmd);
static void guest_handle_hvc(struct api_call_smccc* cmd);
+static void guest_handle_svc(struct api_call_smccc* cmd);
+static void guest_handle_eret(uint64 unused);
static void guest_handle_irq_setup(struct api_call_irq_setup* cmd);
static void guest_handle_memwrite(struct api_call_memwrite* cmd);
static void guest_handle_its_setup(struct api_call_3* cmd);
@@ -149,6 +153,11 @@ guest_main(uint64 size, uint64 cpu)
guest_handle_msr(ccmd->args[0], ccmd->args[1]);
break;
}
+ case SYZOS_API_ERET: {
+ struct api_call_1* ccmd = (struct api_call_1*)cmd;
+ guest_handle_eret(ccmd->arg);
+ break;
+ }
case SYZOS_API_SMC: {
guest_handle_smc((struct api_call_smccc*)cmd);
break;
@@ -157,6 +166,10 @@ guest_main(uint64 size, uint64 cpu)
guest_handle_hvc((struct api_call_smccc*)cmd);
break;
}
+ case SYZOS_API_SVC: {
+ guest_handle_svc((struct api_call_smccc*)cmd);
+ break;
+ }
case SYZOS_API_IRQ_SETUP: {
guest_handle_irq_setup((struct api_call_irq_setup*)cmd);
break;
@@ -243,6 +256,12 @@ guest_handle_mrs(uint64 reg)
: "x0", "x30");
}
+GUEST_CODE static noinline void
+guest_handle_eret(uint64 unused)
+{
+ asm("eret\n" : : : "memory");
+}
+
// Write value to a system register using an MSR instruction.
// The word "MSR" here has nothing to do with the x86 MSR registers.
GUEST_CODE static noinline void
@@ -307,6 +326,28 @@ GUEST_CODE static noinline void guest_handle_hvc(struct api_call_smccc* cmd)
"memory");
}
+GUEST_CODE static noinline void guest_handle_svc(struct api_call_smccc* cmd)
+{
+ asm volatile(
+ "mov x0, %[func_id]\n"
+ "mov x1, %[arg1]\n"
+ "mov x2, %[arg2]\n"
+ "mov x3, %[arg3]\n"
+ "mov x4, %[arg4]\n"
+ "mov x5, %[arg5]\n"
+ // TODO(glider): nonzero immediate values are designated for use by hypervisor vendors.
+ "svc #0\n"
+ : // Ignore the outputs for now
+ : [func_id] "r"((uint64)cmd->func_id),
+ [arg1] "r"(cmd->params[0]), [arg2] "r"(cmd->params[1]),
+ [arg3] "r"(cmd->params[2]), [arg4] "r"(cmd->params[3]),
+ [arg5] "r"(cmd->params[4])
+ : "x0", "x1", "x2", "x3", "x4", "x5",
+ // These registers are not used above, but may be clobbered by the HVC call.
+ "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17",
+ "memory");
+}
+
// VGICv3 setup and IRQ handling code below.
// This code is based on the "Arm Generic Interrupt Controller (GIC) Architecture Specification.
// GIC architecture version 3 and version 4" doc (https://developer.arm.com/documentation/ihi0069/latest/)