Since a hypercall may span two pages and is a gva, we need a function to write to a gva that may span multiple pages. emulator_write_phys() seems like the logical choice for this.
Signed-off-by: Anthony Liguori <[EMAIL PROTECTED]> diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index d154487..ebcc5c9 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c @@ -962,8 +962,35 @@ static int emulator_write_std(unsigned long addr, unsigned int bytes, struct kvm_vcpu *vcpu) { - pr_unimpl(vcpu, "emulator_write_std: addr %lx n %d\n", addr, bytes); - return X86EMUL_UNHANDLEABLE; + const void *data = val; + + while (bytes) { + gpa_t gpa = vcpu->mmu.gva_to_gpa(vcpu, addr); + unsigned offset = addr & (PAGE_SIZE-1); + unsigned tocopy = min(bytes, (unsigned)PAGE_SIZE - offset); + unsigned long pfn; + struct page *page; + void *page_virt; + + if (gpa == UNMAPPED_GVA) + return X86EMUL_PROPAGATE_FAULT; + pfn = gpa >> PAGE_SHIFT; + page = gfn_to_page(vcpu->kvm, pfn); + if (!page) + return X86EMUL_UNHANDLEABLE; + page_virt = kmap_atomic(page, KM_USER0); + + memcpy(page_virt + offset, data, tocopy); + + kunmap_atomic(page_virt, KM_USER0); + mark_page_dirty(vcpu->kvm, addr >> PAGE_SHIFT); + + bytes -= tocopy; + data += tocopy; + addr += tocopy; + } + + return X86EMUL_CONTINUE; } static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu, ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel