mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-27 22:53:55 +08:00
KVM: x86: use kvm_read_guest_page for emulator accesses
Emulator accesses are always done a page at a time, either by the emulator itself (for fetches) or because we need to query the MMU for address translations. Speed up these accesses by using kvm_read_guest_page and, in the case of fetches, by inlining kvm_read_guest_virt_helper and dropping the loop around kvm_read_guest_page. This final tweak saves 30-100 more clock cycles (4-10%), bringing the count (as measured by kvm-unit-tests) down to 720-1100 clock cycles on a Sandy Bridge Xeon host, compared to 2300-3200 before the whole series and 925-1700 after the first two low-hanging fruit changes. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
719d5a9b24
commit
44583cba91
@ -4085,7 +4085,8 @@ static int kvm_read_guest_virt_helper(gva_t addr, void *val, unsigned int bytes,
|
||||
|
||||
if (gpa == UNMAPPED_GVA)
|
||||
return X86EMUL_PROPAGATE_FAULT;
|
||||
ret = kvm_read_guest(vcpu->kvm, gpa, data, toread);
|
||||
ret = kvm_read_guest_page(vcpu->kvm, gpa >> PAGE_SHIFT, data,
|
||||
offset, toread);
|
||||
if (ret < 0) {
|
||||
r = X86EMUL_IO_NEEDED;
|
||||
goto out;
|
||||
@ -4106,10 +4107,24 @@ static int kvm_fetch_guest_virt(struct x86_emulate_ctxt *ctxt,
|
||||
{
|
||||
struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
|
||||
u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0;
|
||||
unsigned offset;
|
||||
int ret;
|
||||
|
||||
return kvm_read_guest_virt_helper(addr, val, bytes, vcpu,
|
||||
access | PFERR_FETCH_MASK,
|
||||
exception);
|
||||
/* Inline kvm_read_guest_virt_helper for speed. */
|
||||
gpa_t gpa = vcpu->arch.walk_mmu->gva_to_gpa(vcpu, addr, access|PFERR_FETCH_MASK,
|
||||
exception);
|
||||
if (unlikely(gpa == UNMAPPED_GVA))
|
||||
return X86EMUL_PROPAGATE_FAULT;
|
||||
|
||||
offset = addr & (PAGE_SIZE-1);
|
||||
if (WARN_ON(offset + bytes > PAGE_SIZE))
|
||||
bytes = (unsigned)PAGE_SIZE - offset;
|
||||
ret = kvm_read_guest_page(vcpu->kvm, gpa >> PAGE_SHIFT, val,
|
||||
offset, bytes);
|
||||
if (unlikely(ret < 0))
|
||||
return X86EMUL_IO_NEEDED;
|
||||
|
||||
return X86EMUL_CONTINUE;
|
||||
}
|
||||
|
||||
int kvm_read_guest_virt(struct x86_emulate_ctxt *ctxt,
|
||||
|
Loading…
Reference in New Issue
Block a user