aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/x86.c
diff options
context:
space:
mode:
authorGleb Natapov <gleb@redhat.com>2010-04-28 12:15:37 -0400
committerAvi Kivity <avi@redhat.com>2010-08-01 03:35:34 -0400
commit8fe681e984b6505d4d12125c0776399304803ec7 (patch)
treedcd8b2a739541463cb1b93074bce5968bdb1a288 /arch/x86/kvm/x86.c
parentf181b96d4c769b8915849eb9070c18116fd8d44e (diff)
KVM: do not inject #PF in (read|write)_emulated() callbacks
Return error to x86 emulator instead of injection exception behind its back. Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r--arch/x86/kvm/x86.c28
1 files changed, 14 insertions, 14 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 15a4b754a451..51402d8a46fa 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3346,10 +3346,10 @@ out:
3346static int emulator_read_emulated(unsigned long addr, 3346static int emulator_read_emulated(unsigned long addr,
3347 void *val, 3347 void *val,
3348 unsigned int bytes, 3348 unsigned int bytes,
3349 unsigned int *error_code,
3349 struct kvm_vcpu *vcpu) 3350 struct kvm_vcpu *vcpu)
3350{ 3351{
3351 gpa_t gpa; 3352 gpa_t gpa;
3352 u32 error_code;
3353 3353
3354 if (vcpu->mmio_read_completed) { 3354 if (vcpu->mmio_read_completed) {
3355 memcpy(val, vcpu->mmio_data, bytes); 3355 memcpy(val, vcpu->mmio_data, bytes);
@@ -3359,12 +3359,10 @@ static int emulator_read_emulated(unsigned long addr,
3359 return X86EMUL_CONTINUE; 3359 return X86EMUL_CONTINUE;
3360 } 3360 }
3361 3361
3362 gpa = kvm_mmu_gva_to_gpa_read(vcpu, addr, &error_code); 3362 gpa = kvm_mmu_gva_to_gpa_read(vcpu, addr, error_code);
3363 3363
3364 if (gpa == UNMAPPED_GVA) { 3364 if (gpa == UNMAPPED_GVA)
3365 kvm_inject_page_fault(vcpu, addr, error_code);
3366 return X86EMUL_PROPAGATE_FAULT; 3365 return X86EMUL_PROPAGATE_FAULT;
3367 }
3368 3366
3369 /* For APIC access vmexit */ 3367 /* For APIC access vmexit */
3370 if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE) 3368 if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE)
@@ -3409,17 +3407,15 @@ int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
3409static int emulator_write_emulated_onepage(unsigned long addr, 3407static int emulator_write_emulated_onepage(unsigned long addr,
3410 const void *val, 3408 const void *val,
3411 unsigned int bytes, 3409 unsigned int bytes,
3410 unsigned int *error_code,
3412 struct kvm_vcpu *vcpu) 3411 struct kvm_vcpu *vcpu)
3413{ 3412{
3414 gpa_t gpa; 3413 gpa_t gpa;
3415 u32 error_code;
3416 3414
3417 gpa = kvm_mmu_gva_to_gpa_write(vcpu, addr, &error_code); 3415 gpa = kvm_mmu_gva_to_gpa_write(vcpu, addr, error_code);
3418 3416
3419 if (gpa == UNMAPPED_GVA) { 3417 if (gpa == UNMAPPED_GVA)
3420 kvm_inject_page_fault(vcpu, addr, error_code);
3421 return X86EMUL_PROPAGATE_FAULT; 3418 return X86EMUL_PROPAGATE_FAULT;
3422 }
3423 3419
3424 /* For APIC access vmexit */ 3420 /* For APIC access vmexit */
3425 if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE) 3421 if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE)
@@ -3449,6 +3445,7 @@ mmio:
3449int emulator_write_emulated(unsigned long addr, 3445int emulator_write_emulated(unsigned long addr,
3450 const void *val, 3446 const void *val,
3451 unsigned int bytes, 3447 unsigned int bytes,
3448 unsigned int *error_code,
3452 struct kvm_vcpu *vcpu) 3449 struct kvm_vcpu *vcpu)
3453{ 3450{
3454 /* Crossing a page boundary? */ 3451 /* Crossing a page boundary? */
@@ -3456,14 +3453,16 @@ int emulator_write_emulated(unsigned long addr,
3456 int rc, now; 3453 int rc, now;
3457 3454
3458 now = -addr & ~PAGE_MASK; 3455 now = -addr & ~PAGE_MASK;
3459 rc = emulator_write_emulated_onepage(addr, val, now, vcpu); 3456 rc = emulator_write_emulated_onepage(addr, val, now, error_code,
3457 vcpu);
3460 if (rc != X86EMUL_CONTINUE) 3458 if (rc != X86EMUL_CONTINUE)
3461 return rc; 3459 return rc;
3462 addr += now; 3460 addr += now;
3463 val += now; 3461 val += now;
3464 bytes -= now; 3462 bytes -= now;
3465 } 3463 }
3466 return emulator_write_emulated_onepage(addr, val, bytes, vcpu); 3464 return emulator_write_emulated_onepage(addr, val, bytes, error_code,
3465 vcpu);
3467} 3466}
3468 3467
3469#define CMPXCHG_TYPE(t, ptr, old, new) \ 3468#define CMPXCHG_TYPE(t, ptr, old, new) \
@@ -3480,6 +3479,7 @@ static int emulator_cmpxchg_emulated(unsigned long addr,
3480 const void *old, 3479 const void *old,
3481 const void *new, 3480 const void *new,
3482 unsigned int bytes, 3481 unsigned int bytes,
3482 unsigned int *error_code,
3483 struct kvm_vcpu *vcpu) 3483 struct kvm_vcpu *vcpu)
3484{ 3484{
3485 gpa_t gpa; 3485 gpa_t gpa;
@@ -3533,7 +3533,7 @@ static int emulator_cmpxchg_emulated(unsigned long addr,
3533emul_write: 3533emul_write:
3534 printk_once(KERN_WARNING "kvm: emulating exchange as write\n"); 3534 printk_once(KERN_WARNING "kvm: emulating exchange as write\n");
3535 3535
3536 return emulator_write_emulated(addr, new, bytes, vcpu); 3536 return emulator_write_emulated(addr, new, bytes, error_code, vcpu);
3537} 3537}
3538 3538
3539static int kernel_pio(struct kvm_vcpu *vcpu, void *pd) 3539static int kernel_pio(struct kvm_vcpu *vcpu, void *pd)
@@ -4293,7 +4293,7 @@ int kvm_fix_hypercall(struct kvm_vcpu *vcpu)
4293 4293
4294 kvm_x86_ops->patch_hypercall(vcpu, instruction); 4294 kvm_x86_ops->patch_hypercall(vcpu, instruction);
4295 4295
4296 return emulator_write_emulated(rip, instruction, 3, vcpu); 4296 return emulator_write_emulated(rip, instruction, 3, NULL, vcpu);
4297} 4297}
4298 4298
4299void realmode_lgdt(struct kvm_vcpu *vcpu, u16 limit, unsigned long base) 4299void realmode_lgdt(struct kvm_vcpu *vcpu, u16 limit, unsigned long base)