mirror of
https://github.com/edk2-porting/linux-next.git
synced 2025-01-15 17:14:00 +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)
|
if (gpa == UNMAPPED_GVA)
|
||||||
return X86EMUL_PROPAGATE_FAULT;
|
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) {
|
if (ret < 0) {
|
||||||
r = X86EMUL_IO_NEEDED;
|
r = X86EMUL_IO_NEEDED;
|
||||||
goto out;
|
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);
|
struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
|
||||||
u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0;
|
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,
|
/* Inline kvm_read_guest_virt_helper for speed. */
|
||||||
access | PFERR_FETCH_MASK,
|
gpa_t gpa = vcpu->arch.walk_mmu->gva_to_gpa(vcpu, addr, access|PFERR_FETCH_MASK,
|
||||||
exception);
|
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,
|
int kvm_read_guest_virt(struct x86_emulate_ctxt *ctxt,
|
||||||
|
Loading…
Reference in New Issue
Block a user