[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 36/36] tcg: Factor out probe_write() logic into prob
From: |
Richard Henderson |
Subject: |
[Qemu-devel] [PATCH 36/36] tcg: Factor out probe_write() logic into probe_access() |
Date: |
Tue, 3 Sep 2019 09:08:58 -0700 |
From: David Hildenbrand <address@hidden>
Let's also allow to probe other access types.
Reviewed-by: Richard Henderson <address@hidden>
Signed-off-by: David Hildenbrand <address@hidden>
Message-Id: <address@hidden>
Signed-off-by: Richard Henderson <address@hidden>
---
include/exec/exec-all.h | 10 ++++++++--
accel/tcg/cputlb.c | 43 ++++++++++++++++++++++++++++++-----------
accel/tcg/user-exec.c | 26 +++++++++++++++++++------
3 files changed, 60 insertions(+), 19 deletions(-)
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index a7893ed16b..81b02eb2fe 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -310,8 +310,14 @@ static inline void
tlb_flush_by_mmuidx_all_cpus_synced(CPUState *cpu,
{
}
#endif
-void *probe_write(CPUArchState *env, target_ulong addr, int size, int mmu_idx,
- uintptr_t retaddr);
+void *probe_access(CPUArchState *env, target_ulong addr, int size,
+ MMUAccessType access_type, int mmu_idx, uintptr_t retaddr);
+
+static inline void *probe_write(CPUArchState *env, target_ulong addr, int size,
+ int mmu_idx, uintptr_t retaddr)
+{
+ return probe_access(env, addr, size, MMU_DATA_STORE, mmu_idx, retaddr);
+}
#define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line
*/
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index cb969d8372..abae79650c 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -1075,30 +1075,51 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env,
target_ulong addr)
return qemu_ram_addr_from_host_nofail(p);
}
-/* Probe for whether the specified guest write access is permitted.
- * If it is not permitted then an exception will be taken in the same
- * way as if this were a real write access (and we will not return).
+/*
+ * Probe for whether the specified guest access is permitted. If it is not
+ * permitted then an exception will be taken in the same way as if this
+ * were a real access (and we will not return).
* If the size is 0 or the page requires I/O access, returns NULL; otherwise,
* returns the address of the host page similar to tlb_vaddr_to_host().
*/
-void *probe_write(CPUArchState *env, target_ulong addr, int size, int mmu_idx,
- uintptr_t retaddr)
+void *probe_access(CPUArchState *env, target_ulong addr, int size,
+ MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
{
uintptr_t index = tlb_index(env, mmu_idx, addr);
CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
- target_ulong tlb_addr = tlb_addr_write(entry);
+ target_ulong tlb_addr;
+ size_t elt_ofs;
+ int wp_access;
g_assert(-(addr | TARGET_PAGE_MASK) >= size);
+ switch (access_type) {
+ case MMU_DATA_LOAD:
+ elt_ofs = offsetof(CPUTLBEntry, addr_read);
+ wp_access = BP_MEM_READ;
+ break;
+ case MMU_DATA_STORE:
+ elt_ofs = offsetof(CPUTLBEntry, addr_write);
+ wp_access = BP_MEM_WRITE;
+ break;
+ case MMU_INST_FETCH:
+ elt_ofs = offsetof(CPUTLBEntry, addr_code);
+ wp_access = BP_MEM_READ;
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ tlb_addr = tlb_read_ofs(entry, elt_ofs);
+
if (unlikely(!tlb_hit(tlb_addr, addr))) {
- if (!VICTIM_TLB_HIT(addr_write, addr)) {
- tlb_fill(env_cpu(env), addr, size, MMU_DATA_STORE,
- mmu_idx, retaddr);
+ if (!victim_tlb_hit(env, mmu_idx, index, elt_ofs,
+ addr & TARGET_PAGE_MASK)) {
+ tlb_fill(env_cpu(env), addr, size, access_type, mmu_idx, retaddr);
/* TLB resize via tlb_fill may have moved the entry. */
index = tlb_index(env, mmu_idx, addr);
entry = tlb_entry(env, mmu_idx, addr);
}
- tlb_addr = tlb_addr_write(entry);
+ tlb_addr = tlb_read_ofs(entry, elt_ofs);
}
if (!size) {
@@ -1109,7 +1130,7 @@ void *probe_write(CPUArchState *env, target_ulong addr,
int size, int mmu_idx,
if (tlb_addr & TLB_WATCHPOINT) {
cpu_check_watchpoint(env_cpu(env), addr, size,
env_tlb(env)->d[mmu_idx].iotlb[index].attrs,
- BP_MEM_WRITE, retaddr);
+ wp_access, retaddr);
}
if (tlb_addr & (TLB_NOTDIRTY | TLB_MMIO)) {
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index 5720bf8056..71c4bf6477 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -188,17 +188,31 @@ static inline int handle_cpu_signal(uintptr_t pc,
siginfo_t *info,
g_assert_not_reached();
}
-void *probe_write(CPUArchState *env, target_ulong addr, int size, int mmu_idx,
- uintptr_t retaddr)
+void *probe_access(CPUArchState *env, target_ulong addr, int size,
+ MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
{
+ int flags;
+
g_assert(-(addr | TARGET_PAGE_MASK) >= size);
- if (!guest_addr_valid(addr) ||
- page_check_range(addr, size, PAGE_WRITE) < 0) {
+ switch (access_type) {
+ case MMU_DATA_STORE:
+ flags = PAGE_WRITE;
+ break;
+ case MMU_DATA_LOAD:
+ flags = PAGE_READ;
+ break;
+ case MMU_INST_FETCH:
+ flags = PAGE_EXEC;
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ if (!guest_addr_valid(addr) || page_check_range(addr, size, flags) < 0) {
CPUState *cpu = env_cpu(env);
CPUClass *cc = CPU_GET_CLASS(cpu);
-
- cc->tlb_fill(cpu, addr, size, MMU_DATA_STORE, MMU_USER_IDX, false,
+ cc->tlb_fill(cpu, addr, size, access_type, MMU_USER_IDX, false,
retaddr);
g_assert_not_reached();
}
--
2.17.1
- [Qemu-devel] [PATCH 27/36] tcg: Check for watchpoints in probe_write(), (continued)
- [Qemu-devel] [PATCH 27/36] tcg: Check for watchpoints in probe_write(), Richard Henderson, 2019/09/03
- [Qemu-devel] [PATCH 29/36] s390x/tcg: Fix length calculation in probe_write_access(), Richard Henderson, 2019/09/03
- [Qemu-devel] [PATCH 26/36] cputlb: Handle watchpoints via TLB_WATCHPOINT, Richard Henderson, 2019/09/03
- [Qemu-devel] [PATCH 28/36] s390x/tcg: Use guest_addr_valid() instead of h2g_valid() in probe_write_access(), Richard Henderson, 2019/09/03
- [Qemu-devel] [PATCH 30/36] tcg: Factor out CONFIG_USER_ONLY probe_write() from s390x code, Richard Henderson, 2019/09/03
- [Qemu-devel] [PATCH 31/36] tcg: Enforce single page access in probe_write(), Richard Henderson, 2019/09/03
- [Qemu-devel] [PATCH 32/36] mips/tcg: Call probe_write() for CONFIG_USER_ONLY as well, Richard Henderson, 2019/09/03
- [Qemu-devel] [PATCH 33/36] hppa/tcg: Call probe_write() also for CONFIG_USER_ONLY, Richard Henderson, 2019/09/03
- [Qemu-devel] [PATCH 34/36] s390x/tcg: Pass a size to probe_write() in do_csst(), Richard Henderson, 2019/09/03
- [Qemu-devel] [PATCH 35/36] tcg: Make probe_write() return a pointer to the host page, Richard Henderson, 2019/09/03
- [Qemu-devel] [PATCH 36/36] tcg: Factor out probe_write() logic into probe_access(),
Richard Henderson <=
- Re: [Qemu-devel] [PATCH 00/36] tcg patch queue, Mark Cave-Ayland, 2019/09/03
- Re: [Qemu-devel] [PATCH 00/36] tcg patch queue, Philippe Mathieu-Daudé, 2019/09/03
- Re: [Qemu-devel] [PATCH 00/36] tcg patch queue, Peter Maydell, 2019/09/04