diff options
author | Avi Kivity <avi@qumranet.com> | 2007-11-25 07:12:03 -0500 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-01-30 10:53:18 -0500 |
commit | c1a5d4f990ce034bcb19aebbb910c07019e60f6b (patch) | |
tree | 23aeb993f99c0b9523486c0dcbedb61247352a45 /drivers/kvm | |
parent | c3c91fee5195ba5176a6da5ddc2a2822243eb79f (diff) |
KVM: Replace #GP injection by the generalized exception queue
Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'drivers/kvm')
-rw-r--r-- | drivers/kvm/svm.c | 17 | ||||
-rw-r--r-- | drivers/kvm/vmx.c | 18 | ||||
-rw-r--r-- | drivers/kvm/x86.c | 43 | ||||
-rw-r--r-- | drivers/kvm/x86.h | 7 | ||||
-rw-r--r-- | drivers/kvm/x86_emulate.c | 4 |
5 files changed, 30 insertions, 59 deletions
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c index aa8e90b404a0..f9769338c621 100644 --- a/drivers/kvm/svm.c +++ b/drivers/kvm/svm.c | |||
@@ -207,17 +207,6 @@ static bool svm_exception_injected(struct kvm_vcpu *vcpu) | |||
207 | return !(svm->vmcb->control.exit_int_info & SVM_EXITINTINFO_VALID); | 207 | return !(svm->vmcb->control.exit_int_info & SVM_EXITINTINFO_VALID); |
208 | } | 208 | } |
209 | 209 | ||
210 | static void svm_inject_gp(struct kvm_vcpu *vcpu, unsigned error_code) | ||
211 | { | ||
212 | struct vcpu_svm *svm = to_svm(vcpu); | ||
213 | |||
214 | svm->vmcb->control.event_inj = SVM_EVTINJ_VALID | | ||
215 | SVM_EVTINJ_VALID_ERR | | ||
216 | SVM_EVTINJ_TYPE_EXEPT | | ||
217 | GP_VECTOR; | ||
218 | svm->vmcb->control.event_inj_err = error_code; | ||
219 | } | ||
220 | |||
221 | static void inject_ud(struct kvm_vcpu *vcpu) | 210 | static void inject_ud(struct kvm_vcpu *vcpu) |
222 | { | 211 | { |
223 | to_svm(vcpu)->vmcb->control.event_inj = SVM_EVTINJ_VALID | | 212 | to_svm(vcpu)->vmcb->control.event_inj = SVM_EVTINJ_VALID | |
@@ -1115,7 +1104,7 @@ static int rdmsr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) | |||
1115 | u64 data; | 1104 | u64 data; |
1116 | 1105 | ||
1117 | if (svm_get_msr(&svm->vcpu, ecx, &data)) | 1106 | if (svm_get_msr(&svm->vcpu, ecx, &data)) |
1118 | svm_inject_gp(&svm->vcpu, 0); | 1107 | kvm_inject_gp(&svm->vcpu, 0); |
1119 | else { | 1108 | else { |
1120 | svm->vmcb->save.rax = data & 0xffffffff; | 1109 | svm->vmcb->save.rax = data & 0xffffffff; |
1121 | svm->vcpu.regs[VCPU_REGS_RDX] = data >> 32; | 1110 | svm->vcpu.regs[VCPU_REGS_RDX] = data >> 32; |
@@ -1176,7 +1165,7 @@ static int wrmsr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) | |||
1176 | | ((u64)(svm->vcpu.regs[VCPU_REGS_RDX] & -1u) << 32); | 1165 | | ((u64)(svm->vcpu.regs[VCPU_REGS_RDX] & -1u) << 32); |
1177 | svm->next_rip = svm->vmcb->save.rip + 2; | 1166 | svm->next_rip = svm->vmcb->save.rip + 2; |
1178 | if (svm_set_msr(&svm->vcpu, ecx, data)) | 1167 | if (svm_set_msr(&svm->vcpu, ecx, data)) |
1179 | svm_inject_gp(&svm->vcpu, 0); | 1168 | kvm_inject_gp(&svm->vcpu, 0); |
1180 | else | 1169 | else |
1181 | skip_emulated_instruction(&svm->vcpu); | 1170 | skip_emulated_instruction(&svm->vcpu); |
1182 | return 1; | 1171 | return 1; |
@@ -1688,8 +1677,6 @@ static struct kvm_x86_ops svm_x86_ops = { | |||
1688 | 1677 | ||
1689 | .tlb_flush = svm_flush_tlb, | 1678 | .tlb_flush = svm_flush_tlb, |
1690 | 1679 | ||
1691 | .inject_gp = svm_inject_gp, | ||
1692 | |||
1693 | .run = svm_vcpu_run, | 1680 | .run = svm_vcpu_run, |
1694 | .handle_exit = handle_exit, | 1681 | .handle_exit = handle_exit, |
1695 | .skip_emulated_instruction = skip_emulated_instruction, | 1682 | .skip_emulated_instruction = skip_emulated_instruction, |
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c index be0b12e709e5..3b3c5f7d2e7c 100644 --- a/drivers/kvm/vmx.c +++ b/drivers/kvm/vmx.c | |||
@@ -613,18 +613,6 @@ static bool vmx_exception_injected(struct kvm_vcpu *vcpu) | |||
613 | return !(vmx->idt_vectoring_info & VECTORING_INFO_VALID_MASK); | 613 | return !(vmx->idt_vectoring_info & VECTORING_INFO_VALID_MASK); |
614 | } | 614 | } |
615 | 615 | ||
616 | static void vmx_inject_gp(struct kvm_vcpu *vcpu, unsigned error_code) | ||
617 | { | ||
618 | printk(KERN_DEBUG "inject_general_protection: rip 0x%lx\n", | ||
619 | vmcs_readl(GUEST_RIP)); | ||
620 | vmcs_write32(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code); | ||
621 | vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, | ||
622 | GP_VECTOR | | ||
623 | INTR_TYPE_EXCEPTION | | ||
624 | INTR_INFO_DELIEVER_CODE_MASK | | ||
625 | INTR_INFO_VALID_MASK); | ||
626 | } | ||
627 | |||
628 | static void vmx_inject_ud(struct kvm_vcpu *vcpu) | 616 | static void vmx_inject_ud(struct kvm_vcpu *vcpu) |
629 | { | 617 | { |
630 | vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, | 618 | vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, |
@@ -2083,7 +2071,7 @@ static int handle_rdmsr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
2083 | u64 data; | 2071 | u64 data; |
2084 | 2072 | ||
2085 | if (vmx_get_msr(vcpu, ecx, &data)) { | 2073 | if (vmx_get_msr(vcpu, ecx, &data)) { |
2086 | vmx_inject_gp(vcpu, 0); | 2074 | kvm_inject_gp(vcpu, 0); |
2087 | return 1; | 2075 | return 1; |
2088 | } | 2076 | } |
2089 | 2077 | ||
@@ -2101,7 +2089,7 @@ static int handle_wrmsr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
2101 | | ((u64)(vcpu->regs[VCPU_REGS_RDX] & -1u) << 32); | 2089 | | ((u64)(vcpu->regs[VCPU_REGS_RDX] & -1u) << 32); |
2102 | 2090 | ||
2103 | if (vmx_set_msr(vcpu, ecx, data) != 0) { | 2091 | if (vmx_set_msr(vcpu, ecx, data) != 0) { |
2104 | vmx_inject_gp(vcpu, 0); | 2092 | kvm_inject_gp(vcpu, 0); |
2105 | return 1; | 2093 | return 1; |
2106 | } | 2094 | } |
2107 | 2095 | ||
@@ -2619,8 +2607,6 @@ static struct kvm_x86_ops vmx_x86_ops = { | |||
2619 | 2607 | ||
2620 | .tlb_flush = vmx_flush_tlb, | 2608 | .tlb_flush = vmx_flush_tlb, |
2621 | 2609 | ||
2622 | .inject_gp = vmx_inject_gp, | ||
2623 | |||
2624 | .run = vmx_vcpu_run, | 2610 | .run = vmx_vcpu_run, |
2625 | .handle_exit = kvm_handle_exit, | 2611 | .handle_exit = kvm_handle_exit, |
2626 | .skip_emulated_instruction = skip_emulated_instruction, | 2612 | .skip_emulated_instruction = skip_emulated_instruction, |
diff --git a/drivers/kvm/x86.c b/drivers/kvm/x86.c index dc007a32a883..6deb052b5f93 100644 --- a/drivers/kvm/x86.c +++ b/drivers/kvm/x86.c | |||
@@ -128,11 +128,6 @@ void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data) | |||
128 | } | 128 | } |
129 | EXPORT_SYMBOL_GPL(kvm_set_apic_base); | 129 | EXPORT_SYMBOL_GPL(kvm_set_apic_base); |
130 | 130 | ||
131 | static void inject_gp(struct kvm_vcpu *vcpu) | ||
132 | { | ||
133 | kvm_x86_ops->inject_gp(vcpu, 0); | ||
134 | } | ||
135 | |||
136 | void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr) | 131 | void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr) |
137 | { | 132 | { |
138 | WARN_ON(vcpu->exception.pending); | 133 | WARN_ON(vcpu->exception.pending); |
@@ -232,20 +227,20 @@ void set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) | |||
232 | if (cr0 & CR0_RESERVED_BITS) { | 227 | if (cr0 & CR0_RESERVED_BITS) { |
233 | printk(KERN_DEBUG "set_cr0: 0x%lx #GP, reserved bits 0x%lx\n", | 228 | printk(KERN_DEBUG "set_cr0: 0x%lx #GP, reserved bits 0x%lx\n", |
234 | cr0, vcpu->cr0); | 229 | cr0, vcpu->cr0); |
235 | inject_gp(vcpu); | 230 | kvm_inject_gp(vcpu, 0); |
236 | return; | 231 | return; |
237 | } | 232 | } |
238 | 233 | ||
239 | if ((cr0 & X86_CR0_NW) && !(cr0 & X86_CR0_CD)) { | 234 | if ((cr0 & X86_CR0_NW) && !(cr0 & X86_CR0_CD)) { |
240 | printk(KERN_DEBUG "set_cr0: #GP, CD == 0 && NW == 1\n"); | 235 | printk(KERN_DEBUG "set_cr0: #GP, CD == 0 && NW == 1\n"); |
241 | inject_gp(vcpu); | 236 | kvm_inject_gp(vcpu, 0); |
242 | return; | 237 | return; |
243 | } | 238 | } |
244 | 239 | ||
245 | if ((cr0 & X86_CR0_PG) && !(cr0 & X86_CR0_PE)) { | 240 | if ((cr0 & X86_CR0_PG) && !(cr0 & X86_CR0_PE)) { |
246 | printk(KERN_DEBUG "set_cr0: #GP, set PG flag " | 241 | printk(KERN_DEBUG "set_cr0: #GP, set PG flag " |
247 | "and a clear PE flag\n"); | 242 | "and a clear PE flag\n"); |
248 | inject_gp(vcpu); | 243 | kvm_inject_gp(vcpu, 0); |
249 | return; | 244 | return; |
250 | } | 245 | } |
251 | 246 | ||
@@ -257,14 +252,14 @@ void set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) | |||
257 | if (!is_pae(vcpu)) { | 252 | if (!is_pae(vcpu)) { |
258 | printk(KERN_DEBUG "set_cr0: #GP, start paging " | 253 | printk(KERN_DEBUG "set_cr0: #GP, start paging " |
259 | "in long mode while PAE is disabled\n"); | 254 | "in long mode while PAE is disabled\n"); |
260 | inject_gp(vcpu); | 255 | kvm_inject_gp(vcpu, 0); |
261 | return; | 256 | return; |
262 | } | 257 | } |
263 | kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l); | 258 | kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l); |
264 | if (cs_l) { | 259 | if (cs_l) { |
265 | printk(KERN_DEBUG "set_cr0: #GP, start paging " | 260 | printk(KERN_DEBUG "set_cr0: #GP, start paging " |
266 | "in long mode while CS.L == 1\n"); | 261 | "in long mode while CS.L == 1\n"); |
267 | inject_gp(vcpu); | 262 | kvm_inject_gp(vcpu, 0); |
268 | return; | 263 | return; |
269 | 264 | ||
270 | } | 265 | } |
@@ -273,7 +268,7 @@ void set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) | |||
273 | if (is_pae(vcpu) && !load_pdptrs(vcpu, vcpu->cr3)) { | 268 | if (is_pae(vcpu) && !load_pdptrs(vcpu, vcpu->cr3)) { |
274 | printk(KERN_DEBUG "set_cr0: #GP, pdptrs " | 269 | printk(KERN_DEBUG "set_cr0: #GP, pdptrs " |
275 | "reserved bits\n"); | 270 | "reserved bits\n"); |
276 | inject_gp(vcpu); | 271 | kvm_inject_gp(vcpu, 0); |
277 | return; | 272 | return; |
278 | } | 273 | } |
279 | 274 | ||
@@ -299,7 +294,7 @@ void set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) | |||
299 | { | 294 | { |
300 | if (cr4 & CR4_RESERVED_BITS) { | 295 | if (cr4 & CR4_RESERVED_BITS) { |
301 | printk(KERN_DEBUG "set_cr4: #GP, reserved bits\n"); | 296 | printk(KERN_DEBUG "set_cr4: #GP, reserved bits\n"); |
302 | inject_gp(vcpu); | 297 | kvm_inject_gp(vcpu, 0); |
303 | return; | 298 | return; |
304 | } | 299 | } |
305 | 300 | ||
@@ -307,19 +302,19 @@ void set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) | |||
307 | if (!(cr4 & X86_CR4_PAE)) { | 302 | if (!(cr4 & X86_CR4_PAE)) { |
308 | printk(KERN_DEBUG "set_cr4: #GP, clearing PAE while " | 303 | printk(KERN_DEBUG "set_cr4: #GP, clearing PAE while " |
309 | "in long mode\n"); | 304 | "in long mode\n"); |
310 | inject_gp(vcpu); | 305 | kvm_inject_gp(vcpu, 0); |
311 | return; | 306 | return; |
312 | } | 307 | } |
313 | } else if (is_paging(vcpu) && !is_pae(vcpu) && (cr4 & X86_CR4_PAE) | 308 | } else if (is_paging(vcpu) && !is_pae(vcpu) && (cr4 & X86_CR4_PAE) |
314 | && !load_pdptrs(vcpu, vcpu->cr3)) { | 309 | && !load_pdptrs(vcpu, vcpu->cr3)) { |
315 | printk(KERN_DEBUG "set_cr4: #GP, pdptrs reserved bits\n"); | 310 | printk(KERN_DEBUG "set_cr4: #GP, pdptrs reserved bits\n"); |
316 | inject_gp(vcpu); | 311 | kvm_inject_gp(vcpu, 0); |
317 | return; | 312 | return; |
318 | } | 313 | } |
319 | 314 | ||
320 | if (cr4 & X86_CR4_VMXE) { | 315 | if (cr4 & X86_CR4_VMXE) { |
321 | printk(KERN_DEBUG "set_cr4: #GP, setting VMXE\n"); | 316 | printk(KERN_DEBUG "set_cr4: #GP, setting VMXE\n"); |
322 | inject_gp(vcpu); | 317 | kvm_inject_gp(vcpu, 0); |
323 | return; | 318 | return; |
324 | } | 319 | } |
325 | kvm_x86_ops->set_cr4(vcpu, cr4); | 320 | kvm_x86_ops->set_cr4(vcpu, cr4); |
@@ -340,7 +335,7 @@ void set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) | |||
340 | if (is_long_mode(vcpu)) { | 335 | if (is_long_mode(vcpu)) { |
341 | if (cr3 & CR3_L_MODE_RESERVED_BITS) { | 336 | if (cr3 & CR3_L_MODE_RESERVED_BITS) { |
342 | printk(KERN_DEBUG "set_cr3: #GP, reserved bits\n"); | 337 | printk(KERN_DEBUG "set_cr3: #GP, reserved bits\n"); |
343 | inject_gp(vcpu); | 338 | kvm_inject_gp(vcpu, 0); |
344 | return; | 339 | return; |
345 | } | 340 | } |
346 | } else { | 341 | } else { |
@@ -348,13 +343,13 @@ void set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) | |||
348 | if (cr3 & CR3_PAE_RESERVED_BITS) { | 343 | if (cr3 & CR3_PAE_RESERVED_BITS) { |
349 | printk(KERN_DEBUG | 344 | printk(KERN_DEBUG |
350 | "set_cr3: #GP, reserved bits\n"); | 345 | "set_cr3: #GP, reserved bits\n"); |
351 | inject_gp(vcpu); | 346 | kvm_inject_gp(vcpu, 0); |
352 | return; | 347 | return; |
353 | } | 348 | } |
354 | if (is_paging(vcpu) && !load_pdptrs(vcpu, cr3)) { | 349 | if (is_paging(vcpu) && !load_pdptrs(vcpu, cr3)) { |
355 | printk(KERN_DEBUG "set_cr3: #GP, pdptrs " | 350 | printk(KERN_DEBUG "set_cr3: #GP, pdptrs " |
356 | "reserved bits\n"); | 351 | "reserved bits\n"); |
357 | inject_gp(vcpu); | 352 | kvm_inject_gp(vcpu, 0); |
358 | return; | 353 | return; |
359 | } | 354 | } |
360 | } | 355 | } |
@@ -375,7 +370,7 @@ void set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) | |||
375 | * to debug) behavior on the guest side. | 370 | * to debug) behavior on the guest side. |
376 | */ | 371 | */ |
377 | if (unlikely(!gfn_to_memslot(vcpu->kvm, cr3 >> PAGE_SHIFT))) | 372 | if (unlikely(!gfn_to_memslot(vcpu->kvm, cr3 >> PAGE_SHIFT))) |
378 | inject_gp(vcpu); | 373 | kvm_inject_gp(vcpu, 0); |
379 | else { | 374 | else { |
380 | vcpu->cr3 = cr3; | 375 | vcpu->cr3 = cr3; |
381 | vcpu->mmu.new_cr3(vcpu); | 376 | vcpu->mmu.new_cr3(vcpu); |
@@ -388,7 +383,7 @@ void set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8) | |||
388 | { | 383 | { |
389 | if (cr8 & CR8_RESERVED_BITS) { | 384 | if (cr8 & CR8_RESERVED_BITS) { |
390 | printk(KERN_DEBUG "set_cr8: #GP, reserved bits 0x%lx\n", cr8); | 385 | printk(KERN_DEBUG "set_cr8: #GP, reserved bits 0x%lx\n", cr8); |
391 | inject_gp(vcpu); | 386 | kvm_inject_gp(vcpu, 0); |
392 | return; | 387 | return; |
393 | } | 388 | } |
394 | if (irqchip_in_kernel(vcpu->kvm)) | 389 | if (irqchip_in_kernel(vcpu->kvm)) |
@@ -436,14 +431,14 @@ static void set_efer(struct kvm_vcpu *vcpu, u64 efer) | |||
436 | if (efer & EFER_RESERVED_BITS) { | 431 | if (efer & EFER_RESERVED_BITS) { |
437 | printk(KERN_DEBUG "set_efer: 0x%llx #GP, reserved bits\n", | 432 | printk(KERN_DEBUG "set_efer: 0x%llx #GP, reserved bits\n", |
438 | efer); | 433 | efer); |
439 | inject_gp(vcpu); | 434 | kvm_inject_gp(vcpu, 0); |
440 | return; | 435 | return; |
441 | } | 436 | } |
442 | 437 | ||
443 | if (is_paging(vcpu) | 438 | if (is_paging(vcpu) |
444 | && (vcpu->shadow_efer & EFER_LME) != (efer & EFER_LME)) { | 439 | && (vcpu->shadow_efer & EFER_LME) != (efer & EFER_LME)) { |
445 | printk(KERN_DEBUG "set_efer: #GP, change LME while paging\n"); | 440 | printk(KERN_DEBUG "set_efer: #GP, change LME while paging\n"); |
446 | inject_gp(vcpu); | 441 | kvm_inject_gp(vcpu, 0); |
447 | return; | 442 | return; |
448 | } | 443 | } |
449 | 444 | ||
@@ -2047,7 +2042,7 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in, | |||
2047 | * String I/O in reverse. Yuck. Kill the guest, fix later. | 2042 | * String I/O in reverse. Yuck. Kill the guest, fix later. |
2048 | */ | 2043 | */ |
2049 | pr_unimpl(vcpu, "guest string pio down\n"); | 2044 | pr_unimpl(vcpu, "guest string pio down\n"); |
2050 | inject_gp(vcpu); | 2045 | kvm_inject_gp(vcpu, 0); |
2051 | return 1; | 2046 | return 1; |
2052 | } | 2047 | } |
2053 | vcpu->run->io.count = now; | 2048 | vcpu->run->io.count = now; |
@@ -2062,7 +2057,7 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in, | |||
2062 | vcpu->pio.guest_pages[i] = page; | 2057 | vcpu->pio.guest_pages[i] = page; |
2063 | mutex_unlock(&vcpu->kvm->lock); | 2058 | mutex_unlock(&vcpu->kvm->lock); |
2064 | if (!page) { | 2059 | if (!page) { |
2065 | inject_gp(vcpu); | 2060 | kvm_inject_gp(vcpu, 0); |
2066 | free_pio_guest_pages(vcpu); | 2061 | free_pio_guest_pages(vcpu); |
2067 | return 1; | 2062 | return 1; |
2068 | } | 2063 | } |
diff --git a/drivers/kvm/x86.h b/drivers/kvm/x86.h index d3ac4e2b3a41..78396d627be0 100644 --- a/drivers/kvm/x86.h +++ b/drivers/kvm/x86.h | |||
@@ -220,8 +220,6 @@ struct kvm_x86_ops { | |||
220 | 220 | ||
221 | void (*tlb_flush)(struct kvm_vcpu *vcpu); | 221 | void (*tlb_flush)(struct kvm_vcpu *vcpu); |
222 | 222 | ||
223 | void (*inject_gp)(struct kvm_vcpu *vcpu, unsigned err_code); | ||
224 | |||
225 | void (*run)(struct kvm_vcpu *vcpu, struct kvm_run *run); | 223 | void (*run)(struct kvm_vcpu *vcpu, struct kvm_run *run); |
226 | int (*handle_exit)(struct kvm_run *run, struct kvm_vcpu *vcpu); | 224 | int (*handle_exit)(struct kvm_run *run, struct kvm_vcpu *vcpu); |
227 | void (*skip_emulated_instruction)(struct kvm_vcpu *vcpu); | 225 | void (*skip_emulated_instruction)(struct kvm_vcpu *vcpu); |
@@ -467,6 +465,11 @@ static inline u32 get_rdx_init_val(void) | |||
467 | return 0x600; /* P6 family */ | 465 | return 0x600; /* P6 family */ |
468 | } | 466 | } |
469 | 467 | ||
468 | static inline void kvm_inject_gp(struct kvm_vcpu *vcpu, u32 error_code) | ||
469 | { | ||
470 | kvm_queue_exception_e(vcpu, GP_VECTOR, error_code); | ||
471 | } | ||
472 | |||
470 | #define ASM_VMX_VMCLEAR_RAX ".byte 0x66, 0x0f, 0xc7, 0x30" | 473 | #define ASM_VMX_VMCLEAR_RAX ".byte 0x66, 0x0f, 0xc7, 0x30" |
471 | #define ASM_VMX_VMLAUNCH ".byte 0x0f, 0x01, 0xc2" | 474 | #define ASM_VMX_VMLAUNCH ".byte 0x0f, 0x01, 0xc2" |
472 | #define ASM_VMX_VMRESUME ".byte 0x0f, 0x01, 0xc3" | 475 | #define ASM_VMX_VMRESUME ".byte 0x0f, 0x01, 0xc3" |
diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c index 3e3eba70d5ac..2e259a847697 100644 --- a/drivers/kvm/x86_emulate.c +++ b/drivers/kvm/x86_emulate.c | |||
@@ -1779,7 +1779,7 @@ twobyte_insn: | |||
1779 | | ((u64)c->regs[VCPU_REGS_RDX] << 32); | 1779 | | ((u64)c->regs[VCPU_REGS_RDX] << 32); |
1780 | rc = kvm_set_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], msr_data); | 1780 | rc = kvm_set_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], msr_data); |
1781 | if (rc) { | 1781 | if (rc) { |
1782 | kvm_x86_ops->inject_gp(ctxt->vcpu, 0); | 1782 | kvm_inject_gp(ctxt->vcpu, 0); |
1783 | c->eip = ctxt->vcpu->rip; | 1783 | c->eip = ctxt->vcpu->rip; |
1784 | } | 1784 | } |
1785 | rc = X86EMUL_CONTINUE; | 1785 | rc = X86EMUL_CONTINUE; |
@@ -1789,7 +1789,7 @@ twobyte_insn: | |||
1789 | /* rdmsr */ | 1789 | /* rdmsr */ |
1790 | rc = kvm_get_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], &msr_data); | 1790 | rc = kvm_get_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], &msr_data); |
1791 | if (rc) { | 1791 | if (rc) { |
1792 | kvm_x86_ops->inject_gp(ctxt->vcpu, 0); | 1792 | kvm_inject_gp(ctxt->vcpu, 0); |
1793 | c->eip = ctxt->vcpu->rip; | 1793 | c->eip = ctxt->vcpu->rip; |
1794 | } else { | 1794 | } else { |
1795 | c->regs[VCPU_REGS_RAX] = (u32)msr_data; | 1795 | c->regs[VCPU_REGS_RAX] = (u32)msr_data; |