From: Peter Maydell <peter.maydell@linaro.org>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PULL 15/20] cputlb: Add functions for flushing TLB for a single MMU index
Date: Tue, 25 Aug 2015 16:00:11 +0100 [thread overview]
Message-ID: <1440514816-16562-16-git-send-email-peter.maydell@linaro.org> (raw)
In-Reply-To: <1440514816-16562-1-git-send-email-peter.maydell@linaro.org>
Guest CPU TLB maintenance operations may be sufficiently
specialized to only need to flush TLB entries corresponding
to a particular MMU index. Implement cputlb functions for
this, to avoid the inefficiency of flushing TLB entries
which we don't need to.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1439548879-1972-2-git-send-email-peter.maydell@linaro.org
---
cputlb.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++
include/exec/exec-all.h | 47 ++++++++++++++++++++++++
2 files changed, 144 insertions(+)
diff --git a/cputlb.c b/cputlb.c
index a506086..4bc6c24 100644
--- a/cputlb.c
+++ b/cputlb.c
@@ -69,6 +69,47 @@ void tlb_flush(CPUState *cpu, int flush_global)
tlb_flush_count++;
}
+static inline void v_tlb_flush_by_mmuidx(CPUState *cpu, va_list argp)
+{
+ CPUArchState *env = cpu->env_ptr;
+
+#if defined(DEBUG_TLB)
+ printf("tlb_flush_by_mmuidx:");
+#endif
+ /* must reset current TB so that interrupts cannot modify the
+ links while we are modifying them */
+ cpu->current_tb = NULL;
+
+ for (;;) {
+ int mmu_idx = va_arg(argp, int);
+
+ if (mmu_idx < 0) {
+ break;
+ }
+
+#if defined(DEBUG_TLB)
+ printf(" %d", mmu_idx);
+#endif
+
+ memset(env->tlb_table[mmu_idx], -1, sizeof(env->tlb_table[0]));
+ memset(env->tlb_v_table[mmu_idx], -1, sizeof(env->tlb_v_table[0]));
+ }
+
+#if defined(DEBUG_TLB)
+ printf("\n");
+#endif
+
+ memset(cpu->tb_jmp_cache, 0, sizeof(cpu->tb_jmp_cache));
+}
+
+void tlb_flush_by_mmuidx(CPUState *cpu, ...)
+{
+ va_list argp;
+ va_start(argp, cpu);
+ v_tlb_flush_by_mmuidx(cpu, argp);
+ va_end(argp);
+}
+
static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr)
{
if (addr == (tlb_entry->addr_read &
@@ -121,6 +162,62 @@ void tlb_flush_page(CPUState *cpu, target_ulong addr)
tb_flush_jmp_cache(cpu, addr);
}
+void tlb_flush_page_by_mmuidx(CPUState *cpu, target_ulong addr, ...)
+{
+ CPUArchState *env = cpu->env_ptr;
+ int i, k;
+ va_list argp;
+
+ va_start(argp, addr);
+
+#if defined(DEBUG_TLB)
+ printf("tlb_flush_page_by_mmu_idx: " TARGET_FMT_lx, addr);
+#endif
+ /* Check if we need to flush due to large pages. */
+ if ((addr & env->tlb_flush_mask) == env->tlb_flush_addr) {
+#if defined(DEBUG_TLB)
+ printf(" forced full flush ("
+ TARGET_FMT_lx "/" TARGET_FMT_lx ")\n",
+ env->tlb_flush_addr, env->tlb_flush_mask);
+#endif
+ v_tlb_flush_by_mmuidx(cpu, argp);
+ va_end(argp);
+ return;
+ }
+ /* must reset current TB so that interrupts cannot modify the
+ links while we are modifying them */
+ cpu->current_tb = NULL;
+
+ addr &= TARGET_PAGE_MASK;
+ i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
+
+ for (;;) {
+ int mmu_idx = va_arg(argp, int);
+
+ if (mmu_idx < 0) {
+ break;
+ }
+
+#if defined(DEBUG_TLB)
+ printf(" %d", mmu_idx);
+#endif
+
+ tlb_flush_entry(&env->tlb_table[mmu_idx][i], addr);
+
+ /* check whether there are vltb entries that need to be flushed */
+ for (k = 0; k < CPU_VTLB_SIZE; k++) {
+ tlb_flush_entry(&env->tlb_v_table[mmu_idx][k], addr);
+ }
+ }
+ va_end(argp);
+
+#if defined(DEBUG_TLB)
+ printf("\n");
+#endif
+
+ tb_flush_jmp_cache(cpu, addr);
+}
+
/* 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 29775c0..fbc6dcb 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -96,8 +96,46 @@ 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 */
+/**
+ * tlb_flush_page:
+ * @cpu: CPU whose TLB should be flushed
+ * @addr: virtual address of page to be flushed
+ *
+ * Flush one page from the TLB of the specified CPU, for all
+ * MMU indexes.
+ */
void tlb_flush_page(CPUState *cpu, target_ulong addr);
+/**
+ * tlb_flush:
+ * @cpu: CPU whose TLB should be flushed
+ * @flush_global: ignored
+ *
+ * Flush the entire TLB for the specified CPU.
+ * The flush_global flag is in theory an indicator of whether the whole
+ * TLB should be flushed, or only those entries not marked global.
+ * In practice QEMU does not implement any global/not global flag for
+ * TLB entries, and the argument is ignored.
+ */
void tlb_flush(CPUState *cpu, int flush_global);
+/**
+ * tlb_flush_page_by_mmuidx:
+ * @cpu: CPU whose TLB should be flushed
+ * @addr: virtual address of page to be flushed
+ * @...: list of MMU indexes to flush, terminated by a negative value
+ *
+ * Flush one page from the TLB of the specified CPU, for the specified
+ * MMU indexes.
+ */
+void tlb_flush_page_by_mmuidx(CPUState *cpu, target_ulong addr, ...);
+/**
+ * tlb_flush_by_mmuidx:
+ * @cpu: CPU whose TLB should be flushed
+ * @...: list of MMU indexes to flush, terminated by a negative value
+ *
+ * Flush all entries from the TLB of the specified CPU, for the specified
+ * MMU indexes.
+ */
+void tlb_flush_by_mmuidx(CPUState *cpu, ...);
void tlb_set_page(CPUState *cpu, target_ulong vaddr,
hwaddr paddr, int prot,
int mmu_idx, target_ulong size);
@@ -115,6 +153,15 @@ static inline void tlb_flush_page(CPUState *cpu, target_ulong addr)
static inline void tlb_flush(CPUState *cpu, int flush_global)
{
}
+
+static inline void tlb_flush_page_by_mmuidx(CPUState *cpu,
+ target_ulong addr, ...)
+{
+}
+
+static inline void tlb_flush_by_mmuidx(CPUState *cpu, ...)
+{
+}
#endif
#define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */
--
1.9.1
next prev parent reply other threads:[~2015-08-25 15:00 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-08-25 14:59 [Qemu-devel] [PULL 00/20] target-arm queue Peter Maydell
2015-08-25 14:59 ` [Qemu-devel] [PULL 01/20] xlnx-zynqmp: Connect the four OCM banks Peter Maydell
2015-08-25 14:59 ` [Qemu-devel] [PULL 02/20] MAINTAINERS: Update Xilinx Maintainership Peter Maydell
2015-08-25 14:59 ` [Qemu-devel] [PULL 03/20] MAINTAINERS: Add ZynqMP to MAINTAINERS file Peter Maydell
2015-08-25 15:00 ` [Qemu-devel] [PULL 04/20] target-arm: Add missing MAIR_EL3 and TPIDR_EL3 registers Peter Maydell
2015-08-25 15:00 ` [Qemu-devel] [PULL 05/20] target-arm: Implement missing AMAIR registers Peter Maydell
2015-08-25 15:00 ` [Qemu-devel] [PULL 06/20] target-arm: Implement missing AFSR registers Peter Maydell
2015-08-25 15:00 ` [Qemu-devel] [PULL 07/20] target-arm: Implement missing ACTLR registers Peter Maydell
2015-08-25 15:00 ` [Qemu-devel] [PULL 08/20] target-arm: there is no TTBR1 for 32-bit EL2 stage 1 translations Peter Maydell
2015-08-25 15:00 ` [Qemu-devel] [PULL 09/20] target-arm: Wire up AArch64 EL2 and EL3 address translation ops Peter Maydell
2015-08-25 15:00 ` [Qemu-devel] [PULL 10/20] target-arm: Add CP_ACCESS_TRAP_UNCATEGORIZED_EL2, 3 Peter Maydell
2015-08-25 15:00 ` [Qemu-devel] [PULL 11/20] target-arm: Enable the AArch32 ATS12NSO ops Peter Maydell
2015-08-25 15:00 ` [Qemu-devel] [PULL 12/20] target-arm: Implement AArch32 ATS1H* operations Peter Maydell
2015-08-25 15:00 ` [Qemu-devel] [PULL 13/20] smbios: add smbios 3.0 support Peter Maydell
2015-08-25 15:00 ` [Qemu-devel] [PULL 14/20] smbios: implement smbios support for mach-virt Peter Maydell
2015-08-25 15:00 ` Peter Maydell [this message]
2015-08-25 15:00 ` [Qemu-devel] [PULL 16/20] target-arm: Move TLBI ALLE1/ALLE1IS definitions into numeric order Peter Maydell
2015-08-25 15:00 ` [Qemu-devel] [PULL 17/20] target-arm: Restrict AArch64 TLB flushes to the MMU indexes they must touch Peter Maydell
2015-08-25 15:00 ` [Qemu-devel] [PULL 18/20] target-arm: Implement missing EL2 TLBI operations Peter Maydell
2015-08-25 15:00 ` [Qemu-devel] [PULL 19/20] target-arm: Implement missing EL3 TLB invalidate operations Peter Maydell
2015-08-25 15:00 ` [Qemu-devel] [PULL 20/20] target-arm: Implement AArch64 TLBI operations on IPAs Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1440514816-16562-16-git-send-email-peter.maydell@linaro.org \
--to=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).