From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41953) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YpYva-0001de-3F for qemu-devel@nongnu.org; Tue, 05 May 2015 05:14:13 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YpYvU-0007QC-JE for qemu-devel@nongnu.org; Tue, 05 May 2015 05:14:09 -0400 Received: from mail-wi0-f174.google.com ([209.85.212.174]:33280) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YpYvU-0007Pl-BT for qemu-devel@nongnu.org; Tue, 05 May 2015 05:14:04 -0400 Received: by wief7 with SMTP id f7so96014131wie.0 for ; Tue, 05 May 2015 02:14:03 -0700 (PDT) From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Fangu=C3=A8de?= Date: Tue, 5 May 2015 11:13:45 +0200 Message-Id: <1430817227-6278-3-git-send-email-j.fanguede@virtualopensystems.com> In-Reply-To: <1430817227-6278-1-git-send-email-j.fanguede@virtualopensystems.com> References: <1430817227-6278-1-git-send-email-j.fanguede@virtualopensystems.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Subject: [Qemu-devel] [RFC 2/4] target-arm/kvm: Flush data cache support List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Peter Maydell , "open list:Overall" , Paolo Bonzini , =?UTF-8?q?J=C3=A9r=C3=A9my=20Fangu=C3=A8de?= , tech@virtualopensystems.com, kvmarm@lists.cs.columbia.edu Implement data cache maintenance coherency functions, by using FLUSH_DCACHE_GPA ioctl. Introduce kvm_arm_maintain_cache_coherency() for flushing the data cache if necessary, a very simple logic is implemented to reduce number of flushes due to reads. Two wrapping functions are exposed, for easier usage. Signed-off-by: Jérémy Fanguède --- include/sysemu/kvm.h | 3 +++ stubs/kvm.c | 9 +++++++++ target-arm/kvm.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index 197e6c0..986f365 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -451,4 +451,7 @@ int kvm_set_one_reg(CPUState *cs, uint64_t id, void *source); * Returns: 0 on success, or a negative errno on failure. */ int kvm_get_one_reg(CPUState *cs, uint64_t id, void *target); + +void kvm_arch_cache_flush_needed(hwaddr addr, int len, bool is_write); +void kvm_arch_cache_coherency_pre_run(void); #endif diff --git a/stubs/kvm.c b/stubs/kvm.c index e7c60b6..8ed5380 100644 --- a/stubs/kvm.c +++ b/stubs/kvm.c @@ -5,3 +5,12 @@ int kvm_arch_irqchip_create(KVMState *s) { return 0; } + + +void kvm_arch_cache_flush_needed(hwaddr addr, int len, bool is_write) +{ +} + +void kvm_arch_cache_coherency_pre_run(void) +{ +} diff --git a/target-arm/kvm.c b/target-arm/kvm.c index fdd9ba3..548dae2 100644 --- a/target-arm/kvm.c +++ b/target-arm/kvm.c @@ -598,3 +598,54 @@ int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route, { return 0; } + +static void kvm_arm_flush_cache_addr(hwaddr addr, int len) +{ + int ret; + struct kvm_mem_addr mem_addr; + mem_addr.addr = addr; + mem_addr.len = len; + ret = kvm_vm_ioctl(kvm_state, KVM_FLUSH_DCACHE_GPA, &mem_addr); + if (ret) { + fprintf(stderr, "error: Failed to flush CPU caches %d\n", ret); + } +} + +static void kvm_arm_maintain_cache_coherency(hwaddr addr, int len, + bool enter_guest, bool is_write) +{ + static hwaddr prev_addr; + static int prev_len; + hwaddr end_line, prev_end_line; + + if (enter_guest) { + /* We will return to the guest after that, restore the default + configuration */ + prev_addr = 0x0; + return; + } + + /* Assume the minimal CPU cache line is 32 B */ + end_line = (addr + len) & ~0x1f; + prev_end_line = (prev_addr + prev_len) & ~0x1f; + + /* Don't flush two times in a row the same line" + Always flush on a write */ + if ((prev_addr & ~0x1f) != (addr & ~0x1f) + || (prev_end_line < end_line) + || is_write) { + kvm_arm_flush_cache_addr(addr, len); + prev_addr = addr; + prev_len = len; + } +} + +void kvm_arch_cache_flush_needed(hwaddr addr, int len, bool is_write) +{ + kvm_arm_maintain_cache_coherency(addr, len, false, is_write); +} + +void kvm_arch_cache_coherency_pre_run(void) +{ + kvm_arm_maintain_cache_coherency(0, 0, true, false); +} -- 1.9.1