qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH RFC 3/5] softmmu: add a tlb_vaddr_to_host_fill funct


From: Aurelien Jarno
Subject: [Qemu-devel] [PATCH RFC 3/5] softmmu: add a tlb_vaddr_to_host_fill function
Date: Tue, 2 Jun 2015 13:26:49 +0200

The softmmu code already provides a tlb_vaddr_to_host function, which
returns the host address corresponding to a guest virtual address,
*if it is already in the QEMU MMU TLB*.

This patch is an attempt to have a function which try to fill the TLB
entry if it is not already in the QEMU MMU TLB, possibly trigger a guest
fault. It can be used directly in helpers. For that it creates a common
function with a boolean to tell if the TLB needs to be filled or not. If
yes, it causes tlb_fill, which might trigger an exception or succeed in
which case the tlbentry pointer need to be reloaded.

I also had to change the MMIO test part. It seems that in write mode
some TLB entries are filled with TLB_NOTDIRTY. They are caught by the
MMIO test and a NULL pointer is returned instead. I am not sure of my
change, but I guess the current softmmu code has the same issue.

At the same time, it defines the same function for the user mode, so
that we can write helpers using the same code for softmmu and user mode,
just like cpu_ldxx_data() functions works for both.

It also replaces hard-coded values for the access-type by the
corresponding constants.

Cc: Richard Henderson <address@hidden>
Cc: Alexander Graf <address@hidden>
Cc: Paolo Bonzini <address@hidden>
Cc: Yongbok Kim <address@hidden>
Cc: Leon Alrae <address@hidden>
Cc: Andreas Färber <address@hidden>
Cc: Peter Maydell <address@hidden>
Signed-off-by: Aurelien Jarno <address@hidden>
---
 include/exec/cpu_ldst.h | 100 +++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 77 insertions(+), 23 deletions(-)

diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
index 1673287..64fe806 100644
--- a/include/exec/cpu_ldst.h
+++ b/include/exec/cpu_ldst.h
@@ -307,37 +307,40 @@ uint64_t helper_ldq_cmmu(CPUArchState *env, target_ulong 
addr, int mmu_idx);
 #undef MEMSUFFIX
 #undef SOFTMMU_CODE_ACCESS
 
-/**
- * tlb_vaddr_to_host:
- * @env: CPUArchState
- * @addr: guest virtual address to look up
- * @access_type: 0 for read, 1 for write, 2 for execute
- * @mmu_idx: MMU index to use for lookup
- *
- * Look up the specified guest virtual index in the TCG softmmu TLB.
- * If the TLB contains a host virtual address suitable for direct RAM
- * access, then return it. Otherwise (TLB miss, TLB entry is for an
- * I/O access, etc) return NULL.
- *
- * This is the equivalent of the initial fast-path code used by
- * TCG backends for guest load and store accesses.
- */
-static inline void *tlb_vaddr_to_host(CPUArchState *env, target_ulong addr,
-                                      int access_type, int mmu_idx)
+#endif /* defined(CONFIG_USER_ONLY) */
+
+
+
+#if defined(CONFIG_USER_ONLY)
+static inline void *tlb_vaddr_to_host_common(CPUArchState *env,
+                                             target_ulong addr,
+                                             int access_type, int mmu_idx,
+                                             uintptr_t retaddr, bool fill)
+{
+    return g2h(vaddr);
+}
+#else
+static inline void *tlb_vaddr_to_host_common(CPUArchState *env,
+                                             target_ulong addr,
+                                             int access_type, int mmu_idx,
+                                             uintptr_t retaddr, bool fill)
 {
     int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
-    CPUTLBEntry *tlbentry = &env->tlb_table[mmu_idx][index];
+    CPUTLBEntry *tlbentry;
     target_ulong tlb_addr;
     uintptr_t haddr;
 
+again:
+    tlbentry = &env->tlb_table[mmu_idx][index];
+
     switch (access_type) {
-    case 0:
+    case MMU_DATA_LOAD:
         tlb_addr = tlbentry->addr_read;
         break;
-    case 1:
+    case MMU_DATA_STORE:
         tlb_addr = tlbentry->addr_write;
         break;
-    case 2:
+    case MMU_INST_FETCH:
         tlb_addr = tlbentry->addr_code;
         break;
     default:
@@ -347,10 +350,14 @@ static inline void *tlb_vaddr_to_host(CPUArchState *env, 
target_ulong addr,
     if ((addr & TARGET_PAGE_MASK)
         != (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
         /* TLB entry is for a different page */
+        if (fill) {
+            tlb_fill(ENV_GET_CPU(env), addr, access_type, mmu_idx, retaddr);
+            goto again;
+        }
         return NULL;
     }
 
-    if (tlb_addr & ~TARGET_PAGE_MASK) {
+    if (tlb_addr & TLB_MMIO) {
         /* IO access */
         return NULL;
     }
@@ -358,7 +365,54 @@ static inline void *tlb_vaddr_to_host(CPUArchState *env, 
target_ulong addr,
     haddr = addr + env->tlb_table[mmu_idx][index].addend;
     return (void *)haddr;
 }
+#endif
 
-#endif /* defined(CONFIG_USER_ONLY) */
+/**
+ * tlb_vaddr_to_host:
+ * @env: CPUArchState
+ * @addr: guest virtual address to look up
+ * @access_type: MMU_DATA_LOAD for read, MMU_DATA_STORE for write,
+ *               MMU_INST_FETCH for execute
+ * @mmu_idx: MMU index to use for lookup
+ *
+ * Look up the specified guest virtual index in the TCG softmmu TLB.
+ * If the TLB contains a host virtual address suitable for direct RAM
+ * access, then return it. Otherwise (TLB miss, TLB entry is for an
+ * I/O access, etc) return NULL.
+ *
+ * This is the equivalent of the initial fast-path code used by
+ * TCG backends for guest load and store accesses.
+ */
+static inline void *tlb_vaddr_to_host(CPUArchState *env, target_ulong addr,
+                                      int access_type, int mmu_idx)
+{
+    return tlb_vaddr_to_host_common(env, addr, access_type,
+                                    mmu_idx, 0, false);
+}
+
+/**
+ * tlb_vaddr_to_host_fill:
+ * @env: CPUArchState
+ * @addr: guest virtual address to look up
+ * @access_type: MMU_DATA_LOAD for read, MMU_DATA_STORE for write,
+ *               MMU_INST_FETCH for execute
+ * @mmu_idx: MMU index to use for lookup
+ * @retaddr: address returned by GETPC() when called from a helper or 0
+ *
+ * Look up the specified guest virtual index in the TCG softmmu TLB.
+ * If the TLB contains a host virtual address suitable for direct RAM
+ * access, then return it. In case of a TLB miss, it trigger an exception.
+ * Otherwise (TLB entry is for an I/O access, etc), it returns NULL.
+ *
+ * It is the responsability of the caller to ensure endian conversion, that
+ * page boundaries are not crossed and that access alignement is correct.
+ */
+static inline void *tlb_vaddr_to_host_fill(CPUArchState *env, target_ulong 
addr,
+                                           int access_type, int mmu_idx,
+                                           uintptr_t retaddr)
+{
+    return tlb_vaddr_to_host_common(env, addr, access_type,
+                                    mmu_idx, retaddr, true);
+}
 
 #endif /* CPU_LDST_H */
-- 
2.1.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]