aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/x86.c
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2010-11-22 10:53:26 -0500
committerAvi Kivity <avi@redhat.com>2011-01-12 04:29:59 -0500
commitab9ae3138789afacd133a9c4b3d7a3f1578e25c7 (patch)
tree27c81b48c395dffd2049b37bafef940573ae6841 /arch/x86/kvm/x86.c
parent35d3d4a1dd2c1ffd6f2481f6d8ad6c358bb22f07 (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.c52
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)
3603static gpa_t translate_nested_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u32 access) 3603static 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
3619gpa_t kvm_mmu_gva_to_gpa_read(struct kvm_vcpu *vcpu, gva_t gva, u32 *error) 3619gpa_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
3632gpa_t kvm_mmu_gva_to_gpa_write(struct kvm_vcpu *vcpu, gva_t gva, u32 *error) 3634gpa_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 */
3640gpa_t kvm_mmu_gva_to_gpa_system(struct kvm_vcpu *vcpu, gva_t gva, u32 *error) 3643gpa_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
3645static 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
3653static int kvm_read_guest_virt_helper(gva_t addr, void *val, unsigned int bytes, 3649static 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)