All pastes #566908 Raw Edit

Stuff

public text v1 · immutable
·published 2007-06-14 17:59 UTC
rendered paste body
---
 drivers/kvm/kvm.h      |   10 +++++++
 drivers/kvm/kvm_main.c |   70 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 80 insertions(+)

Index: linux/drivers/kvm/kvm.h
===================================================================
--- linux.orig/drivers/kvm/kvm.h
+++ linux/drivers/kvm/kvm.h
@@ -484,11 +484,21 @@ int kvm_read_guest(struct kvm_vcpu *vcpu
               unsigned long size,
               void *dest);
 
+int kvm_read_guest_gpa(struct kvm_vcpu *vcpu,
+              gpa_t addr,
+              unsigned long size,
+              void *dest);
+
 int kvm_write_guest(struct kvm_vcpu *vcpu,
                gva_t addr,
                unsigned long size,
                void *data);
 
+int kvm_write_guest_gpa(struct kvm_vcpu *vcpu,
+                       gpa_t addr,
+                       unsigned long size,
+                       void *data);
+
 unsigned long segment_base(u16 selector);
 
 void kvm_mmu_pre_write(struct kvm_vcpu *vcpu, gpa_t gpa, int bytes);
Index: linux/drivers/kvm/kvm_main.c
===================================================================
--- linux.orig/drivers/kvm/kvm_main.c
+++ linux/drivers/kvm/kvm_main.c
@@ -217,6 +217,41 @@ int kvm_read_guest(struct kvm_vcpu *vcpu
 }
 EXPORT_SYMBOL_GPL(kvm_read_guest);
 
+int kvm_read_guest_gpa(struct kvm_vcpu *vcpu,
+                            gpa_t addr,
+                            unsigned long size,
+                            void *dest)
+{
+       unsigned char *host_buf = dest;
+       unsigned long req_size = size;
+
+       while (size) {
+               hpa_t paddr;
+               unsigned now;
+               unsigned offset;
+               hva_t guest_buf;
+
+               paddr = gpa_to_hpa(vcpu, addr);
+
+               if (is_error_hpa(paddr))
+                       break;
+
+               guest_buf = (hva_t)kmap_atomic(
+                                       pfn_to_page(paddr >> PAGE_SHIFT),
+                                       KM_USER0);
+               offset = addr & ~PAGE_MASK;
+               guest_buf |= offset;
+               now = min(size, PAGE_SIZE - offset);
+               memcpy(host_buf, (void*)guest_buf, now);
+               host_buf += now;
+               addr += now;
+               size -= now;
+               kunmap_atomic((void *)(guest_buf & PAGE_MASK), KM_USER0);
+       }
+       return req_size - size;
+}
+EXPORT_SYMBOL_GPL(kvm_read_guest_gpa);
+
 int kvm_write_guest(struct kvm_vcpu *vcpu, gva_t addr, unsigned long size,
                    void *data)
 {
@@ -252,6 +287,41 @@ int kvm_write_guest(struct kvm_vcpu *vcp
 }
 EXPORT_SYMBOL_GPL(kvm_write_guest);
 
+int kvm_write_guest_gpa(struct kvm_vcpu *vcpu,
+                       gpa_t addr,
+                       unsigned long size,
+                       void *data)
+{
+       unsigned char *host_buf = data;
+       unsigned long req_size = size;
+
+       while (size) {
+               hpa_t paddr;
+               unsigned now;
+               unsigned offset;
+               hva_t guest_buf;
+
+               paddr = gpa_to_hpa(vcpu, addr);
+               if (is_error_hpa(paddr)) {
+                       printk("hm, couldnt look up gpa: %08Lx\n", addr);
+                       break;
+               }
+
+               guest_buf = (hva_t)kmap_atomic(
+                               pfn_to_page(paddr >> PAGE_SHIFT), KM_USER0);
+               offset = addr & ~PAGE_MASK;
+               guest_buf |= offset;
+               now = min(size, PAGE_SIZE - offset);
+               memcpy((void*)guest_buf, host_buf, now);
+               host_buf += now;
+               addr += now;
+               size -= now;
+               kunmap_atomic((void *)(guest_buf & PAGE_MASK), KM_USER0);
+       }
+       return req_size - size;
+}
+EXPORT_SYMBOL_GPL(kvm_write_guest_gpa);
+
 /*
  * Switches to specified vcpu, until a matching vcpu_put()
  */