Skip to content

Commit

Permalink
KVM/nSVM: Use the new mapping API for mapping guest memory
Browse files Browse the repository at this point in the history
Use the new mapping API for mapping guest memory to avoid depending on
"struct page".

Signed-off-by: KarimAllah Ahmed <karahmed@amazon.de>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
  • Loading branch information
KarimAllah Ahmed authored and Paolo Bonzini committed Apr 30, 2019
1 parent 42e35f8 commit 8c5fbf1
Showing 1 changed file with 45 additions and 49 deletions.
94 changes: 45 additions & 49 deletions arch/x86/kvm/svm.c
Original file line number Diff line number Diff line change
Expand Up @@ -3071,32 +3071,6 @@ static inline bool nested_svm_nmi(struct vcpu_svm *svm)
return false;
}

static void *nested_svm_map(struct vcpu_svm *svm, u64 gpa, struct page **_page)
{
struct page *page;

might_sleep();

page = kvm_vcpu_gfn_to_page(&svm->vcpu, gpa >> PAGE_SHIFT);
if (is_error_page(page))
goto error;

*_page = page;

return kmap(page);

error:
kvm_inject_gp(&svm->vcpu, 0);

return NULL;
}

static void nested_svm_unmap(struct page *page)
{
kunmap(page);
kvm_release_page_dirty(page);
}

