Trap system register accesses to trace registers
Traps system register accesses to trace registers (ETM extension), but has no
effect on accesses through the memory-mapped interface.
Trace registers expose a side-channel that should be disabled system-wide.
Blocking access from the memory-mapped interface is done by not mapping
the address space to these registers. This is to be done in a separate commit,
see bug 143871895.
Additionally, making the register CPU-wide rather than per VM because none of
its fields were being set per VM. This would reduce the overhead of context
switching between VMs.
Bug: 141600635
Change-Id: Id84436c8f39d8bd11e80453d0c6e366d46fe7c20
diff --git a/src/arch/aarch64/cpu.c b/src/arch/aarch64/cpu.c
index 5025009..ba9d27b 100644
--- a/src/arch/aarch64/cpu.c
+++ b/src/arch/aarch64/cpu.c
@@ -78,7 +78,6 @@
{
uintreg_t pc = r->pc;
uintreg_t arg = r->r[0];
- uintreg_t cptr;
uintreg_t cnthctl;
memset_s(r, sizeof(*r), 0, sizeof(*r));
@@ -86,7 +85,6 @@
r->pc = pc;
r->r[0] = arg;
- cptr = 0;
cnthctl = 0;
if (is_primary) {
@@ -96,7 +94,6 @@
}
r->lazy.hcr_el2 = get_hcr_el2_value(vm_id);
- r->lazy.cptr_el2 = cptr;
r->lazy.cnthctl_el2 = cnthctl;
r->lazy.vttbr_el2 = pa_addr(table) | ((uint64_t)vm_id << 48);
r->lazy.vmpidr_el2 = vcpu_id;
@@ -147,4 +144,6 @@
* supports them, Hafnium ensures that they are disabled.
*/
lor_disable();
+
+ write_msr(CPTR_EL2, get_cptr_el2_value());
}
diff --git a/src/arch/aarch64/hypervisor/exceptions.S b/src/arch/aarch64/hypervisor/exceptions.S
index b8a1fcd..2f47c00 100644
--- a/src/arch/aarch64/hypervisor/exceptions.S
+++ b/src/arch/aarch64/hypervisor/exceptions.S
@@ -271,25 +271,22 @@
mrs x25, hcr_el2
stp x24, x25, [x28], #16
- mrs x26, cptr_el2
- mrs x27, cnthctl_el2
+ mrs x26, cnthctl_el2
+ mrs x27, vttbr_el2
stp x26, x27, [x28], #16
- mrs x4, vttbr_el2
- mrs x5, mdcr_el2
+ mrs x4, mdcr_el2
+ mrs x5, mdscr_el1
stp x4, x5, [x28], #16
- mrs x6, mdscr_el1
- mrs x7, pmccfiltr_el0
+ mrs x6, pmccfiltr_el0
+ mrs x7, pmcr_el0
stp x6, x7, [x28], #16
- mrs x8, pmcr_el0
- mrs x9, pmcntenset_el0
+ mrs x8, pmcntenset_el0
+ mrs x9, pmintenset_el1
stp x8, x9, [x28], #16
- mrs x10, pmintenset_el1
- str x10, [x28], #16
-
/* Save GIC registers. */
#if GIC_VERSION == 3 || GIC_VERSION == 4
/* Offset is too large, so start from a new base. */
@@ -439,34 +436,32 @@
msr hcr_el2, x25
ldp x26, x27, [x28], #16
- msr cptr_el2, x26
- msr cnthctl_el2, x27
+ msr cnthctl_el2, x26
+ msr vttbr_el2, x27
ldp x4, x5, [x28], #16
- msr vttbr_el2, x4
- msr mdcr_el2, x5
+ msr mdcr_el2, x4
+ msr mdscr_el1, x5
ldp x6, x7, [x28], #16
- msr mdscr_el1, x6
- msr pmccfiltr_el0, x7
+ msr pmccfiltr_el0, x6
+ msr pmcr_el0, x7
ldp x8, x9, [x28], #16
- msr pmcr_el0, x8
/*
* NOTE: Writing 0s to pmcntenset_el0's bits do not alter their values.
* To reset them, clear the register by writing to pmcntenclr_el0.
*/
mov x27, #0xffffffff
msr pmcntenclr_el0, x27
- msr pmcntenset_el0, x9
+ msr pmcntenset_el0, x8
- ldr x10, [x28], #16
/*
* NOTE: Writing 0s to pmintenset_el1's bits do not alter their values.
* To reset them, clear the register by writing to pmintenclr_el1.
*/
msr pmintenclr_el1, x27
- msr pmintenset_el1, x10
+ msr pmintenset_el1, x9
/* Restore GIC registers. */
#if GIC_VERSION == 3 || GIC_VERSION == 4
diff --git a/src/arch/aarch64/hypervisor/sysregs.c b/src/arch/aarch64/hypervisor/sysregs.c
index 779aa66..dcdf9d6 100644
--- a/src/arch/aarch64/hypervisor/sysregs.c
+++ b/src/arch/aarch64/hypervisor/sysregs.c
@@ -110,3 +110,11 @@
return mdcr_el2_value;
}
+
+/**
+ * Returns the value for MDCR_EL2 for the CPU.
+ */
+uintreg_t get_cptr_el2_value(void)
+{
+ return CPTR_EL2_TTA;
+}
diff --git a/src/arch/aarch64/hypervisor/sysregs.h b/src/arch/aarch64/hypervisor/sysregs.h
index f83aa95..63efa1f 100644
--- a/src/arch/aarch64/hypervisor/sysregs.h
+++ b/src/arch/aarch64/hypervisor/sysregs.h
@@ -370,6 +370,15 @@
*/
#define HCR_EL2_VM (UINT64_C(0x1) << 0)
+/**
+ * Trap system register accesses to trace registers.
+ * Traps accesses to ETM registers using the register interface. Does not trap
+ * on accesses through the memory-mapped interface.
+ */
+#define CPTR_EL2_TTA (UINT64_C(0x1) << 28)
+
uintreg_t get_hcr_el2_value(spci_vm_id_t vm_id);
uintreg_t get_mdcr_el2_value(spci_vm_id_t vm_id);
+
+uintreg_t get_cptr_el2_value(void);
diff --git a/src/arch/aarch64/inc/hf/arch/types.h b/src/arch/aarch64/inc/hf/arch/types.h
index b750631..987fd7b 100644
--- a/src/arch/aarch64/inc/hf/arch/types.h
+++ b/src/arch/aarch64/inc/hf/arch/types.h
@@ -106,7 +106,6 @@
uintreg_t spsr_el1;
uintreg_t par_el1;
uintreg_t hcr_el2;
- uintreg_t cptr_el2;
uintreg_t cnthctl_el2;
uintreg_t vttbr_el2;
uintreg_t mdcr_el2;