qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH] linux-user: Fix stale tbs after mmap


From: Alexander Graf
Subject: Re: [Qemu-devel] [PATCH] linux-user: Fix stale tbs after mmap
Date: Mon, 7 May 2012 13:07:34 +0200

On 07.05.2012, at 12:37, Peter Maydell wrote:

> On 7 May 2012 10:30, Alexander Graf <address@hidden> wrote:
>> @@ -587,6 +587,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int 
>> prot,
>>     page_dump(stdout);
>>     printf("\n");
>>  #endif
>> +    tb_invalidate_phys_page_range(start, start + len, 0);
>>     mmap_unlock();
>>     return start;
> 
> The comment at the top of tb_invalidate_phys_page_range() says
> "start and end must refer to the same physical page" -- is it
> out of date or does that not apply to user-mode?

How about this one?


diff --git a/exec-all.h b/exec-all.h
index c211242..7fcd76f 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -96,6 +96,8 @@ void QEMU_NORETURN cpu_loop_exit(CPUState *env1);
 int page_unprotect(target_ulong address, unsigned long pc, void *puc);
 void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
                                    int is_cpu_write_access);
+void tb_invalidate_phys_range(tb_page_addr_t start, tb_page_addr_t end,
+                              int is_cpu_write_access);
 void tlb_flush_page(CPUState *env, target_ulong addr);
 void tlb_flush(CPUState *env, int flush_global);
 #if !defined(CONFIG_USER_ONLY)
diff --git a/exec.c b/exec.c
index e71a82d..532b00c 100644
--- a/exec.c
+++ b/exec.c
@@ -1016,6 +1016,23 @@ TranslationBlock *tb_gen_code(CPUState *env,
     return tb;
 }
 
+/*
+ * invalidate all TBs which intersect with the target physical pages
+ * starting in range [start;end[. NOTE: start and end may refer to
+ * different physical pages. 'is_cpu_write_access' should be true if called
+ * from a real cpu write access: the virtual CPU will exit the current
+ * TB if code is modified inside this TB.
+ */
+void tb_invalidate_phys_range(tb_page_addr_t start, tb_page_addr_t end,
+                              int is_cpu_write_access)
+{
+    while (start < end) {
+        tb_invalidate_phys_page_range(start, end, is_cpu_write_access);
+        start &= TARGET_PAGE_MASK;
+        start += TARGET_PAGE_SIZE;
+    }
+}
+
 /* invalidate all TBs which intersect with the target physical page
    starting in range [start;end[. NOTE: start and end must refer to
    the same physical page. 'is_cpu_write_access' should be true if called
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 2620f88..3611deb 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -587,6 +587,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int 
prot,
     page_dump(stdout);
     printf("\n");
 #endif
+    tb_invalidate_phys_range(start, start + len, 0);
     mmap_unlock();
     return start;
 fail:
@@ -768,6 +769,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong 
old_size,
         page_set_flags(old_addr, old_addr + old_size, 0);
         page_set_flags(new_addr, new_addr + new_size, prot | PAGE_VALID);
     }
+    tb_invalidate_phys_range(new_addr, new_addr + new_size, 0);
     mmap_unlock();
     return new_addr;
 }




reply via email to

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