From: Richard Henderson <richard.henderson@linaro.org>
To: qemu-devel@nongnu.org
Cc: peter.maydell@linaro.org, qemu-arm@nongnu.org,
david.spickett@linaro.org, steplong@quicinc.com
Subject: [PATCH v8 43/45] target/arm: Create tagged ram when MTE is enabled
Date: Tue, 23 Jun 2020 12:36:56 -0700 [thread overview]
Message-ID: <20200623193658.623279-44-richard.henderson@linaro.org> (raw)
In-Reply-To: <20200623193658.623279-1-richard.henderson@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
v5: Assign cs->num_ases to the final value first.
Downgrade to ID_AA64PFR1.MTE=1 if tag memory is not available.
v6: Add secure tag memory for EL3.
v8: Add arm,armv8.5-memtag.
---
include/hw/arm/boot.h | 3 +++
target/arm/cpu.h | 6 +++++
hw/arm/boot.c | 12 ++++++---
hw/arm/virt.c | 57 +++++++++++++++++++++++++++++++++++++++++--
target/arm/cpu.c | 51 +++++++++++++++++++++++++++++++++++---
5 files changed, 121 insertions(+), 8 deletions(-)
diff --git a/include/hw/arm/boot.h b/include/hw/arm/boot.h
index ce2b48b88b..605446afe7 100644
--- a/include/hw/arm/boot.h
+++ b/include/hw/arm/boot.h
@@ -116,6 +116,9 @@ struct arm_boot_info {
*/
bool secure_board_setup;
+ /* If set, all ram objects have tag memory objects. */
+ bool tag_memory;
+
arm_endianness endianness;
};
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 10c4d031b1..206e617c25 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -792,6 +792,10 @@ struct ARMCPU {
/* MemoryRegion to use for secure physical accesses */
MemoryRegion *secure_memory;
+ /* MemoryRegion to use for allocation tag accesses */
+ MemoryRegion *tag_memory;
+ MemoryRegion *secure_tag_memory;
+
/* For v8M, pointer to the IDAU interface provided by board/SoC */
Object *idau;
@@ -2985,6 +2989,8 @@ typedef enum ARMMMUIdxBit {
typedef enum ARMASIdx {
ARMASIdx_NS = 0,
ARMASIdx_S = 1,
+ ARMASIdx_TagNS = 2,
+ ARMASIdx_TagS = 3,
} ARMASIdx;
/* Return the Exception Level targeted by debug exceptions. */
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index fef4072db1..4f96ce42fe 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -427,7 +427,7 @@ static void set_kernel_args_old(const struct arm_boot_info *info,
static int fdt_add_memory_node(void *fdt, uint32_t acells, hwaddr mem_base,
uint32_t scells, hwaddr mem_len,
- int numa_node_id)
+ int numa_node_id, bool tag_memory)
{
char *nodename;
int ret;
@@ -446,6 +446,10 @@ static int fdt_add_memory_node(void *fdt, uint32_t acells, hwaddr mem_base,
ret = qemu_fdt_setprop_cell(fdt, nodename,
"numa-node-id", numa_node_id);
}
+ if (tag_memory) {
+ qemu_fdt_setprop(fdt, nodename, "arm,armv8.5-memtag", "", 0);
+ }
+
out:
g_free(nodename);
return ret;
@@ -534,6 +538,7 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
hwaddr mem_base, mem_len;
char **node_path;
Error *err = NULL;
+ bool tag_memory;
if (binfo->dtb_filename) {
char *filename;
@@ -599,12 +604,13 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
}
g_strfreev(node_path);
+ tag_memory = binfo->tag_memory;
if (ms->numa_state != NULL && ms->numa_state->num_nodes > 0) {
mem_base = binfo->loader_start;
for (i = 0; i < ms->numa_state->num_nodes; i++) {
mem_len = ms->numa_state->nodes[i].node_mem;
rc = fdt_add_memory_node(fdt, acells, mem_base,
- scells, mem_len, i);
+ scells, mem_len, i, tag_memory);
if (rc < 0) {
fprintf(stderr, "couldn't add /memory@%"PRIx64" node\n",
mem_base);
@@ -615,7 +621,7 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
}
} else {
rc = fdt_add_memory_node(fdt, acells, binfo->loader_start,
- scells, binfo->ram_size, -1);
+ scells, binfo->ram_size, -1, tag_memory);
if (rc < 0) {
fprintf(stderr, "couldn't add /memory@%"PRIx64" node\n",
binfo->loader_start);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index caceb1e4a0..0d81e0d3ac 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1390,8 +1390,19 @@ static void create_platform_bus(VirtMachineState *vms)
sysbus_mmio_get_region(s, 0));
}
+static void create_tag_ram(MemoryRegion *tag_sysmem,
+ hwaddr base, hwaddr size,
+ const char *name)
+{
+ MemoryRegion *tagram = g_new(MemoryRegion, 1);
+
+ memory_region_init_ram(tagram, NULL, name, size / 32, &error_fatal);
+ memory_region_add_subregion(tag_sysmem, base / 32, tagram);
+}
+
static void create_secure_ram(VirtMachineState *vms,
- MemoryRegion *secure_sysmem)
+ MemoryRegion *secure_sysmem,
+ MemoryRegion *secure_tag_sysmem)
{
MemoryRegion *secram = g_new(MemoryRegion, 1);
char *nodename;
@@ -1409,6 +1420,11 @@ static void create_secure_ram(VirtMachineState *vms,
qemu_fdt_setprop_string(vms->fdt, nodename, "status", "disabled");
qemu_fdt_setprop_string(vms->fdt, nodename, "secure-status", "okay");
+ if (secure_tag_sysmem) {
+ create_tag_ram(secure_tag_sysmem, base, size, "mach-virt.secure-tag");
+ qemu_fdt_setprop(vms->fdt, nodename, "arm,armv8.5-memtag", "", 0);
+ }
+
g_free(nodename);
}
@@ -1665,6 +1681,8 @@ static void machvirt_init(MachineState *machine)
const CPUArchIdList *possible_cpus;
MemoryRegion *sysmem = get_system_memory();
MemoryRegion *secure_sysmem = NULL;
+ MemoryRegion *tag_sysmem = NULL;
+ MemoryRegion *secure_tag_sysmem = NULL;
int n, virt_max_cpus;
bool firmware_loaded;
bool aarch64 = true;
@@ -1819,6 +1837,36 @@ static void machvirt_init(MachineState *machine)
"secure-memory", &error_abort);
}
+ /*
+ * The cpu adds the property if and only if MemTag is supported.
+ * If it is, we must allocate the ram to back that up.
+ */
+ if (object_property_find(cpuobj, "tag-memory", NULL)) {
+ if (!tag_sysmem) {
+ vms->bootinfo.tag_memory = true;
+ tag_sysmem = g_new(MemoryRegion, 1);
+ memory_region_init(tag_sysmem, OBJECT(machine),
+ "tag-memory", UINT64_MAX / 32);
+
+ if (vms->secure) {
+ secure_tag_sysmem = g_new(MemoryRegion, 1);
+ memory_region_init(secure_tag_sysmem, OBJECT(machine),
+ "secure-tag-memory", UINT64_MAX / 32);
+
+ /* As with ram, secure-tag takes precedence over tag. */
+ memory_region_add_subregion_overlap(secure_tag_sysmem, 0,
+ tag_sysmem, -1);
+ }
+ }
+
+ object_property_set_link(cpuobj, OBJECT(tag_sysmem),
+ "tag-memory", &error_abort);
+ if (vms->secure) {
+ object_property_set_link(cpuobj, OBJECT(secure_tag_sysmem),
+ "secure-tag-memory", &error_abort);
+ }
+ }
+
qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
object_unref(cpuobj);
}
@@ -1857,10 +1905,15 @@ static void machvirt_init(MachineState *machine)
create_uart(vms, VIRT_UART, sysmem, serial_hd(0));
if (vms->secure) {
- create_secure_ram(vms, secure_sysmem);
+ create_secure_ram(vms, secure_sysmem, secure_tag_sysmem);
create_uart(vms, VIRT_SECURE_UART, secure_sysmem, serial_hd(1));
}
+ if (tag_sysmem) {
+ create_tag_ram(tag_sysmem, vms->memmap[VIRT_MEM].base,
+ machine->ram_size, "mach-virt.tag");
+ }
+
vms->highmem_ecam &= vms->highmem && (!firmware_loaded || aarch64);
create_rtc(vms);
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index f09efc4370..7159188247 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1249,6 +1249,25 @@ void arm_cpu_post_init(Object *obj)
if (kvm_enabled()) {
kvm_arm_add_vcpu_properties(obj);
}
+
+#ifndef CONFIG_USER_ONLY
+ if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64) &&
+ cpu_isar_feature(aa64_mte, cpu)) {
+ object_property_add_link(obj, "tag-memory",
+ TYPE_MEMORY_REGION,
+ (Object **)&cpu->tag_memory,
+ qdev_prop_allow_set_link_before_realize,
+ OBJ_PROP_LINK_STRONG);
+
+ if (arm_feature(&cpu->env, ARM_FEATURE_EL3)) {
+ object_property_add_link(obj, "secure-tag-memory",
+ TYPE_MEMORY_REGION,
+ (Object **)&cpu->secure_tag_memory,
+ qdev_prop_allow_set_link_before_realize,
+ OBJ_PROP_LINK_STRONG);
+ }
+ }
+#endif
}
static void arm_cpu_finalizefn(Object *obj)
@@ -1739,17 +1758,43 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
MachineState *ms = MACHINE(qdev_get_machine());
unsigned int smp_cpus = ms->smp.cpus;
- if (cpu->has_el3 || arm_feature(env, ARM_FEATURE_M_SECURITY)) {
+ /*
+ * We must set cs->num_ases to the final value before
+ * the first call to cpu_address_space_init.
+ */
+ if (cpu->tag_memory != NULL) {
+ cs->num_ases = 4;
+ } else if (cpu->has_el3 || arm_feature(env, ARM_FEATURE_M_SECURITY)) {
cs->num_ases = 2;
+ } else {
+ cs->num_ases = 1;
+ }
+ if (cpu->has_el3 || arm_feature(env, ARM_FEATURE_M_SECURITY)) {
if (!cpu->secure_memory) {
cpu->secure_memory = cs->memory;
}
cpu_address_space_init(cs, ARMASIdx_S, "cpu-secure-memory",
cpu->secure_memory);
- } else {
- cs->num_ases = 1;
}
+
+ if (cpu->tag_memory != NULL) {
+ cpu_address_space_init(cs, ARMASIdx_TagNS, "cpu-tag-memory",
+ cpu->tag_memory);
+ if (cpu->has_el3) {
+ cpu_address_space_init(cs, ARMASIdx_TagS, "cpu-tag-memory",
+ cpu->secure_tag_memory);
+ }
+ } else if (cpu_isar_feature(aa64_mte, cpu)) {
+ /*
+ * Since there is no tag memory, we can't meaningfully support MTE
+ * to its fullest. To avoid problems later, when we would come to
+ * use the tag memory, downgrade support to insns only.
+ */
+ cpu->isar.id_aa64pfr1 =
+ FIELD_DP64(cpu->isar.id_aa64pfr1, ID_AA64PFR1, MTE, 1);
+ }
+
cpu_address_space_init(cs, ARMASIdx_NS, "cpu-memory", cs->memory);
/* No core_count specified, default to smp_cpus. */
--
2.25.1
next prev parent reply other threads:[~2020-06-23 20:13 UTC|newest]
Thread overview: 77+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-06-23 19:36 [PATCH v8 00/45] target/arm: Implement ARMv8.5-MemTag, system mode Richard Henderson
2020-06-23 19:36 ` [PATCH v8 01/45] target/arm: Add isar tests for mte Richard Henderson
2020-06-23 19:36 ` [PATCH v8 02/45] target/arm: Improve masking of SCR RES0 bits Richard Henderson
2020-06-23 19:36 ` [PATCH v8 03/45] target/arm: Add support for MTE to SCTLR_ELx Richard Henderson
2020-06-23 19:36 ` [PATCH v8 04/45] target/arm: Add support for MTE to HCR_EL2 and SCR_EL3 Richard Henderson
2020-06-23 19:36 ` [PATCH v8 05/45] target/arm: Rename DISAS_UPDATE to DISAS_UPDATE_EXIT Richard Henderson
2020-06-23 19:36 ` [PATCH v8 06/45] target/arm: Add DISAS_UPDATE_NOCHAIN Richard Henderson
2020-06-23 19:36 ` [PATCH v8 07/45] target/arm: Add MTE system registers Richard Henderson
2020-06-23 19:36 ` [PATCH v8 08/45] target/arm: Add MTE bits to tb_flags Richard Henderson
2020-06-23 19:36 ` [PATCH v8 09/45] target/arm: Implement the IRG instruction Richard Henderson
2020-06-23 19:36 ` [PATCH v8 10/45] target/arm: Revise decoding for disas_add_sub_imm Richard Henderson
2020-06-25 10:16 ` Peter Maydell
2020-06-23 19:36 ` [PATCH v8 11/45] target/arm: Implement the ADDG, SUBG instructions Richard Henderson
2020-06-25 10:39 ` Peter Maydell
2020-06-23 19:36 ` [PATCH v8 12/45] target/arm: Implement the GMI instruction Richard Henderson
2020-06-23 19:36 ` [PATCH v8 13/45] target/arm: Implement the SUBP instruction Richard Henderson
2020-06-23 19:36 ` [PATCH v8 14/45] target/arm: Define arm_cpu_do_unaligned_access for user-only Richard Henderson
2020-06-25 10:45 ` Peter Maydell
2020-06-23 19:36 ` [PATCH v8 15/45] target/arm: Implement LDG, STG, ST2G instructions Richard Henderson
2020-06-25 10:48 ` Peter Maydell
2020-06-23 19:36 ` [PATCH v8 16/45] target/arm: Implement the STGP instruction Richard Henderson
2020-06-23 19:36 ` [PATCH v8 17/45] target/arm: Restrict the values of DCZID.BS under TCG Richard Henderson
2020-06-23 19:36 ` [PATCH v8 18/45] target/arm: Simplify DC_ZVA Richard Henderson
2020-06-23 19:36 ` [PATCH v8 19/45] target/arm: Implement the LDGM, STGM, STZGM instructions Richard Henderson
2020-06-23 19:36 ` [PATCH v8 20/45] target/arm: Implement the access tag cache flushes Richard Henderson
2020-06-23 19:36 ` [PATCH v8 21/45] target/arm: Move regime_el to internals.h Richard Henderson
2020-06-23 19:36 ` [PATCH v8 22/45] target/arm: Move regime_tcr " Richard Henderson
2020-06-23 19:36 ` [PATCH v8 23/45] target/arm: Add gen_mte_check1 Richard Henderson
2020-06-23 19:36 ` [PATCH v8 24/45] target/arm: Add gen_mte_checkN Richard Henderson
2020-06-23 19:36 ` [PATCH v8 25/45] target/arm: Implement helper_mte_check1 Richard Henderson
2020-06-25 10:55 ` Peter Maydell
2020-06-23 19:36 ` [PATCH v8 26/45] target/arm: Implement helper_mte_checkN Richard Henderson
2020-06-23 19:36 ` [PATCH v8 27/45] target/arm: Add helper_mte_check_zva Richard Henderson
2020-06-23 19:36 ` [PATCH v8 28/45] target/arm: Use mte_checkN for sve unpredicated loads Richard Henderson
2020-06-25 11:06 ` Peter Maydell
2020-06-23 19:36 ` [PATCH v8 29/45] target/arm: Use mte_checkN for sve unpredicated stores Richard Henderson
2020-06-25 11:07 ` Peter Maydell
2020-06-23 19:36 ` [PATCH v8 30/45] target/arm: Use mte_check1 for sve LD1R Richard Henderson
2020-06-25 11:12 ` Peter Maydell
2020-06-23 19:36 ` [PATCH v8 31/45] target/arm: Tidy trans_LD1R_zpri Richard Henderson
2020-06-25 11:12 ` Peter Maydell
2020-06-23 19:36 ` [PATCH v8 32/45] target/arm: Add arm_tlb_bti_gp Richard Henderson
2020-06-25 12:29 ` Peter Maydell
2020-06-25 18:59 ` Richard Henderson
2020-06-23 19:36 ` [PATCH v8 33/45] target/arm: Add mte helpers for sve scalar + int loads Richard Henderson
2020-06-25 12:36 ` Peter Maydell
2020-06-23 19:36 ` [PATCH v8 34/45] target/arm: Add mte helpers for sve scalar + int stores Richard Henderson
2020-06-25 12:37 ` Peter Maydell
2020-06-23 19:36 ` [PATCH v8 35/45] target/arm: Add mte helpers for sve scalar + int ff/nf loads Richard Henderson
2020-06-25 12:38 ` Peter Maydell
2020-06-23 19:36 ` [PATCH v8 36/45] target/arm: Handle TBI for sve scalar + int memory ops Richard Henderson
2020-06-25 12:40 ` Peter Maydell
2020-06-23 19:36 ` [PATCH v8 37/45] target/arm: Add mte helpers for sve scatter/gather " Richard Henderson
2020-06-25 12:43 ` Peter Maydell
2020-06-23 19:36 ` [PATCH v8 38/45] target/arm: Complete TBI clearing for user-only for SVE Richard Henderson
2020-06-25 12:52 ` Peter Maydell
2020-06-25 16:54 ` Richard Henderson
2020-06-25 17:07 ` Peter Maydell
2020-06-23 19:36 ` [PATCH v8 39/45] target/arm: Implement data cache set allocation tags Richard Henderson
2020-06-23 19:36 ` [PATCH v8 40/45] target/arm: Set PSTATE.TCO on exception entry Richard Henderson
2020-06-23 19:36 ` [PATCH v8 41/45] target/arm: Always pass cacheattr to get_phys_addr Richard Henderson
2020-06-25 12:56 ` Peter Maydell
2020-06-23 19:36 ` [PATCH v8 42/45] target/arm: Cache the Tagged bit for a page in MemTxAttrs Richard Henderson
2020-06-25 12:59 ` Peter Maydell
2020-06-23 19:36 ` Richard Henderson [this message]
2020-06-25 13:26 ` [PATCH v8 43/45] target/arm: Create tagged ram when MTE is enabled Peter Maydell
2020-06-23 19:36 ` [PATCH v8 44/45] target/arm: Add allocation tag storage for system mode Richard Henderson
2020-06-25 13:03 ` Peter Maydell
2020-06-25 17:02 ` Richard Henderson
2020-06-25 17:09 ` Peter Maydell
2020-06-25 22:16 ` Richard Henderson
2020-06-23 19:36 ` [PATCH v8 45/45] target/arm: Enable MTE Richard Henderson
2020-06-25 13:06 ` Peter Maydell
2020-06-23 19:55 ` [PATCH v8 00/45] target/arm: Implement ARMv8.5-MemTag, system mode Derrick McKee
2020-06-23 20:06 ` Richard Henderson
2020-06-23 20:30 ` no-reply
2020-06-25 13:28 ` 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=20200623193658.623279-44-richard.henderson@linaro.org \
--to=richard.henderson@linaro.org \
--cc=david.spickett@linaro.org \
--cc=peter.maydell@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=steplong@quicinc.com \
/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).