From 933e3bd8d14f4800cd228b0c190a98061d4e9b3a Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 12 Feb 2018 18:38:17 -0500 Subject: [PATCH] Add MemTxAttrs to the IOTLB Add a MemTxAttrs field to the IOTLB, and allow target-specific code to set it via a new tlb_set_page_with_attrs() function; pass the attributes through to the device when making IO accesses. Backports commit fadc1cbe85c6b032d5842ec0d19d209f50fcb375 from qemu --- qemu/aarch64.h | 1 + qemu/aarch64eb.h | 1 + qemu/arm.h | 1 + qemu/armeb.h | 1 + qemu/cputlb.c | 18 +++++++++++++++--- qemu/header_gen.py | 1 + qemu/include/exec/cpu-defs.h | 2 ++ qemu/include/exec/exec-all.h | 3 +++ qemu/m68k.h | 1 + qemu/mips.h | 1 + qemu/mips64.h | 1 + qemu/mips64el.h | 1 + qemu/mipsel.h | 1 + qemu/powerpc.h | 1 + qemu/softmmu_template.h | 4 ++-- qemu/sparc.h | 1 + qemu/sparc64.h | 1 + qemu/x86_64.h | 1 + 18 files changed, 36 insertions(+), 5 deletions(-) diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 59a2befe..df47b27d 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -149,6 +149,7 @@ #define tlb_flush tlb_flush_aarch64 #define tlb_flush_page tlb_flush_page_aarch64 #define tlb_set_page tlb_set_page_aarch64 +#define tlb_set_page_with_attrs tlb_set_page_with_attrs_aarch64 #define arm_translate_init arm_translate_init_aarch64 #define arm_v7m_class_init arm_v7m_class_init_aarch64 #define arm_v7m_cpu_do_interrupt arm_v7m_cpu_do_interrupt_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index 26a38527..61bd1ba6 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -149,6 +149,7 @@ #define tlb_flush tlb_flush_aarch64eb #define tlb_flush_page tlb_flush_page_aarch64eb #define tlb_set_page tlb_set_page_aarch64eb +#define tlb_set_page_with_attrs tlb_set_page_with_attrs_aarch64eb #define arm_translate_init arm_translate_init_aarch64eb #define arm_v7m_class_init arm_v7m_class_init_aarch64eb #define arm_v7m_cpu_do_interrupt arm_v7m_cpu_do_interrupt_aarch64eb diff --git a/qemu/arm.h b/qemu/arm.h index f24f5fb6..7f44e158 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -149,6 +149,7 @@ #define tlb_flush tlb_flush_arm #define tlb_flush_page tlb_flush_page_arm #define tlb_set_page tlb_set_page_arm +#define tlb_set_page_with_attrs tlb_set_page_with_attrs_arm #define arm_translate_init arm_translate_init_arm #define arm_v7m_class_init arm_v7m_class_init_arm #define arm_v7m_cpu_do_interrupt arm_v7m_cpu_do_interrupt_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index 8fc6895b..eed97c47 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -149,6 +149,7 @@ #define tlb_flush tlb_flush_armeb #define tlb_flush_page tlb_flush_page_armeb #define tlb_set_page tlb_set_page_armeb +#define tlb_set_page_with_attrs tlb_set_page_with_attrs_armeb #define arm_translate_init arm_translate_init_armeb #define arm_v7m_class_init arm_v7m_class_init_armeb #define arm_v7m_cpu_do_interrupt arm_v7m_cpu_do_interrupt_armeb diff --git a/qemu/cputlb.c b/qemu/cputlb.c index cb381dad..9218f705 100644 --- a/qemu/cputlb.c +++ b/qemu/cputlb.c @@ -198,9 +198,9 @@ void tlb_set_dirty(CPUArchState *env, target_ulong vaddr) /* Add a new TLB entry. At most one entry for a given virtual address is permitted. Only a single TARGET_PAGE_SIZE region is mapped, the supplied size is only used by tlb_flush_page. */ -void tlb_set_page(CPUState *cpu, target_ulong vaddr, - hwaddr paddr, int prot, - int mmu_idx, target_ulong size) +void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr, + hwaddr paddr, MemTxAttrs attrs, int prot, + int mmu_idx, target_ulong size) { CPUArchState *env = cpu->env_ptr; MemoryRegionSection *section; @@ -250,6 +250,7 @@ void tlb_set_page(CPUState *cpu, target_ulong vaddr, /* refill the tlb */ env->iotlb[mmu_idx][index].addr = iotlb - vaddr; + env->iotlb[mmu_idx][index].attrs = attrs; te->addend = (uintptr_t)(addend - vaddr); if (prot & PAGE_READ) { te->addr_read = address; @@ -279,6 +280,17 @@ void tlb_set_page(CPUState *cpu, target_ulong vaddr, } } +/* Add a new TLB entry, but without specifying the memory + * transaction attributes to be used. + */ +void tlb_set_page(CPUState *cpu, target_ulong vaddr, + hwaddr paddr, int prot, + int mmu_idx, target_ulong size) +{ + tlb_set_page_with_attrs(cpu, vaddr, paddr, MEMTXATTRS_UNSPECIFIED, + prot, mmu_idx, size); +} + /* NOTE: this function can trigger an exception */ /* NOTE2: the returned address is not exactly the physical address: it * is actually a ram_addr_t (in system mode; the user mode emulation diff --git a/qemu/header_gen.py b/qemu/header_gen.py index 1e0a9584..938d720a 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -155,6 +155,7 @@ symbols = ( 'tlb_flush', 'tlb_flush_page', 'tlb_set_page', + 'tlb_set_page_with_attrs', 'arm_translate_init', 'arm_v7m_class_init', 'arm_v7m_cpu_do_interrupt', diff --git a/qemu/include/exec/cpu-defs.h b/qemu/include/exec/cpu-defs.h index f399e37f..c7b867ac 100644 --- a/qemu/include/exec/cpu-defs.h +++ b/qemu/include/exec/cpu-defs.h @@ -30,6 +30,7 @@ #ifndef CONFIG_USER_ONLY #include "exec/hwaddr.h" #endif +#include "exec/memattrs.h" #ifndef TARGET_LONG_BITS #error TARGET_LONG_BITS must be defined before including this header @@ -128,6 +129,7 @@ QEMU_BUILD_BUG_ON(sizeof(CPUTLBEntry) != (1 << CPU_TLB_ENTRY_BITS)); */ typedef struct CPUIOTLBEntry { hwaddr addr; + MemTxAttrs attrs; } CPUIOTLBEntry; #define CPU_COMMON_TLB \ diff --git a/qemu/include/exec/exec-all.h b/qemu/include/exec/exec-all.h index dbe14261..4750f444 100644 --- a/qemu/include/exec/exec-all.h +++ b/qemu/include/exec/exec-all.h @@ -100,6 +100,9 @@ void tlb_flush(CPUState *cpu, int flush_global); void tlb_set_page(CPUState *cpu, target_ulong vaddr, hwaddr paddr, int prot, int mmu_idx, target_ulong size); +void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr, + hwaddr paddr, MemTxAttrs attrs, + int prot, int mmu_idx, target_ulong size); void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr); diff --git a/qemu/m68k.h b/qemu/m68k.h index 05a59653..114bb0a6 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -149,6 +149,7 @@ #define tlb_flush tlb_flush_m68k #define tlb_flush_page tlb_flush_page_m68k #define tlb_set_page tlb_set_page_m68k +#define tlb_set_page_with_attrs tlb_set_page_with_attrs_m68k #define arm_translate_init arm_translate_init_m68k #define arm_v7m_class_init arm_v7m_class_init_m68k #define arm_v7m_cpu_do_interrupt arm_v7m_cpu_do_interrupt_m68k diff --git a/qemu/mips.h b/qemu/mips.h index b328f678..8f5f9119 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -149,6 +149,7 @@ #define tlb_flush tlb_flush_mips #define tlb_flush_page tlb_flush_page_mips #define tlb_set_page tlb_set_page_mips +#define tlb_set_page_with_attrs tlb_set_page_with_attrs_mips #define arm_translate_init arm_translate_init_mips #define arm_v7m_class_init arm_v7m_class_init_mips #define arm_v7m_cpu_do_interrupt arm_v7m_cpu_do_interrupt_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index 0385e4db..198329f9 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -149,6 +149,7 @@ #define tlb_flush tlb_flush_mips64 #define tlb_flush_page tlb_flush_page_mips64 #define tlb_set_page tlb_set_page_mips64 +#define tlb_set_page_with_attrs tlb_set_page_with_attrs_mips64 #define arm_translate_init arm_translate_init_mips64 #define arm_v7m_class_init arm_v7m_class_init_mips64 #define arm_v7m_cpu_do_interrupt arm_v7m_cpu_do_interrupt_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index 466a6910..1f74cb7c 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -149,6 +149,7 @@ #define tlb_flush tlb_flush_mips64el #define tlb_flush_page tlb_flush_page_mips64el #define tlb_set_page tlb_set_page_mips64el +#define tlb_set_page_with_attrs tlb_set_page_with_attrs_mips64el #define arm_translate_init arm_translate_init_mips64el #define arm_v7m_class_init arm_v7m_class_init_mips64el #define arm_v7m_cpu_do_interrupt arm_v7m_cpu_do_interrupt_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index 8d4bc492..e2b6eec5 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -149,6 +149,7 @@ #define tlb_flush tlb_flush_mipsel #define tlb_flush_page tlb_flush_page_mipsel #define tlb_set_page tlb_set_page_mipsel +#define tlb_set_page_with_attrs tlb_set_page_with_attrs_mipsel #define arm_translate_init arm_translate_init_mipsel #define arm_v7m_class_init arm_v7m_class_init_mipsel #define arm_v7m_cpu_do_interrupt arm_v7m_cpu_do_interrupt_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index df0087c8..5b68c188 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -149,6 +149,7 @@ #define tlb_flush tlb_flush_powerpc #define tlb_flush_page tlb_flush_page_powerpc #define tlb_set_page tlb_set_page_powerpc +#define tlb_set_page_with_attrs tlb_set_page_with_attrs_powerpc #define arm_translate_init arm_translate_init_powerpc #define arm_v7m_class_init arm_v7m_class_init_powerpc #define arm_v7m_cpu_do_interrupt arm_v7m_cpu_do_interrupt_powerpc diff --git a/qemu/softmmu_template.h b/qemu/softmmu_template.h index 8e4fe1a7..d494fb12 100644 --- a/qemu/softmmu_template.h +++ b/qemu/softmmu_template.h @@ -175,7 +175,7 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env, cpu->mem_io_vaddr = addr; memory_region_dispatch_read(mr, physaddr, &val, 1 << SHIFT, - MEMTXATTRS_UNSPECIFIED); + iotlbentry->attrs); return (DATA_TYPE)val; } #endif @@ -677,7 +677,7 @@ static inline void glue(io_write, SUFFIX)(CPUArchState *env, cpu->mem_io_vaddr = addr; cpu->mem_io_pc = retaddr; memory_region_dispatch_write(mr, physaddr, val, 1 << SHIFT, - MEMTXATTRS_UNSPECIFIED); + iotlbentry->attrs); } void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, diff --git a/qemu/sparc.h b/qemu/sparc.h index 1e931f78..302b8a30 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -149,6 +149,7 @@ #define tlb_flush tlb_flush_sparc #define tlb_flush_page tlb_flush_page_sparc #define tlb_set_page tlb_set_page_sparc +#define tlb_set_page_with_attrs tlb_set_page_with_attrs_sparc #define arm_translate_init arm_translate_init_sparc #define arm_v7m_class_init arm_v7m_class_init_sparc #define arm_v7m_cpu_do_interrupt arm_v7m_cpu_do_interrupt_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index 12bc6175..ba1c89b7 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -149,6 +149,7 @@ #define tlb_flush tlb_flush_sparc64 #define tlb_flush_page tlb_flush_page_sparc64 #define tlb_set_page tlb_set_page_sparc64 +#define tlb_set_page_with_attrs tlb_set_page_with_attrs_sparc64 #define arm_translate_init arm_translate_init_sparc64 #define arm_v7m_class_init arm_v7m_class_init_sparc64 #define arm_v7m_cpu_do_interrupt arm_v7m_cpu_do_interrupt_sparc64 diff --git a/qemu/x86_64.h b/qemu/x86_64.h index 75b45d2b..d076f666 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -149,6 +149,7 @@ #define tlb_flush tlb_flush_x86_64 #define tlb_flush_page tlb_flush_page_x86_64 #define tlb_set_page tlb_set_page_x86_64 +#define tlb_set_page_with_attrs tlb_set_page_with_attrs_x86_64 #define arm_translate_init arm_translate_init_x86_64 #define arm_v7m_class_init arm_v7m_class_init_x86_64 #define arm_v7m_cpu_do_interrupt arm_v7m_cpu_do_interrupt_x86_64