lkml.org 
[lkml]   [2011]   [Jun]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH v2 03/22] KVM: x86: fix broken read emulation spans a page boundary
    If the range spans a boundary, the mmio access can be broke, fix it as
    write emulation.

    And we already get the guest physical address, so use it to read guest data
    directly to avoid walking guest page table again

    Signed-off-by: Xiao Guangrong <xiaoguangrong@cn.fujitsu.com>
    ---
    arch/x86/kvm/x86.c | 41 ++++++++++++++++++++++++++++++++---------
    1 files changed, 32 insertions(+), 9 deletions(-)

    diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
    index 0b803f0..eb27be4 100644
    --- a/arch/x86/kvm/x86.c
    +++ b/arch/x86/kvm/x86.c
    @@ -3944,14 +3944,13 @@ out:
    }
    EXPORT_SYMBOL_GPL(kvm_write_guest_virt_system);

    -static int emulator_read_emulated(struct x86_emulate_ctxt *ctxt,
    - unsigned long addr,
    - void *val,
    - unsigned int bytes,
    - struct x86_exception *exception)
    +static int emulator_read_emulated_onepage(unsigned long addr,
    + void *val,
    + unsigned int bytes,
    + struct x86_exception *exception,
    + struct kvm_vcpu *vcpu)
    {
    - struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
    - gpa_t gpa;
    + gpa_t gpa;
    int handled;

    if (vcpu->mmio_read_completed) {
    @@ -3971,8 +3970,7 @@ static int emulator_read_emulated(struct x86_emulate_ctxt *ctxt,
    if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE)
    goto mmio;

    - if (kvm_read_guest_virt(ctxt, addr, val, bytes, exception)
    - == X86EMUL_CONTINUE)
    + if (!kvm_read_guest(vcpu->kvm, gpa, val, bytes))
    return X86EMUL_CONTINUE;

    mmio:
    @@ -4001,6 +3999,31 @@ mmio:
    return X86EMUL_IO_NEEDED;
    }

    +static int emulator_read_emulated(struct x86_emulate_ctxt *ctxt,
    + unsigned long addr,
    + void *val,
    + unsigned int bytes,
    + struct x86_exception *exception)
    +{
    + struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
    +
    + /* Crossing a page boundary? */
    + if (((addr + bytes - 1) ^ addr) & PAGE_MASK) {
    + int rc, now;
    +
    + now = -addr & ~PAGE_MASK;
    + rc = emulator_read_emulated_onepage(addr, val, now, exception,
    + vcpu);
    + if (rc != X86EMUL_CONTINUE)
    + return rc;
    + addr += now;
    + val += now;
    + bytes -= now;
    + }
    + return emulator_read_emulated_onepage(addr, val, bytes, exception,
    + vcpu);
    +}
    +
    int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
    const void *val, int bytes)
    {
    --
    1.7.5.4


    \
     
     \ /
      Last update: 2011-06-22 16:29    [W:4.094 / U:0.080 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site