Skip to content

Commit 2e16ac1

Browse files
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).
1 parent 796f6c5 commit 2e16ac1

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

executor/common_kvm_amd64_syzos.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ typedef enum {
2828
SYZOS_API_CPUID = 20,
2929
SYZOS_API_WRMSR = 30,
3030
SYZOS_API_RDMSR = 50,
31+
SYZOS_API_WR_CRN = 70,
3132
SYZOS_API_STOP, // Must be the last one
3233
} syzos_api_id;
3334

@@ -67,6 +68,7 @@ static void guest_execute_code(uint8* insns, uint64 size);
6768
static void guest_handle_cpuid(uint32 eax, uint32 ecx);
6869
static void guest_handle_wrmsr(uint64 reg, uint64 val);
6970
static void guest_handle_rdmsr(uint64 reg);
71+
static void guest_handle_wr_crn(struct api_call_2* cmd);
7072

7173
typedef enum {
7274
UEXIT_END = (uint64)-1,
@@ -114,6 +116,10 @@ guest_main(uint64 size, uint64 cpu)
114116
guest_handle_rdmsr(ccmd->arg);
115117
break;
116118
}
119+
case SYZOS_API_WR_CRN: {
120+
guest_handle_wr_crn((struct api_call_2*)cmd);
121+
break;
122+
}
117123
}
118124
addr += cmd->size;
119125
size -= cmd->size;
@@ -174,3 +180,34 @@ GUEST_CODE static noinline void guest_handle_rdmsr(uint64 reg)
174180
: // No explicit clobbers.
175181
);
176182
}
183+
184+
// Write to CRn control register.
185+
GUEST_CODE static noinline void guest_handle_wr_crn(struct api_call_2* cmd)
186+
{
187+
uint64 value = cmd->args[1];
188+
switch (cmd->args[0]) {
189+
case 0:
190+
// Move value to CR0.
191+
asm volatile("movq %0, %%cr0" ::"r"(value) : "memory");
192+
break;
193+
case 2:
194+
// Move value to CR2.
195+
asm volatile("movq %0, %%cr2" ::"r"(value) : "memory");
196+
break;
197+
case 3:
198+
// Move value to CR3.
199+
asm volatile("movq %0, %%cr3" ::"r"(value) : "memory");
200+
break;
201+
case 4:
202+
// Move value to CR4.
203+
asm volatile("movq %0, %%cr4" ::"r"(value) : "memory");
204+
break;
205+
case 8:
206+
// Move value to CR8 (TPR - Task Priority Register).
207+
asm volatile("movq %0, %%cr8" ::"r"(value) : "memory");
208+
break;
209+
default:
210+
// Do nothing.
211+
break;
212+
}
213+
}

sys/linux/dev_kvm_amd64.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,21 @@ syzos_api_rdmsr {
5959
arg_reg flags[msr_index, int64]
6060
}
6161

62+
# CR1 and CR5-7 are reserved.
63+
x86_cr_reg_ids = 0, 2, 3, 4, 8
64+
65+
syzos_api_wr_crn {
66+
arg_reg flags[x86_cr_reg_ids, int64]
67+
arg_value int64
68+
}
69+
6270
syzos_api_call$x86 [
6371
uexit syzos_api$x86[0, intptr]
6472
code syzos_api$x86[10, syzos_api_code$x86]
6573
cpuid syzos_api$x86[20, syzos_api_cpuid]
6674
wrmsr syzos_api$x86[30, syzos_api_wrmsr]
6775
rdmsr syzos_api$x86[50, syzos_api_rdmsr]
76+
wr_crn syzos_api$x86[70, syzos_api_wr_crn]
6877
] [varlen]
6978

7079
kvm_text_x86 [

0 commit comments

Comments
 (0)