qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [RFC PATCH V6 15/18] cpu: introduce tlb_flush*_all.


From: fred . konrad
Subject: [Qemu-devel] [RFC PATCH V6 15/18] cpu: introduce tlb_flush*_all.
Date: Fri, 26 Jun 2015 16:47:30 +0200

From: KONRAD Frederic <address@hidden>

Some architectures allow to flush the tlb of other VCPUs. This is not a problem
when we have only one thread for all VCPUs but it definitely needs to be an
asynchronous work when we are in true multithreaded work.

TODO: Some test case, I fear some bad results in case a VCPUs execute a barrier
      or something like that.

Signed-off-by: KONRAD Frederic <address@hidden>
---
 cputlb.c                | 76 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/exec/exec-all.h |  2 ++
 2 files changed, 78 insertions(+)

diff --git a/cputlb.c b/cputlb.c
index 79fff1c..e5853fd 100644
--- a/cputlb.c
+++ b/cputlb.c
@@ -72,6 +72,45 @@ void tlb_flush(CPUState *cpu, int flush_global)
     tlb_flush_count++;
 }
 
+struct TLBFlushParams {
+    CPUState *cpu;
+    int flush_global;
+};
+
+static void tlb_flush_async_work(void *opaque)
+{
+    struct TLBFlushParams *params = opaque;
+
+    tlb_flush(params->cpu, params->flush_global);
+    g_free(params);
+}
+
+void tlb_flush_all(int flush_global)
+{
+    CPUState *cpu;
+    struct TLBFlushParams *params;
+
+#if 0 /* MTTCG */
+    CPU_FOREACH(cpu) {
+        tlb_flush(cpu, flush_global);
+    }
+#else
+    CPU_FOREACH(cpu) {
+        if (qemu_cpu_is_self(cpu)) {
+            /* async_run_on_cpu handle this case but this just avoid a malloc
+             * here.
+             */
+            tlb_flush(cpu, flush_global);
+        } else {
+            params = g_malloc(sizeof(struct TLBFlushParams));
+            params->cpu = cpu;
+            params->flush_global = flush_global;
+            async_run_on_cpu(cpu, tlb_flush_async_work, params);
+        }
+    }
+#endif /* MTTCG */
+}
+
 static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr)
 {
     if (addr == (tlb_entry->addr_read &
@@ -124,6 +163,43 @@ void tlb_flush_page(CPUState *cpu, target_ulong addr)
     tb_flush_jmp_cache(cpu, addr);
 }
 
+struct TLBFlushPageParams {
+    CPUState *cpu;
+    target_ulong addr;
+};
+
+static void tlb_flush_page_async_work(void *opaque)
+{
+    struct TLBFlushPageParams *params = opaque;
+
+    tlb_flush_page(params->cpu, params->addr);
+    g_free(params);
+}
+
+void tlb_flush_page_all(target_ulong addr)
+{
+    CPUState *cpu;
+    struct TLBFlushPageParams *params;
+
+    CPU_FOREACH(cpu) {
+#if 0 /* !MTTCG */
+        tlb_flush_page(cpu, addr);
+#else
+        if (qemu_cpu_is_self(cpu)) {
+            /* async_run_on_cpu handle this case but this just avoid a malloc
+             * here.
+             */
+            tlb_flush_page(cpu, addr);
+        } else {
+            params = g_malloc(sizeof(struct TLBFlushPageParams));
+            params->cpu = cpu;
+            params->addr = addr;
+            async_run_on_cpu(cpu, tlb_flush_page_async_work, params);
+        }
+#endif /* MTTCG */
+    }
+}
+
 /* update the TLBs so that writes to code in the virtual page 'addr'
    can be detected */
 void tlb_protect_code(ram_addr_t ram_addr)
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 44f3336..484c351 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -96,7 +96,9 @@ bool qemu_in_vcpu_thread(void);
 void cpu_reload_memory_map(CPUState *cpu);
 void tcg_cpu_address_space_init(CPUState *cpu, AddressSpace *as);
 /* cputlb.c */
+void tlb_flush_page_all(target_ulong addr);
 void tlb_flush_page(CPUState *cpu, target_ulong addr);
+void tlb_flush_all(int flush_global);
 void tlb_flush(CPUState *cpu, int flush_global);
 void tlb_set_page(CPUState *cpu, target_ulong vaddr,
                   hwaddr paddr, int prot,
-- 
1.9.0




reply via email to

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