diff options
| author | Paolo Bonzini <pbonzini@redhat.com> | 2018-06-06 11:37:49 -0400 |
|---|---|---|
| committer | Paolo Bonzini <pbonzini@redhat.com> | 2018-06-12 09:06:28 -0400 |
| commit | ce14e868a54edeb2e30cb7a7b104a2fc4b9d76ca (patch) | |
| tree | 3aa7fc16c03c0205c1e08945f3553e3631ad2bd5 | |
| parent | 79367a65743975e5cac8d24d08eccc7fdae832b0 (diff) | |
KVM: x86: pass kvm_vcpu to kvm_read_guest_virt and kvm_write_guest_virt_system
Int the next patch the emulator's .read_std and .write_std callbacks will
grow another argument, which is not needed in kvm_read_guest_virt and
kvm_write_guest_virt_system's callers. Since we have to make separate
functions, let's give the currently existing names a nicer interface, too.
Fixes: 129a72a0d3c8 ("KVM: x86: Introduce segmented_write_std", 2017-01-12)
Cc: stable@vger.kernel.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
| -rw-r--r-- | arch/x86/kvm/vmx.c | 23 | ||||
| -rw-r--r-- | arch/x86/kvm/x86.c | 39 | ||||
| -rw-r--r-- | arch/x86/kvm/x86.h | 4 |
3 files changed, 38 insertions, 28 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 4bf1f9de9332..48989f78be60 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
| @@ -7823,8 +7823,7 @@ static int nested_vmx_get_vmptr(struct kvm_vcpu *vcpu, gpa_t *vmpointer) | |||
| 7823 | vmcs_read32(VMX_INSTRUCTION_INFO), false, &gva)) | 7823 | vmcs_read32(VMX_INSTRUCTION_INFO), false, &gva)) |
| 7824 | return 1; | 7824 | return 1; |
| 7825 | 7825 | ||
| 7826 | if (kvm_read_guest_virt(&vcpu->arch.emulate_ctxt, gva, vmpointer, | 7826 | if (kvm_read_guest_virt(vcpu, gva, vmpointer, sizeof(*vmpointer), &e)) { |
| 7827 | sizeof(*vmpointer), &e)) { | ||
| 7828 | kvm_inject_page_fault(vcpu, &e); | 7827 | kvm_inject_page_fault(vcpu, &e); |
| 7829 | return 1; | 7828 | return 1; |
| 7830 | } | 7829 | } |
| @@ -8295,8 +8294,8 @@ static int handle_vmread(struct kvm_vcpu *vcpu) | |||
| 8295 | vmx_instruction_info, true, &gva)) | 8294 | vmx_instruction_info, true, &gva)) |
| 8296 | return 1; | 8295 | return 1; |
| 8297 | /* _system ok, nested_vmx_check_permission has verified cpl=0 */ | 8296 | /* _system ok, nested_vmx_check_permission has verified cpl=0 */ |
| 8298 | kvm_write_guest_virt_system(&vcpu->arch.emulate_ctxt, gva, | 8297 | kvm_write_guest_virt_system(vcpu, gva, &field_value, |
| 8299 | &field_value, (is_long_mode(vcpu) ? 8 : 4), NULL); | 8298 | (is_long_mode(vcpu) ? 8 : 4), NULL); |
| 8300 | } | 8299 | } |
| 8301 | 8300 | ||
| 8302 | nested_vmx_succeed(vcpu); | 8301 | nested_vmx_succeed(vcpu); |
| @@ -8334,8 +8333,8 @@ static int handle_vmwrite(struct kvm_vcpu *vcpu) | |||
| 8334 | if (get_vmx_mem_address(vcpu, exit_qualification, | 8333 | if (get_vmx_mem_address(vcpu, exit_qualification, |
| 8335 | vmx_instruction_info, false, &gva)) | 8334 | vmx_instruction_info, false, &gva)) |
| 8336 | return 1; | 8335 | return 1; |
| 8337 | if (kvm_read_guest_virt(&vcpu->arch.emulate_ctxt, gva, | 8336 | if (kvm_read_guest_virt(vcpu, gva, &field_value, |
| 8338 | &field_value, (is_64_bit_mode(vcpu) ? 8 : 4), &e)) { | 8337 | (is_64_bit_mode(vcpu) ? 8 : 4), &e)) { |
| 8339 | kvm_inject_page_fault(vcpu, &e); | 8338 | kvm_inject_page_fault(vcpu, &e); |
| 8340 | return 1; | 8339 | return 1; |
| 8341 | } | 8340 | } |
| @@ -8460,9 +8459,9 @@ static int handle_vmptrst(struct kvm_vcpu *vcpu) | |||
| 8460 | vmx_instruction_info, true, &vmcs_gva)) | 8459 | vmx_instruction_info, true, &vmcs_gva)) |
| 8461 | return 1; | 8460 | return 1; |
| 8462 | /* *_system ok, nested_vmx_check_permission has verified cpl=0 */ | 8461 | /* *_system ok, nested_vmx_check_permission has verified cpl=0 */ |
| 8463 | if (kvm_write_guest_virt_system(&vcpu->arch.emulate_ctxt, vmcs_gva, | 8462 | if (kvm_write_guest_virt_system(vcpu, vmcs_gva, |
| 8464 | (void *)&to_vmx(vcpu)->nested.current_vmptr, | 8463 | (void *)&to_vmx(vcpu)->nested.current_vmptr, |
| 8465 | sizeof(u64), &e)) { | 8464 | sizeof(u64), &e)) { |
| 8466 | kvm_inject_page_fault(vcpu, &e); | 8465 | kvm_inject_page_fault(vcpu, &e); |
| 8467 | return 1; | 8466 | return 1; |
| 8468 | } | 8467 | } |
| @@ -8509,8 +8508,7 @@ static int handle_invept(struct kvm_vcpu *vcpu) | |||
| 8509 | if (get_vmx_mem_address(vcpu, vmcs_readl(EXIT_QUALIFICATION), | 8508 | if (get_vmx_mem_address(vcpu, vmcs_readl(EXIT_QUALIFICATION), |
| 8510 | vmx_instruction_info, false, &gva)) | 8509 | vmx_instruction_info, false, &gva)) |
| 8511 | return 1; | 8510 | return 1; |
| 8512 | if (kvm_read_guest_virt(&vcpu->arch.emulate_ctxt, gva, &operand, | 8511 | if (kvm_read_guest_virt(vcpu, gva, &operand, sizeof(operand), &e)) { |
| 8513 | sizeof(operand), &e)) { | ||
| 8514 | kvm_inject_page_fault(vcpu, &e); | 8512 | kvm_inject_page_fault(vcpu, &e); |
| 8515 | return 1; | 8513 | return 1; |
| 8516 | } | 8514 | } |
| @@ -8574,8 +8572,7 @@ static int handle_invvpid(struct kvm_vcpu *vcpu) | |||
| 8574 | if (get_vmx_mem_address(vcpu, vmcs_readl(EXIT_QUALIFICATION), | 8572 | if (get_vmx_mem_address(vcpu, vmcs_readl(EXIT_QUALIFICATION), |
| 8575 | vmx_instruction_info, false, &gva)) | 8573 | vmx_instruction_info, false, &gva)) |
| 8576 | return 1; | 8574 | return 1; |
| 8577 | if (kvm_read_guest_virt(&vcpu->arch.emulate_ctxt, gva, &operand, | 8575 | if (kvm_read_guest_virt(vcpu, gva, &operand, sizeof(operand), &e)) { |
| 8578 | sizeof(operand), &e)) { | ||
| 8579 | kvm_inject_page_fault(vcpu, &e); | 8576 | kvm_inject_page_fault(vcpu, &e); |
| 8580 | return 1; | 8577 | return 1; |
| 8581 | } | 8578 | } |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 93dd25d005a1..2bbe9858e187 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
| @@ -4798,11 +4798,10 @@ static int kvm_fetch_guest_virt(struct x86_emulate_ctxt *ctxt, | |||
| 4798 | return X86EMUL_CONTINUE; | 4798 | return X86EMUL_CONTINUE; |
| 4799 | } | 4799 | } |
| 4800 | 4800 | ||
| 4801 | int kvm_read_guest_virt(struct x86_emulate_ctxt *ctxt, | 4801 | int kvm_read_guest_virt(struct kvm_vcpu *vcpu, |
| 4802 | gva_t addr, void *val, unsigned int bytes, | 4802 | gva_t addr, void *val, unsigned int bytes, |
| 4803 | struct x86_exception *exception) | 4803 | struct x86_exception *exception) |
| 4804 | { | 4804 | { |
| 4805 | struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt); | ||
| 4806 | u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0; | 4805 | u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0; |
| 4807 | 4806 | ||
| 4808 | return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, access, | 4807 | return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, access, |
| @@ -4810,9 +4809,9 @@ int kvm_read_guest_virt(struct x86_emulate_ctxt *ctxt, | |||
| 4810 | } | 4809 | } |
| 4811 | EXPORT_SYMBOL_GPL(kvm_read_guest_virt); | 4810 | EXPORT_SYMBOL_GPL(kvm_read_guest_virt); |
| 4812 | 4811 | ||
| 4813 | static int kvm_read_guest_virt_system(struct x86_emulate_ctxt *ctxt, | 4812 | static int emulator_read_std(struct x86_emulate_ctxt *ctxt, |
| 4814 | gva_t addr, void *val, unsigned int bytes, | 4813 | gva_t addr, void *val, unsigned int bytes, |
| 4815 | struct x86_exception *exception) | 4814 | struct x86_exception *exception) |
| 4816 | { | 4815 | { |
| 4817 | struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt); | 4816 | struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt); |
| 4818 | return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, 0, exception); | 4817 | return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, 0, exception); |
| @@ -4827,18 +4826,16 @@ static int kvm_read_guest_phys_system(struct x86_emulate_ctxt *ctxt, | |||
| 4827 | return r < 0 ? X86EMUL_IO_NEEDED : X86EMUL_CONTINUE; | 4826 | return r < 0 ? X86EMUL_IO_NEEDED : X86EMUL_CONTINUE; |
| 4828 | } | 4827 | } |
| 4829 | 4828 | ||
| 4830 | int kvm_write_guest_virt_system(struct x86_emulate_ctxt *ctxt, | 4829 | static int kvm_write_guest_virt_helper(gva_t addr, void *val, unsigned int bytes, |
| 4831 | gva_t addr, void *val, | 4830 | struct kvm_vcpu *vcpu, u32 access, |
| 4832 | unsigned int bytes, | 4831 | struct x86_exception *exception) |
| 4833 | struct x86_exception *exception) | ||
| 4834 | { | 4832 | { |
| 4835 | struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt); | ||
| 4836 | void *data = val; | 4833 | void *data = val; |
| 4837 | int r = X86EMUL_CONTINUE; | 4834 | int r = X86EMUL_CONTINUE; |
| 4838 | 4835 | ||
| 4839 | while (bytes) { | 4836 | while (bytes) { |
| 4840 | gpa_t gpa = vcpu->arch.walk_mmu->gva_to_gpa(vcpu, addr, | 4837 | gpa_t gpa = vcpu->arch.walk_mmu->gva_to_gpa(vcpu, addr, |
| 4841 | PFERR_WRITE_MASK, | 4838 | access, |
| 4842 | exception); | 4839 | exception); |
| 4843 | unsigned offset = addr & (PAGE_SIZE-1); | 4840 | unsigned offset = addr & (PAGE_SIZE-1); |
| 4844 | unsigned towrite = min(bytes, (unsigned)PAGE_SIZE - offset); | 4841 | unsigned towrite = min(bytes, (unsigned)PAGE_SIZE - offset); |
| @@ -4859,6 +4856,22 @@ int kvm_write_guest_virt_system(struct x86_emulate_ctxt *ctxt, | |||
| 4859 | out: | 4856 | out: |
| 4860 | return r; | 4857 | return r; |
| 4861 | } | 4858 | } |
| 4859 | |||
| 4860 | static int emulator_write_std(struct x86_emulate_ctxt *ctxt, gva_t addr, void *val, | ||
| 4861 | unsigned int bytes, struct x86_exception *exception) | ||
| 4862 | { | ||
| 4863 | struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt); | ||
| 4864 | |||
| 4865 | return kvm_write_guest_virt_helper(addr, val, bytes, vcpu, | ||
| 4866 | PFERR_WRITE_MASK, exception); | ||
| 4867 | } | ||
| 4868 | |||
| 4869 | int kvm_write_guest_virt_system(struct kvm_vcpu *vcpu, gva_t addr, void *val, | ||
| 4870 | unsigned int bytes, struct x86_exception *exception) | ||
| 4871 | { | ||
| 4872 | return kvm_write_guest_virt_helper(addr, val, bytes, vcpu, | ||
| 4873 | PFERR_WRITE_MASK, exception); | ||
| 4874 | } | ||
| 4862 | EXPORT_SYMBOL_GPL(kvm_write_guest_virt_system); | 4875 | EXPORT_SYMBOL_GPL(kvm_write_guest_virt_system); |
| 4863 | 4876 | ||
| 4864 | int handle_ud(struct kvm_vcpu *vcpu) | 4877 | int handle_ud(struct kvm_vcpu *vcpu) |
| @@ -5611,8 +5624,8 @@ static int emulator_pre_leave_smm(struct x86_emulate_ctxt *ctxt, u64 smbase) | |||
| 5611 | static const struct x86_emulate_ops emulate_ops = { | 5624 | static const struct x86_emulate_ops emulate_ops = { |
| 5612 | .read_gpr = emulator_read_gpr, | 5625 | .read_gpr = emulator_read_gpr, |
| 5613 | .write_gpr = emulator_write_gpr, | 5626 | .write_gpr = emulator_write_gpr, |
| 5614 | .read_std = kvm_read_guest_virt_system, | 5627 | .read_std = emulator_read_std, |
| 5615 | .write_std = kvm_write_guest_virt_system, | 5628 | .write_std = emulator_write_std, |
| 5616 | .read_phys = kvm_read_guest_phys_system, | 5629 | .read_phys = kvm_read_guest_phys_system, |
| 5617 | .fetch = kvm_fetch_guest_virt, | 5630 | .fetch = kvm_fetch_guest_virt, |
| 5618 | .read_emulated = emulator_read_emulated, | 5631 | .read_emulated = emulator_read_emulated, |
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index c9492f764902..331993c49dae 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h | |||
| @@ -247,11 +247,11 @@ int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq, int inc_eip); | |||
| 247 | void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr); | 247 | void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr); |
| 248 | u64 get_kvmclock_ns(struct kvm *kvm); | 248 | u64 get_kvmclock_ns(struct kvm *kvm); |
| 249 | 249 | ||
| 250 | int kvm_read_guest_virt(struct x86_emulate_ctxt *ctxt, | 250 | int kvm_read_guest_virt(struct kvm_vcpu *vcpu, |
| 251 | gva_t addr, void *val, unsigned int bytes, | 251 | gva_t addr, void *val, unsigned int bytes, |
| 252 | struct x86_exception *exception); | 252 | struct x86_exception *exception); |
| 253 | 253 | ||
| 254 | int kvm_write_guest_virt_system(struct x86_emulate_ctxt *ctxt, | 254 | int kvm_write_guest_virt_system(struct kvm_vcpu *vcpu, |
| 255 | gva_t addr, void *val, unsigned int bytes, | 255 | gva_t addr, void *val, unsigned int bytes, |
| 256 | struct x86_exception *exception); | 256 | struct x86_exception *exception); |
| 257 | 257 | ||
