mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-08 14:23:19 +00:00
KVM: nVMX: Use kvm_{read,write}_guest_cached() for shadow_vmcs12
Using kvm_vcpu_map() for reading from the guest is entirely gratuitous, when all we do is a single memcpy and unmap it again. Fix it up to use kvm_read_guest()... but in fact I couldn't bring myself to do that without also making it use a gfn_to_hva_cache for both that *and* the copy in the other direction. Signed-off-by: David Woodhouse <dwmw@amazon.co.uk> Message-Id: <20211115165030.7422-5-dwmw2@infradead.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
4e8436479a
commit
297d597a6d
@ -670,33 +670,39 @@ static inline bool nested_vmx_prepare_msr_bitmap(struct kvm_vcpu *vcpu,
|
||||
static void nested_cache_shadow_vmcs12(struct kvm_vcpu *vcpu,
|
||||
struct vmcs12 *vmcs12)
|
||||
{
|
||||
struct kvm_host_map map;
|
||||
struct vmcs12 *shadow;
|
||||
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
||||
struct gfn_to_hva_cache *ghc = &vmx->nested.shadow_vmcs12_cache;
|
||||
|
||||
if (!nested_cpu_has_shadow_vmcs(vmcs12) ||
|
||||
vmcs12->vmcs_link_pointer == INVALID_GPA)
|
||||
return;
|
||||
|
||||
shadow = get_shadow_vmcs12(vcpu);
|
||||
|
||||
if (kvm_vcpu_map(vcpu, gpa_to_gfn(vmcs12->vmcs_link_pointer), &map))
|
||||
if (ghc->gpa != vmcs12->vmcs_link_pointer &&
|
||||
kvm_gfn_to_hva_cache_init(vcpu->kvm, ghc,
|
||||
vmcs12->vmcs_link_pointer, VMCS12_SIZE))
|
||||
return;
|
||||
|
||||
memcpy(shadow, map.hva, VMCS12_SIZE);
|
||||
kvm_vcpu_unmap(vcpu, &map, false);
|
||||
kvm_read_guest_cached(vmx->vcpu.kvm, ghc, get_shadow_vmcs12(vcpu),
|
||||
VMCS12_SIZE);
|
||||
}
|
||||
|
||||
static void nested_flush_cached_shadow_vmcs12(struct kvm_vcpu *vcpu,
|
||||
struct vmcs12 *vmcs12)
|
||||
{
|
||||
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
||||
struct gfn_to_hva_cache *ghc = &vmx->nested.shadow_vmcs12_cache;
|
||||
|
||||
if (!nested_cpu_has_shadow_vmcs(vmcs12) ||
|
||||
vmcs12->vmcs_link_pointer == INVALID_GPA)
|
||||
return;
|
||||
|
||||
kvm_write_guest(vmx->vcpu.kvm, vmcs12->vmcs_link_pointer,
|
||||
get_shadow_vmcs12(vcpu), VMCS12_SIZE);
|
||||
if (ghc->gpa != vmcs12->vmcs_link_pointer &&
|
||||
kvm_gfn_to_hva_cache_init(vcpu->kvm, ghc,
|
||||
vmcs12->vmcs_link_pointer, VMCS12_SIZE))
|
||||
return;
|
||||
|
||||
kvm_write_guest_cached(vmx->vcpu.kvm, ghc, get_shadow_vmcs12(vcpu),
|
||||
VMCS12_SIZE);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -141,6 +141,11 @@ struct nested_vmx {
|
||||
*/
|
||||
struct vmcs12 *cached_shadow_vmcs12;
|
||||
|
||||
/*
|
||||
* GPA to HVA cache for accessing vmcs12->vmcs_link_pointer
|
||||
*/
|
||||
struct gfn_to_hva_cache shadow_vmcs12_cache;
|
||||
|
||||
/*
|
||||
* Indicates if the shadow vmcs or enlightened vmcs must be updated
|
||||
* with the data held by struct vmcs12.
|
||||
|
Loading…
Reference in New Issue
Block a user