diff options
author | Avi Kivity <avi@redhat.com> | 2010-11-22 10:53:26 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2011-01-12 04:29:59 -0500 |
commit | ab9ae3138789afacd133a9c4b3d7a3f1578e25c7 (patch) | |
tree | 27c81b48c395dffd2049b37bafef940573ae6841 /arch/x86/kvm/x86.c | |
parent | 35d3d4a1dd2c1ffd6f2481f6d8ad6c358bb22f07 (diff) |
KVM: Push struct x86_exception info the various gva_to_gpa variants
Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r-- | arch/x86/kvm/x86.c | 52 |
1 files changed, 22 insertions, 30 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 8311ed909c49..a7a7decba43f 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -3603,51 +3603,47 @@ static gpa_t translate_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u32 access) | |||
3603 | static gpa_t translate_nested_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u32 access) | 3603 | static gpa_t translate_nested_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u32 access) |
3604 | { | 3604 | { |
3605 | gpa_t t_gpa; | 3605 | gpa_t t_gpa; |
3606 | u32 error; | 3606 | struct x86_exception exception; |
3607 | 3607 | ||
3608 | BUG_ON(!mmu_is_nested(vcpu)); | 3608 | BUG_ON(!mmu_is_nested(vcpu)); |
3609 | 3609 | ||
3610 | /* NPT walks are always user-walks */ | 3610 | /* NPT walks are always user-walks */ |
3611 | access |= PFERR_USER_MASK; | 3611 | access |= PFERR_USER_MASK; |
3612 | t_gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, gpa, access, &error); | 3612 | t_gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, gpa, access, &exception); |
3613 | if (t_gpa == UNMAPPED_GVA) | 3613 | if (t_gpa == UNMAPPED_GVA) |
3614 | vcpu->arch.fault.nested = true; | 3614 | vcpu->arch.fault.nested = true; |
3615 | 3615 | ||
3616 | return t_gpa; | 3616 | return t_gpa; |
3617 | } | 3617 | } |
3618 | 3618 | ||
3619 | gpa_t kvm_mmu_gva_to_gpa_read(struct kvm_vcpu *vcpu, gva_t gva, u32 *error) | 3619 | gpa_t kvm_mmu_gva_to_gpa_read(struct kvm_vcpu *vcpu, gva_t gva, |
3620 | struct x86_exception *exception) | ||
3620 | { | 3621 | { |
3621 | u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0; | 3622 | u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0; |
3622 | return vcpu->arch.walk_mmu->gva_to_gpa(vcpu, gva, access, error); | 3623 | return vcpu->arch.walk_mmu->gva_to_gpa(vcpu, gva, access, exception); |
3623 | } | 3624 | } |
3624 | 3625 | ||
3625 | gpa_t kvm_mmu_gva_to_gpa_fetch(struct kvm_vcpu *vcpu, gva_t gva, u32 *error) | 3626 | gpa_t kvm_mmu_gva_to_gpa_fetch(struct kvm_vcpu *vcpu, gva_t gva, |
3627 | struct x86_exception *exception) | ||
3626 | { | 3628 | { |
3627 | u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0; | 3629 | u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0; |
3628 | access |= PFERR_FETCH_MASK; | 3630 | access |= PFERR_FETCH_MASK; |
3629 | return vcpu->arch.walk_mmu->gva_to_gpa(vcpu, gva, access, error); | 3631 | return vcpu->arch.walk_mmu->gva_to_gpa(vcpu, gva, access, exception); |
3630 | } | 3632 | } |
3631 | 3633 | ||
3632 | gpa_t kvm_mmu_gva_to_gpa_write(struct kvm_vcpu *vcpu, gva_t gva, u32 *error) | 3634 | gpa_t kvm_mmu_gva_to_gpa_write(struct kvm_vcpu *vcpu, gva_t gva, |
3635 | struct x86_exception *exception) | ||
3633 | { | 3636 | { |
3634 | u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0; | 3637 | u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0; |
3635 | access |= PFERR_WRITE_MASK; | 3638 | access |= PFERR_WRITE_MASK; |
3636 | return vcpu->arch.walk_mmu->gva_to_gpa(vcpu, gva, access, error); | 3639 | return vcpu->arch.walk_mmu->gva_to_gpa(vcpu, gva, access, exception); |
3637 | } | 3640 | } |
3638 | 3641 | ||
3639 | /* uses this to access any guest's mapped memory without checking CPL */ | 3642 | /* uses this to access any guest's mapped memory without checking CPL */ |
3640 | gpa_t kvm_mmu_gva_to_gpa_system(struct kvm_vcpu *vcpu, gva_t gva, u32 *error) | 3643 | gpa_t kvm_mmu_gva_to_gpa_system(struct kvm_vcpu *vcpu, gva_t gva, |
3641 | { | 3644 | struct x86_exception *exception) |
3642 | return vcpu->arch.walk_mmu->gva_to_gpa(vcpu, gva, 0, error); | ||
3643 | } | ||
3644 | |||
3645 | static int make_page_fault(struct x86_exception *exception, u32 error) | ||
3646 | { | 3645 | { |
3647 | exception->vector = PF_VECTOR; | 3646 | return vcpu->arch.walk_mmu->gva_to_gpa(vcpu, gva, 0, exception); |
3648 | exception->error_code_valid = true; | ||
3649 | exception->error_code = error; | ||
3650 | return X86EMUL_PROPAGATE_FAULT; | ||
3651 | } | 3647 | } |
3652 | 3648 | ||
3653 | static int kvm_read_guest_virt_helper(gva_t addr, void *val, unsigned int bytes, | 3649 | static int kvm_read_guest_virt_helper(gva_t addr, void *val, unsigned int bytes, |
@@ -3656,17 +3652,16 @@ static int kvm_read_guest_virt_helper(gva_t addr, void *val, unsigned int bytes, | |||
3656 | { | 3652 | { |
3657 | void *data = val; | 3653 | void *data = val; |
3658 | int r = X86EMUL_CONTINUE; | 3654 | int r = X86EMUL_CONTINUE; |
3659 | u32 error; | ||
3660 | 3655 | ||
3661 | while (bytes) { | 3656 | while (bytes) { |
3662 | gpa_t gpa = vcpu->arch.walk_mmu->gva_to_gpa(vcpu, addr, access, | 3657 | gpa_t gpa = vcpu->arch.walk_mmu->gva_to_gpa(vcpu, addr, access, |
3663 | &error); | 3658 | exception); |
3664 | unsigned offset = addr & (PAGE_SIZE-1); | 3659 | unsigned offset = addr & (PAGE_SIZE-1); |
3665 | unsigned toread = min(bytes, (unsigned)PAGE_SIZE - offset); | 3660 | unsigned toread = min(bytes, (unsigned)PAGE_SIZE - offset); |
3666 | int ret; | 3661 | int ret; |
3667 | 3662 | ||
3668 | if (gpa == UNMAPPED_GVA) | 3663 | if (gpa == UNMAPPED_GVA) |
3669 | return make_page_fault(exception, error); | 3664 | return X86EMUL_PROPAGATE_FAULT; |
3670 | ret = kvm_read_guest(vcpu->kvm, gpa, data, toread); | 3665 | ret = kvm_read_guest(vcpu->kvm, gpa, data, toread); |
3671 | if (ret < 0) { | 3666 | if (ret < 0) { |
3672 | r = X86EMUL_IO_NEEDED; | 3667 | r = X86EMUL_IO_NEEDED; |
@@ -3715,18 +3710,17 @@ static int kvm_write_guest_virt_system(gva_t addr, void *val, | |||
3715 | { | 3710 | { |
3716 | void *data = val; | 3711 | void *data = val; |
3717 | int r = X86EMUL_CONTINUE; | 3712 | int r = X86EMUL_CONTINUE; |
3718 | u32 error; | ||
3719 | 3713 | ||
3720 | while (bytes) { | 3714 | while (bytes) { |
3721 | gpa_t gpa = vcpu->arch.walk_mmu->gva_to_gpa(vcpu, addr, | 3715 | gpa_t gpa = vcpu->arch.walk_mmu->gva_to_gpa(vcpu, addr, |
3722 | PFERR_WRITE_MASK, | 3716 | PFERR_WRITE_MASK, |
3723 | &error); | 3717 | exception); |
3724 | unsigned offset = addr & (PAGE_SIZE-1); | 3718 | unsigned offset = addr & (PAGE_SIZE-1); |
3725 | unsigned towrite = min(bytes, (unsigned)PAGE_SIZE - offset); | 3719 | unsigned towrite = min(bytes, (unsigned)PAGE_SIZE - offset); |
3726 | int ret; | 3720 | int ret; |
3727 | 3721 | ||
3728 | if (gpa == UNMAPPED_GVA) | 3722 | if (gpa == UNMAPPED_GVA) |
3729 | return make_page_fault(exception, error); | 3723 | return X86EMUL_PROPAGATE_FAULT; |
3730 | ret = kvm_write_guest(vcpu->kvm, gpa, data, towrite); | 3724 | ret = kvm_write_guest(vcpu->kvm, gpa, data, towrite); |
3731 | if (ret < 0) { | 3725 | if (ret < 0) { |
3732 | r = X86EMUL_IO_NEEDED; | 3726 | r = X86EMUL_IO_NEEDED; |
@@ -3748,7 +3742,6 @@ static int emulator_read_emulated(unsigned long addr, | |||
3748 | struct kvm_vcpu *vcpu) | 3742 | struct kvm_vcpu *vcpu) |
3749 | { | 3743 | { |
3750 | gpa_t gpa; | 3744 | gpa_t gpa; |
3751 | u32 error_code; | ||
3752 | 3745 | ||
3753 | if (vcpu->mmio_read_completed) { | 3746 | if (vcpu->mmio_read_completed) { |
3754 | memcpy(val, vcpu->mmio_data, bytes); | 3747 | memcpy(val, vcpu->mmio_data, bytes); |
@@ -3758,10 +3751,10 @@ static int emulator_read_emulated(unsigned long addr, | |||
3758 | return X86EMUL_CONTINUE; | 3751 | return X86EMUL_CONTINUE; |
3759 | } | 3752 | } |
3760 | 3753 | ||
3761 | gpa = kvm_mmu_gva_to_gpa_read(vcpu, addr, &error_code); | 3754 | gpa = kvm_mmu_gva_to_gpa_read(vcpu, addr, exception); |
3762 | 3755 | ||
3763 | if (gpa == UNMAPPED_GVA) | 3756 | if (gpa == UNMAPPED_GVA) |
3764 | return make_page_fault(exception, error_code); | 3757 | return X86EMUL_PROPAGATE_FAULT; |
3765 | 3758 | ||
3766 | /* For APIC access vmexit */ | 3759 | /* For APIC access vmexit */ |
3767 | if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE) | 3760 | if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE) |
@@ -3810,12 +3803,11 @@ static int emulator_write_emulated_onepage(unsigned long addr, | |||
3810 | struct kvm_vcpu *vcpu) | 3803 | struct kvm_vcpu *vcpu) |
3811 | { | 3804 | { |
3812 | gpa_t gpa; | 3805 | gpa_t gpa; |
3813 | u32 error_code; | ||
3814 | 3806 | ||
3815 | gpa = kvm_mmu_gva_to_gpa_write(vcpu, addr, &error_code); | 3807 | gpa = kvm_mmu_gva_to_gpa_write(vcpu, addr, exception); |
3816 | 3808 | ||
3817 | if (gpa == UNMAPPED_GVA) | 3809 | if (gpa == UNMAPPED_GVA) |
3818 | return make_page_fault(exception, error_code); | 3810 | return X86EMUL_PROPAGATE_FAULT; |
3819 | 3811 | ||
3820 | /* For APIC access vmexit */ | 3812 | /* For APIC access vmexit */ |
3821 | if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE) | 3813 | if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE) |