diff options
author | Gleb Natapov <gleb@redhat.com> | 2010-04-28 12:15:37 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2010-08-01 03:35:34 -0400 |
commit | 8fe681e984b6505d4d12125c0776399304803ec7 (patch) | |
tree | dcd8b2a739541463cb1b93074bce5968bdb1a288 /arch/x86/kvm/x86.c | |
parent | f181b96d4c769b8915849eb9070c18116fd8d44e (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.c | 28 |
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: | |||
3346 | static int emulator_read_emulated(unsigned long addr, | 3346 | static 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, | |||
3409 | static int emulator_write_emulated_onepage(unsigned long addr, | 3407 | static 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: | |||
3449 | int emulator_write_emulated(unsigned long addr, | 3445 | int 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, | |||
3533 | emul_write: | 3533 | emul_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 | ||
3539 | static int kernel_pio(struct kvm_vcpu *vcpu, void *pd) | 3539 | static 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 | ||
4299 | void realmode_lgdt(struct kvm_vcpu *vcpu, u16 limit, unsigned long base) | 4299 | void realmode_lgdt(struct kvm_vcpu *vcpu, u16 limit, unsigned long base) |