From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LPLgx-00034Q-EG for qemu-devel@nongnu.org; Tue, 20 Jan 2009 13:51:15 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LPLgu-00032g-SA for qemu-devel@nongnu.org; Tue, 20 Jan 2009 13:51:14 -0500 Received: from [199.232.76.173] (port=48489 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LPLgu-00032b-LZ for qemu-devel@nongnu.org; Tue, 20 Jan 2009 13:51:12 -0500 Received: from mx2.redhat.com ([66.187.237.31]:59031) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1LPLgs-0003vM-Sn for qemu-devel@nongnu.org; Tue, 20 Jan 2009 13:51:11 -0500 From: Glauber Costa Date: Tue, 20 Jan 2009 13:51:03 -0500 Message-Id: <1232477465-32386-5-git-send-email-glommer@redhat.com> In-Reply-To: <1232477465-32386-4-git-send-email-glommer@redhat.com> References: <1232477465-32386-1-git-send-email-glommer@redhat.com> <1232477465-32386-2-git-send-email-glommer@redhat.com> <1232477465-32386-3-git-send-email-glommer@redhat.com> <1232477465-32386-4-git-send-email-glommer@redhat.com> Subject: [Qemu-devel] [PATCH 4/6] replace cpu_physical_memory_rw Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: aliguori@us.ibm.com This patch introduces a kvm version of cpu_physical_memory_rw. The main motivation is to bypass tcg version, which contains tcg-specific code, as well as data structures not used by kvm, such as l1_phys_map. In this patch, I'm using a runtime selection of which function to call, but the mid-term goal is to use function pointers in a way very close to which QEMUAccel used to be. Signed-off-by: Glauber Costa --- exec.c | 13 +++++++++++-- kvm-all.c | 44 ++++++++++++++++++++++++++++++++++++++++---- kvm.h | 2 ++ 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/exec.c b/exec.c index f72fb96..20ac972 100644 --- a/exec.c +++ b/exec.c @@ -2957,8 +2957,8 @@ int cpu_physical_memory_do_io(target_phys_addr_t addr, uint8_t *buf, int l, int return l; } -void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, - int len, int is_write) +static void default_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, + int len, int is_write) { int l; uint8_t *ptr; @@ -3016,6 +3016,15 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, } } +void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, + int len, int is_write) +{ + if (kvm_enabled()) + kvm_cpu_physical_memory_rw(addr, buf, len, is_write); + else + default_physical_memory_rw(addr, buf, len, is_write); +} + /* used for ROM loading : can write in RAM and ROM */ void cpu_physical_memory_write_rom(target_phys_addr_t addr, const uint8_t *buf, int len) diff --git a/kvm-all.c b/kvm-all.c index 53aca0a..9cbb2f9 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -540,7 +540,7 @@ void kvm_set_phys_mem(target_phys_addr_t start_addr, mem = kvm_lookup_slot(s, start_addr); if (mem) { - if ((flags == IO_MEM_UNASSIGNED) || (flags >= TLB_MMIO)) { + if ((flags == IO_MEM_UNASSIGNED)) { mem->memory_size = 0; mem->start_addr = start_addr; mem->phys_offset = 0; @@ -559,6 +559,8 @@ void kvm_set_phys_mem(target_phys_addr_t start_addr, mem->phys_offset) return; + if ((phys_offset & ~TARGET_PAGE_MASK) != 0) + return; /* unregister whole slot */ memcpy(&slot, mem, sizeof(slot)); mem->memory_size = 0; @@ -598,16 +600,21 @@ void kvm_set_phys_mem(target_phys_addr_t start_addr, } } /* KVM does not need to know about this memory */ - if (flags >= IO_MEM_UNASSIGNED) + if (flags == IO_MEM_UNASSIGNED) return; - mem = kvm_alloc_slot(s); + if (!mem) + mem = kvm_alloc_slot(s); mem->memory_size = size; mem->start_addr = start_addr; mem->phys_offset = phys_offset; mem->flags = 0; - kvm_set_user_memory_region(s, mem); + if (flags < TLB_MMIO) + kvm_set_user_memory_region(s, mem); + else{ + mem->phys_offset = flags; + } /* FIXME deal with errors */ } @@ -673,3 +680,32 @@ int kvm_has_sync_mmu(void) return 0; } + +void kvm_cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, + int len, int is_write) +{ + KVMSlot *mem; + KVMState *s = kvm_state; + int l; + + mem = kvm_lookup_slot(s, addr); + if (!mem) + return; + + if ((mem->phys_offset & ~TARGET_PAGE_MASK) >= TLB_MMIO) { + l = 0; + while (len > l) + l += cpu_physical_memory_do_io(addr + l, buf + l, len - l, is_write, mem->phys_offset); + } else { + uint8_t *uaddr = phys_ram_base + mem->phys_offset + (addr - mem->start_addr); + l = len; + if (addr + len > mem->start_addr + mem->memory_size) + l = mem->memory_size - addr; + if (!is_write) + memcpy(buf, uaddr, l); + else + memcpy(uaddr, buf, l); + if (l != len) + kvm_cpu_physical_memory_rw(addr + l, buf + l, len - l, is_write); + } +} diff --git a/kvm.h b/kvm.h index efce145..e3e9ca0 100644 --- a/kvm.h +++ b/kvm.h @@ -49,6 +49,8 @@ int kvm_has_sync_mmu(void); int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size); int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size); +void kvm_cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, + int len, int is_write); /* internal API */ struct KVMState; -- 1.5.6.5