static int nested_svm_intercept_ioio(struct vcpu_svm *svm)
{
unsigned port, size, iopm_len;
Expand Down Expand Up @@ -3299,10 +3273,11 @@ static inline void copy_vmcb_control_area(struct vmcb *dst_vmcb, struct vmcb *fr

static int nested_svm_vmexit(struct vcpu_svm *svm)
{
int rc;
struct vmcb *nested_vmcb;
struct vmcb *hsave = svm->nested.hsave;
struct vmcb *vmcb = svm->vmcb;
struct page *page;
struct kvm_host_map map;

trace_kvm_nested_vmexit_inject(vmcb->control.exit_code,
vmcb->control.exit_info_1,
Expand All @@ -3311,9 +3286,14 @@ static int nested_svm_vmexit(struct vcpu_svm *svm)
vmcb->control.exit_int_info_err,
KVM_ISA_SVM);

nested_vmcb = nested_svm_map(svm, svm->nested.vmcb, &page);
if (!nested_vmcb)
rc = kvm_vcpu_map(&svm->vcpu, gfn_to_gpa(svm->nested.vmcb), &map);
if (rc) {
if (rc == -EINVAL)
kvm_inject_gp(&svm->vcpu, 0);
return 1;
}

nested_vmcb = map.hva;

/* Exit Guest-Mode */
leave_guest_mode(&svm->vcpu);
Expand Down Expand Up @@ -3417,7 +3397,7 @@ static int nested_svm_vmexit(struct vcpu_svm *svm)

mark_all_dirty(svm->vmcb);

nested_svm_unmap(page);
kvm_vcpu_unmap(&svm->vcpu, &map, true);

nested_svm_uninit_mmu_context(&svm->vcpu);
kvm_mmu_reset_context(&svm->vcpu);
Expand Down Expand Up @@ -3483,7 +3463,7 @@ static bool nested_vmcb_checks(struct vmcb *vmcb)
}

static void enter_svm_guest_mode(struct vcpu_svm *svm, u64 vmcb_gpa,
struct vmcb *nested_vmcb, struct page *page)
struct vmcb *nested_vmcb, struct kvm_host_map *map)
{
if (kvm_get_rflags(&svm->vcpu) & X86_EFLAGS_IF)
svm->vcpu.arch.hflags |= HF_HIF_MASK;
Expand Down Expand Up @@ -3567,7 +3547,7 @@ static void enter_svm_guest_mode(struct vcpu_svm *svm, u64 vmcb_gpa,
svm->vmcb->control.pause_filter_thresh =
nested_vmcb->control.pause_filter_thresh;

nested_svm_unmap(page);
kvm_vcpu_unmap(&svm->vcpu, map, true);

/* Enter Guest-Mode */
enter_guest_mode(&svm->vcpu);
Expand All @@ -3587,25 +3567,31 @@ static void enter_svm_guest_mode(struct vcpu_svm *svm, u64 vmcb_gpa,

static bool nested_svm_vmrun(struct vcpu_svm *svm)
{
int rc;
struct vmcb *nested_vmcb;
struct vmcb *hsave = svm->nested.hsave;
struct vmcb *vmcb = svm->vmcb;
struct page *page;
struct kvm_host_map map;
u64 vmcb_gpa;

vmcb_gpa = svm->vmcb->save.rax;

nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, &page);
if (!nested_vmcb)
rc = kvm_vcpu_map(&svm->vcpu, gfn_to_gpa(vmcb_gpa), &map);
if (rc) {
if (rc == -EINVAL)
kvm_inject_gp(&svm->vcpu, 0);
return false;
}

nested_vmcb = map.hva;

if (!nested_vmcb_checks(nested_vmcb)) {
nested_vmcb->control.exit_code = SVM_EXIT_ERR;
nested_vmcb->control.exit_code_hi = 0;
nested_vmcb->control.exit_info_1 = 0;
nested_vmcb->control.exit_info_2 = 0;

nested_svm_unmap(page);
kvm_vcpu_unmap(&svm->vcpu, &map, true);

return false;
}
Expand Down Expand Up @@ -3649,7 +3635,7 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm)

copy_vmcb_control_area(hsave, vmcb);

enter_svm_guest_mode(svm, vmcb_gpa, nested_vmcb, page);
enter_svm_guest_mode(svm, vmcb_gpa, nested_vmcb, &map);

return true;
}
Expand All @@ -3673,43 +3659,53 @@ static void nested_svm_vmloadsave(struct vmcb *from_vmcb, struct vmcb *to_vmcb)
static int vmload_interception(struct vcpu_svm *svm)
{
struct vmcb *nested_vmcb;
struct page *page;
struct kvm_host_map map;
int ret;

if (nested_svm_check_permissions(svm))
return 1;

nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, &page);
if (!nested_vmcb)
ret = kvm_vcpu_map(&svm->vcpu, gpa_to_gfn(svm->vmcb->save.rax), &map);
if (ret) {
if (ret == -EINVAL)
kvm_inject_gp(&svm->vcpu, 0);
return 1;
}

nested_vmcb = map.hva;

svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
ret = kvm_skip_emulated_instruction(&svm->vcpu);

nested_svm_vmloadsave(nested_vmcb, svm->vmcb);
nested_svm_unmap(page);
kvm_vcpu_unmap(&svm->vcpu, &map, true);

return ret;
}

static int vmsave_interception(struct vcpu_svm *svm)
{
struct vmcb *nested_vmcb;
struct page *page;
struct kvm_host_map map;
int ret;

if (nested_svm_check_permissions(svm))
return 1;

nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, &page);
if (!nested_vmcb)
ret = kvm_vcpu_map(&svm->vcpu, gpa_to_gfn(svm->vmcb->save.rax), &map);
if (ret) {
if (ret == -EINVAL)
kvm_inject_gp(&svm->vcpu, 0);
return 1;
}

nested_vmcb = map.hva;

svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
ret = kvm_skip_emulated_instruction(&svm->vcpu);

nested_svm_vmloadsave(svm->vmcb, nested_vmcb);
nested_svm_unmap(page);
kvm_vcpu_unmap(&svm->vcpu, &map, true);

return ret;
}
Expand Down Expand Up @@ -6236,18 +6232,18 @@ static int svm_pre_leave_smm(struct kvm_vcpu *vcpu, const char *smstate)
{
struct vcpu_svm *svm = to_svm(vcpu);
struct vmcb *nested_vmcb;
struct page *page;
struct kvm_host_map map;
u64 guest;
u64 vmcb;

guest = GET_SMSTATE(u64, smstate, 0x7ed8);
vmcb = GET_SMSTATE(u64, smstate, 0x7ee0);

if (guest) {
nested_vmcb = nested_svm_map(svm, vmcb, &page);
if (!nested_vmcb)
if (kvm_vcpu_map(&svm->vcpu, gpa_to_gfn(vmcb), &map) == -EINVAL)
return 1;
enter_svm_guest_mode(svm, vmcb, nested_vmcb, page);
nested_vmcb = map.hva;
enter_svm_guest_mode(svm, vmcb, nested_vmcb, &map);
}
return 0;
}
Expand Down

0 comments on commit 8c5fbf1

Please sign in to comment.