diff options
| author | Alexander Potapenko <glider@google.com> | 2025-07-23 16:50:59 +0200 |
|---|---|---|
| committer | Alexander Potapenko <glider@google.com> | 2025-07-24 12:46:04 +0000 |
| commit | 2e16ac1977e641846ba0ef0cc7558a5e9a1ea946 (patch) | |
| tree | 81479ab75aa082a0677df1ed7505391404e84238 /executor/common_kvm_amd64_syzos.h | |
| parent | 796f6c5861b465fbe4e4fd608a2a61534ecb8d05 (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.h | 37 |
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; + } +} |
