summaryrefslogtreecommitdiffstats
path: root/hw
diff options
context:
space:
mode:
authoraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>2008-12-09 20:09:57 +0000
committeraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>2008-12-09 20:09:57 +0000
commitf65ed4c1529f29a7d62d6733eaa50bed24a4b2ed (patch)
tree1d0351afc0542f8f709f9ed7f6a445474b137a9e /hw
parentd85dc283fa87353be10b11b463196d10eb49ca41 (diff)
downloadhqemu-f65ed4c1529f29a7d62d6733eaa50bed24a4b2ed.zip
hqemu-f65ed4c1529f29a7d62d6733eaa50bed24a4b2ed.tar.gz
KVM: Coalesced MMIO support
MMIO exits are more expensive in KVM or Xen than in QEMU because they involve, at least, privilege transitions. However, MMIO write operations can be effectively batched if those writes do not have side effects. Good examples of this include VGA pixel operations when in a planar mode. As it turns out, we can get a nice boost in other areas too. Laurent mentioned a 9.7% performance boost in iperf with the coalesced MMIO changes for the e1000 when he originally posted this work for KVM. Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5961 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'hw')
-rw-r--r--hw/cirrus_vga.c1
-rw-r--r--hw/e1000.c12
-rw-r--r--hw/pci.c1
-rw-r--r--hw/vga.c2
4 files changed, 16 insertions, 0 deletions
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 5690719..83c5f40 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -3220,6 +3220,7 @@ 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,
s->vga_io_memory);
+ qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000);
s->sr[0x06] = 0x0f;
if (device_id == CIRRUS_ID_CLGD5446) {
diff --git a/hw/e1000.c b/hw/e1000.c
index f07936f..67a062a 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -1001,10 +1001,22 @@ e1000_mmio_map(PCIDevice *pci_dev, int region_num,
uint32_t addr, uint32_t size, int type)
{
E1000State *d = (E1000State *)pci_dev;
+ int i;
+ const uint32_t excluded_regs[] = {
+ E1000_MDIC, E1000_ICR, E1000_ICS, E1000_IMS,
+ E1000_IMC, E1000_TCTL, E1000_TDT, PNPMMIO_SIZE
+ };
+
DBGOUT(MMIO, "e1000_mmio_map addr=0x%08x 0x%08x\n", addr, size);
cpu_register_physical_memory(addr, PNPMMIO_SIZE, d->mmio_index);
+ qemu_register_coalesced_mmio(addr, excluded_regs[0]);
+
+ for (i = 0; excluded_regs[i] != PNPMMIO_SIZE; i++)
+ qemu_register_coalesced_mmio(addr + excluded_regs[i] + 4,
+ excluded_regs[i + 1] -
+ excluded_regs[i] - 4);
}
void
diff --git a/hw/pci.c b/hw/pci.c
index a0f91a8..c48a75e 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -279,6 +279,7 @@ static void pci_update_mappings(PCIDevice *d)
cpu_register_physical_memory(pci_to_cpu_addr(r->addr),
r->size,
IO_MEM_UNASSIGNED);
+ qemu_unregister_coalesced_mmio(r->addr, r->size);
}
}
r->addr = new_addr;
diff --git a/hw/vga.c b/hw/vga.c
index 132dd0b..29354f4 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -2256,6 +2256,7 @@ 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);
+ qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000);
}
/* Memory mapped interface */
@@ -2330,6 +2331,7 @@ 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);
+ qemu_register_coalesced_mmio(vram_base + 0x000a0000, 0x20000);
}
int isa_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
OpenPOWER on IntegriCloud