aboutsummaryrefslogtreecommitdiffstats
path: root/executor/common_kvm_amd64_syzos.h
diff options
context:
space:
mode:
authorAlexander Potapenko <glider@google.com>2025-07-23 16:50:59 +0200
committerAlexander Potapenko <glider@google.com>2025-07-24 12:46:04 +0000
commit2e16ac1977e641846ba0ef0cc7558a5e9a1ea946 (patch)
tree81479ab75aa082a0677df1ed7505391404e84238 /executor/common_kvm_amd64_syzos.h
parent796f6c5861b465fbe4e4fd608a2a61534ecb8d05 (diff)
sys/linux: executor: implement SYZOS_API_WR_CRN on x86
Add a SYZOS call to write to one of the system registers (CR0, CR2, CR3, CR4, CR8).
Diffstat (limited to 'executor/common_kvm_amd64_syzos.h')
-rw-r--r--executor/common_kvm_amd64_syzos.h37
1 files changed, 37 insertions, 0 deletions
diff --git a/executor/common_kvm_amd64_syzos.h b/executor/common_kvm_amd64_syzos.h
index 41915a84b..828cdebff 100644
--- a/executor/common_kvm_amd64_syzos.h
+++ b/executor/common_kvm_amd64_syzos.h
@@ -28,6 +28,7 @@ typedef enum {
SYZOS_API_CPUID = 20,
SYZOS_API_WRMSR = 30,
SYZOS_API_RDMSR = 50,
+ SYZOS_API_WR_CRN = 70,
SYZOS_API_STOP, // Must be the last one
} syzos_api_id;
@@ -67,6 +68,7 @@ static void guest_execute_code(uint8* insns, uint64 size);
static void guest_handle_cpuid(uint32 eax, uint32 ecx);
static void guest_handle_wrmsr(uint64 reg, uint64 val);
static void guest_handle_rdmsr(uint64 reg);
+static void guest_handle_wr_crn(struct api_call_2* cmd);
typedef enum {
UEXIT_END = (uint64)-1,
@@ -114,6 +116,10 @@ guest_main(uint64 size, uint64 cpu)
guest_handle_rdmsr(ccmd->arg);
break;
}
+ case SYZOS_API_WR_CRN: {
+ guest_handle_wr_crn((struct api_call_2*)cmd);
+ break;
+ }
}
addr += cmd->size;
size -= cmd->size;
@@ -174,3 +180,34 @@ GUEST_CODE static noinline void guest_handle_rdmsr(uint64 reg)
: // No explicit clobbers.
);
}
+
+// Write to CRn control register.
+GUEST_CODE static noinline void guest_handle_wr_crn(struct api_call_2* cmd)
+{
+ uint64 value = cmd->args[1];
+ switch (cmd->args[0]) {
+ case 0:
+ // Move value to CR0.
+ asm volatile("movq %0, %%cr0" ::"r"(value) : "memory");
+ break;
+ case 2:
+ // Move value to CR2.
+ asm volatile("movq %0, %%cr2" ::"r"(value) : "memory");
+ break;
+ case 3:
+ // Move value to CR3.
+ asm volatile("movq %0, %%cr3" ::"r"(value) : "memory");
+ break;
+ case 4:
+ // Move value to CR4.
+ asm volatile("movq %0, %%cr4" ::"r"(value) : "memory");
+ break;
+ case 8:
+ // Move value to CR8 (TPR - Task Priority Register).
+ asm volatile("movq %0, %%cr8" ::"r"(value) : "memory");
+ break;
+ default:
+ // Do nothing.
+ break;
+ }
+}