This patch is userspace part of the "batch writes to MMIO" patch.

It defines delayed MMIO zone using kvm_set_mmio() (for VGA and e1000).
It empties the ring buffer and process the MMIO accesses.

Signed-off-by: Laurent Vivier <[EMAIL PROTECTED]>
---
 libkvm/libkvm-x86.c  |   18 ++++++++++++++++++
 libkvm/libkvm.c      |   13 +++++++++++++
 libkvm/libkvm.h      |    2 ++
 qemu/hw/cirrus_vga.c |    2 ++
 qemu/hw/e1000.c      |    8 ++++++++
 qemu/hw/vga.c        |    4 ++++
 qemu/qemu-kvm.c      |    6 ++++++
 qemu/qemu-kvm.h      |    2 ++
 8 files changed, 55 insertions(+), 0 deletions(-)

diff --git a/libkvm/libkvm-x86.c b/libkvm/libkvm-x86.c
index d46fdcc..911e079 100644
--- a/libkvm/libkvm-x86.c
+++ b/libkvm/libkvm-x86.c
@@ -391,6 +391,24 @@ int kvm_set_pit(kvm_context_t kvm, struct kvm_pit_state *s)
 
 #endif
 
+int kvm_set_mmio(kvm_context_t kvm,
+                uint8_t is_delayed, uint64_t addr, uint32_t size)
+{
+       struct kvm_mmio_zone zone;
+       int r;
+
+       zone.is_delayed = is_delayed;
+       zone.addr = addr;
+       zone.size = size;
+
+       r = ioctl(kvm->vm_fd, KVM_SET_MMIO, &zone);
+       if (r == -1) {
+               r = -errno;
+               perror("kvm_set_mmio");
+       }
+       return r;
+}
+
 void kvm_show_code(kvm_context_t kvm, int vcpu)
 {
 #define SHOW_CODE_LEN 50
diff --git a/libkvm/libkvm.c b/libkvm/libkvm.c
index d1e95a4..b891630 100644
--- a/libkvm/libkvm.c
+++ b/libkvm/libkvm.c
@@ -861,6 +861,9 @@ int kvm_run(kvm_context_t kvm, int vcpu)
        int r;
        int fd = kvm->vcpu_fd[vcpu];
        struct kvm_run *run = kvm->run[vcpu];
+#if defined(__x86_64__) || defined(__i386__)
+       struct kvm_batch *batch = (void *)run + 2 * PAGE_SIZE;
+#endif
 
 again:
        if (!kvm->irqchip_in_kernel)
@@ -879,6 +882,16 @@ again:
 
        post_kvm_run(kvm, vcpu);
 
+#if defined(__x86_64__) || defined(__i386__)
+       while (batch->first != batch->last) {
+               kvm->callbacks->mmio_write(kvm->opaque,
+                                          batch->mmio[batch->first].phys_addr,
+                                          &batch->mmio[batch->first].data[0],
+                                          batch->mmio[batch->first].len);
+               batch->first = (batch->first + 1) % KVM_MAX_BATCH;
+       }
+#endif
+
        if (r == -1) {
                r = handle_io_window(kvm);
                goto more;
diff --git a/libkvm/libkvm.h b/libkvm/libkvm.h
index 31c0d59..1f453e1 100644
--- a/libkvm/libkvm.h
+++ b/libkvm/libkvm.h
@@ -448,6 +448,8 @@ int kvm_get_dirty_pages_range(kvm_context_t kvm, unsigned 
long phys_addr,
                              unsigned long end_addr, void *buf, void*opaque,
                              int (*cb)(unsigned long start, unsigned long len,
                                        void*bitmap, void *opaque));
+int kvm_set_mmio(kvm_context_t kvm,
+                uint8_t is_delayed, uint64_t addr, uint32_t size);
 
 /*!
  * \brief Create a memory alias
diff --git a/qemu/hw/cirrus_vga.c b/qemu/hw/cirrus_vga.c
index 2c4aeec..4ef8085 100644
--- a/qemu/hw/cirrus_vga.c
+++ b/qemu/hw/cirrus_vga.c
@@ -3291,6 +3291,8 @@ static void cirrus_init_common(CirrusVGAState * s, int 
device_id, int is_pci)
                                            cirrus_vga_mem_write, s);
     cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
                                  vga_io_memory);
+    if (kvm_enabled())
+        qemu_kvm_set_mmio(1, isa_mem_base + 0x000a0000, 0x20000);
 
     s->sr[0x06] = 0x0f;
     if (device_id == CIRRUS_ID_CLGD5446) {
diff --git a/qemu/hw/e1000.c b/qemu/hw/e1000.c
index 0728539..d223631 100644
--- a/qemu/hw/e1000.c
+++ b/qemu/hw/e1000.c
@@ -26,6 +26,7 @@
 #include "hw.h"
 #include "pci.h"
 #include "net.h"
+#include "qemu-kvm.h"
 
 #include "e1000_hw.h"
 
@@ -938,6 +939,13 @@ e1000_mmio_map(PCIDevice *pci_dev, int region_num,
 
     d->mmio_base = addr;
     cpu_register_physical_memory(addr, PNPMMIO_SIZE, d->mmio_index);
+
+    if (kvm_enabled()) {
+        qemu_kvm_set_mmio(1, addr, PNPMMIO_SIZE);
+        qemu_kvm_set_mmio(0, addr + E1000_TCTL, 4);
+        qemu_kvm_set_mmio(0, addr + E1000_TDT, 4);
+        qemu_kvm_set_mmio(0, addr + E1000_ICR, 4);
+    }
 }
 
 static int
diff --git a/qemu/hw/vga.c b/qemu/hw/vga.c
index 3a49573..844c2a7 100644
--- a/qemu/hw/vga.c
+++ b/qemu/hw/vga.c
@@ -2257,6 +2257,8 @@ void vga_init(VGAState *s)
     vga_io_memory = cpu_register_io_memory(0, vga_mem_read, vga_mem_write, s);
     cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
                                  vga_io_memory);
+    if (kvm_enabled())
+       qemu_kvm_set_mmio(1, isa_mem_base + 0x000a0000, 0x20000);
 }
 
 /* Memory mapped interface */
@@ -2332,6 +2334,8 @@ static void vga_mm_init(VGAState *s, target_phys_addr_t 
vram_base,
     cpu_register_physical_memory(ctrl_base, 0x100000, s_ioport_ctrl);
     s->bank_offset = 0;
     cpu_register_physical_memory(vram_base + 0x000a0000, 0x20000, 
vga_io_memory);
+    if (kvm_enabled())
+        qemu_kvm_set_mmio(1, vram_base + 0x000a0000, 0x20000);
 }
 
 int isa_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
diff --git a/qemu/qemu-kvm.c b/qemu/qemu-kvm.c
index e522269..9f03ab1 100644
--- a/qemu/qemu-kvm.c
+++ b/qemu/qemu-kvm.c
@@ -955,3 +955,9 @@ void kvm_mutex_lock(void)
     pthread_mutex_lock(&qemu_mutex);
     cpu_single_env = NULL;
 }
+
+int qemu_kvm_set_mmio(int is_delayed,
+                     target_phys_addr_t addr, unsigned int size)
+{
+    return kvm_set_mmio(kvm_context, is_delayed, addr, size);
+}
diff --git a/qemu/qemu-kvm.h b/qemu/qemu-kvm.h
index 21606e9..37d4d11 100644
--- a/qemu/qemu-kvm.h
+++ b/qemu/qemu-kvm.h
@@ -75,6 +75,8 @@ int handle_tpr_access(void *opaque, int vcpu,
 void kvm_tpr_vcpu_start(CPUState *env);
 
 int qemu_kvm_get_dirty_pages(unsigned long phys_addr, void *buf);
+int qemu_kvm_set_mmio(int is_delayed,
+                     target_phys_addr_t addr, unsigned int size);
 
 void qemu_kvm_system_reset_request(void);
 
-- 
1.5.2.4


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft 
Defy all challenges. Microsoft(R) Visual Studio 2008. 
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
kvm-devel mailing list
kvm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-devel

Reply via email to