1111#include <sys/types.h>
1212
1313int kvm , vmfd ;
14+ struct kvm_run * run ;
15+ struct kvm_regs regs ;
16+ struct kvm_sregs sregs ;
1417
1518int
1619vmm_create (void )
5255vmm_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+
81121int
82122vmm_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}
0 commit comments