Skip to content

Commit 5946224

Browse files
committed
implement vmm_cpu_write_register
1 parent 1de0438 commit 5946224

File tree

2 files changed

+109
-28
lines changed

2 files changed

+109
-28
lines changed

src/hv_kvm.c

Lines changed: 107 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
#include <sys/types.h>
1212

1313
int kvm, vmfd;
14+
struct kvm_run *run;
15+
struct kvm_regs regs;
16+
struct kvm_sregs sregs;
1417

1518
int
1619
vmm_create(void)
@@ -52,7 +55,6 @@ int
5255
vmm_cpu_create(vmm_cpuid_t *cpu)
5356
{
5457
int cpufd;
55-
struct kvm_run *run;
5658
int mmap_size;
5759

5860
if ((cpufd = ioctl(vmfd, KVM_CREATE_VCPU, 0UL)) < 0)
@@ -78,32 +80,113 @@ vmm_cpu_run(vmm_cpuid_t cpu)
7880
return 0;
7981
}
8082

83+
/*
84+
85+
struct kvm_regs {
86+
__u64 rax, rbx, rcx, rdx;
87+
__u64 rsi, rdi, rsp, rbp;
88+
__u64 r8, r9, r10, r11;
89+
__u64 r12, r13, r14, r15;
90+
__u64 rip, rflags;
91+
};
92+
93+
struct kvm_segment {
94+
__u64 base;
95+
__u32 limit;
96+
__u16 selector;
97+
__u8 type;
98+
__u8 present, dpl, db, s, l, g, avl;
99+
__u8 unusable;
100+
__u8 padding;
101+
};
102+
103+
struct kvm_dtable {
104+
__u64 base;
105+
__u16 limit;
106+
__u16 padding[3];
107+
};
108+
109+
struct kvm_sregs {
110+
struct kvm_segment cs, ds, es, fs, gs, ss;
111+
struct kvm_segment tr, ldt;
112+
struct kvm_dtable gdt, idt;
113+
__u64 cr0, cr2, cr3, cr4, cr8;
114+
__u64 efer;
115+
__u64 apic_base;
116+
__u64 interrupt_bitmap[(KVM_NR_INTERRUPTS + 63) / 64];
117+
};
118+
119+
*/
120+
81121
int
82122
vmm_cpu_write_register(vmm_cpuid_t cpu, vmm_x64_reg_t reg, uint64_t value)
83123
{
84-
/* FIXME */
85-
86-
/* Initialize CS to point at 0, via a read-modify-write of sregs. */
87-
ret = ioctl(vcpufd, KVM_GET_SREGS, &sregs);
88-
if (ret == -1)
89-
err(1, "KVM_GET_SREGS");
90-
sregs.cs.base = 0;
91-
sregs.cs.selector = 0;
92-
ret = ioctl(vcpufd, KVM_SET_SREGS, &sregs);
93-
if (ret == -1)
94-
err(1, "KVM_SET_SREGS");
95-
96-
/* Initialize registers: instruction pointer for our code, addends, and
97-
* initial flags required by x86 architecture. */
98-
struct kvm_regs regs = {
99-
.rip = 0x1000,
100-
.rax = 2,
101-
.rbx = 2,
102-
.rflags = 0x2,
103-
};
104-
ret = ioctl(vcpufd, KVM_SET_REGS, &regs);
105-
if (ret == -1)
106-
err(1, "KVM_SET_REGS");
124+
if (ioctl(vcpufd, KVM_GET_REGS, &regs) < 0)
125+
return VMM_ERROR;
126+
if (ioctl(vcpufd, KVM_GET_SREGS, &sregs) < 0)
127+
return VMM_ERROR;
128+
129+
switch (reg) {
130+
case VMM_X64_RIP: regs.rip = value; break;
131+
case VMM_X64_RFLAGS: regs.rflags = value; break;
132+
case VMM_X64_RAX: regs.rax = value; break;
133+
case VMM_X64_RBX: regs.rbx = value; break;
134+
case VMM_X64_RCX: regs.rcx = value; break;
135+
case VMM_X64_RDX: regs.rdx = value; break;
136+
case VMM_X64_RSI: regs.rsi = value; break;
137+
case VMM_X64_RDI: regs.rdi = value; break;
138+
case VMM_X64_RSP: regs.rsp = value; break;
139+
case VMM_X64_RBP: regs.rbp = value; break;
140+
case VMM_X64_R8:
141+
case VMM_X64_R9:
142+
case VMM_X64_R10:
143+
case VMM_X64_R11:
144+
case VMM_X64_R12:
145+
case VMM_X64_R13:
146+
case VMM_X64_R14:
147+
case VMM_X64_R15:
148+
assert(false);
149+
case VMM_X64_CS: sregs.cs.base = value; break;
150+
case VMM_X64_SS:
151+
case VMM_X64_DS:
152+
case VMM_X64_ES:
153+
case VMM_X64_FS:
154+
case VMM_X64_GS:
155+
case VMM_X64_IDT_BASE:
156+
case VMM_X64_IDT_LIMIT:
157+
case VMM_X64_GDT_BASE:
158+
case VMM_X64_GDT_LIMIT:
159+
case VMM_X64_LDTR:
160+
case VMM_X64_LDT_BASE:
161+
case VMM_X64_LDT_LIMIT:
162+
case VMM_X64_LDT_AR:
163+
case VMM_X64_TR:
164+
case VMM_X64_TSS_BASE:
165+
case VMM_X64_TSS_LIMIT:
166+
case VMM_X64_TSS_AR:
167+
case VMM_X64_CR0:
168+
case VMM_X64_CR1:
169+
case VMM_X64_CR2:
170+
case VMM_X64_CR3:
171+
case VMM_X64_CR4:
172+
case VMM_X64_DR0:
173+
case VMM_X64_DR1:
174+
case VMM_X64_DR2:
175+
case VMM_X64_DR3:
176+
case VMM_X64_DR4:
177+
case VMM_X64_DR5:
178+
case VMM_X64_DR6:
179+
case VMM_X64_DR7:
180+
case VMM_X64_TPR:
181+
case VMM_X64_XCR0:
182+
default:
183+
assert(false);
184+
}
185+
186+
if (ioctl(vcpufd, KVM_SET_REGS, &regs) < 0)
187+
return VMM_ERROR;
188+
if (ioctl(vcpufd, KVM_SET_SREGS, &sregs) < 0)
189+
return VMM_ERROR;
107190

108191
return 0;
109192
}

test/main.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@
2424
* IN THE SOFTWARE.
2525
*/
2626

27-
#include <hv.h>
27+
#include "hv.h"
28+
#include <stdio.h>
2829

2930
int main(void)
3031
{
31-
int kvm, vmfd, ret;
3232
unsigned cpu;
3333
const uint8_t code[] = {
3434
0xba, 0xf8, 0x03, /* mov $0x3f8, %dx */
@@ -40,8 +40,6 @@ int main(void)
4040
0xf4, /* hlt */
4141
};
4242
uint8_t *mem;
43-
struct kvm_sregs sregs;
44-
size_t mmap_size;
4543

4644
vmm_create();
4745

0 commit comments

Comments
 (0)