Initial commit
This commit is contained in:
+250
@@ -0,0 +1,250 @@
|
||||
From f526797b83113cc64e3e658c22d8a5d269896a2a Mon Sep 17 00:00:00 2001
|
||||
From: Ben Horgan <ben.horgan@arm.com>
|
||||
Date: Fri, 4 Mar 2022 16:48:14 +0000
|
||||
Subject: [PATCH] feat: emulate cntp timer register accesses using cnthps
|
||||
|
||||
Upstream-Status: Inappropriate [Experimental feature]
|
||||
Signed-off-by: Ben Horgan <ben.horgan@arm.com>
|
||||
Change-Id: I67508203273baf3bd8e6be2d99717028db945715
|
||||
---
|
||||
Makefile | 3 +-
|
||||
src/arch/aarch64/hypervisor/BUILD.gn | 1 +
|
||||
src/arch/aarch64/hypervisor/cpu.c | 11 ++-
|
||||
src/arch/aarch64/hypervisor/handler.c | 6 ++
|
||||
src/arch/aarch64/hypervisor/timer_el1.c | 104 ++++++++++++++++++++++++
|
||||
src/arch/aarch64/hypervisor/timer_el1.h | 20 +++++
|
||||
src/arch/aarch64/msr.h | 8 ++
|
||||
7 files changed, 150 insertions(+), 3 deletions(-)
|
||||
create mode 100644 src/arch/aarch64/hypervisor/timer_el1.c
|
||||
create mode 100644 src/arch/aarch64/hypervisor/timer_el1.h
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 95cab9a5..21cca938 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -60,7 +60,8 @@ CHECKPATCH := $(CURDIR)/third_party/linux/scripts/checkpatch.pl \
|
||||
# debug_el1.c : uses XMACROS, which checkpatch doesn't understand.
|
||||
# perfmon.c : uses XMACROS, which checkpatch doesn't understand.
|
||||
# feature_id.c : uses XMACROS, which checkpatch doesn't understand.
|
||||
-CHECKPATCH_IGNORE := "src/arch/aarch64/hypervisor/debug_el1.c\|src/arch/aarch64/hypervisor/perfmon.c\|src/arch/aarch64/hypervisor/feature_id.c"
|
||||
+# timer_el1.c : uses XMACROS, which checkpatch doesn't understand.
|
||||
+CHECKPATCH_IGNORE := "src/arch/aarch64/hypervisor/debug_el1.c\|src/arch/aarch64/hypervisor/perfmon.c\|src/arch/aarch64/hypervisor/feature_id.c\|src/arch/aarch64/hypervisor/timer_el1.c"
|
||||
|
||||
OUT ?= out/$(PROJECT)
|
||||
OUT_DIR = out/$(PROJECT)
|
||||
diff --git a/src/arch/aarch64/hypervisor/BUILD.gn b/src/arch/aarch64/hypervisor/BUILD.gn
|
||||
index 6068d1e8..de1a414d 100644
|
||||
--- a/src/arch/aarch64/hypervisor/BUILD.gn
|
||||
+++ b/src/arch/aarch64/hypervisor/BUILD.gn
|
||||
@@ -45,6 +45,7 @@ source_set("hypervisor") {
|
||||
"handler.c",
|
||||
"perfmon.c",
|
||||
"psci_handler.c",
|
||||
+ "timer_el1.c",
|
||||
"vm.c",
|
||||
]
|
||||
|
||||
diff --git a/src/arch/aarch64/hypervisor/cpu.c b/src/arch/aarch64/hypervisor/cpu.c
|
||||
index bcf5ffce..d2df77d8 100644
|
||||
--- a/src/arch/aarch64/hypervisor/cpu.c
|
||||
+++ b/src/arch/aarch64/hypervisor/cpu.c
|
||||
@@ -98,13 +98,20 @@ void arch_regs_reset(struct vcpu *vcpu)
|
||||
if (is_primary) {
|
||||
/*
|
||||
* cnthctl_el2 is redefined when VHE is enabled.
|
||||
- * EL1PCTEN, don't trap phys cnt access.
|
||||
- * EL1PCEN, don't trap phys timer access.
|
||||
+ * EL1PCTEN, don't trap phys cnt access. Except when in
|
||||
+ * secure world without vhe.
|
||||
+ * EL1PCEN, don't trap phys timer access. Except when in
|
||||
+ * secure world without vhe.
|
||||
*/
|
||||
if (has_vhe_support()) {
|
||||
cnthctl |= (1U << 10) | (1U << 11);
|
||||
} else {
|
||||
+#if SECURE_WORLD == 1
|
||||
+ cnthctl &= ~(1U << 0);
|
||||
+ cnthctl &= ~(1U << 1);
|
||||
+#else
|
||||
cnthctl |= (1U << 0) | (1U << 1);
|
||||
+#endif
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/arch/aarch64/hypervisor/handler.c b/src/arch/aarch64/hypervisor/handler.c
|
||||
index 4bd8a3b4..4c1b6e48 100644
|
||||
--- a/src/arch/aarch64/hypervisor/handler.c
|
||||
+++ b/src/arch/aarch64/hypervisor/handler.c
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "psci_handler.h"
|
||||
#include "smc.h"
|
||||
#include "sysregs.h"
|
||||
+#include "timer_el1.h"
|
||||
|
||||
/**
|
||||
* Hypervisor Fault Address Register Non-Secure.
|
||||
@@ -1277,6 +1278,11 @@ void handle_system_register_access(uintreg_t esr_el2)
|
||||
inject_el1_unknown_exception(vcpu, esr_el2);
|
||||
return;
|
||||
}
|
||||
+ } else if (timer_el1_is_register_access(esr_el2)) {
|
||||
+ if (!timer_el1_process_access(vcpu, vm_id, esr_el2)) {
|
||||
+ inject_el1_unknown_exception(vcpu, esr_el2);
|
||||
+ return;
|
||||
+ }
|
||||
} else {
|
||||
inject_el1_unknown_exception(vcpu, esr_el2);
|
||||
return;
|
||||
diff --git a/src/arch/aarch64/hypervisor/timer_el1.c b/src/arch/aarch64/hypervisor/timer_el1.c
|
||||
new file mode 100644
|
||||
index 00000000..c30e5543
|
||||
--- /dev/null
|
||||
+++ b/src/arch/aarch64/hypervisor/timer_el1.c
|
||||
@@ -0,0 +1,104 @@
|
||||
+/*
|
||||
+ * Copyright 2022 The Hafnium Authors.
|
||||
+ *
|
||||
+ * Use of this source code is governed by a BSD-style
|
||||
+ * license that can be found in the LICENSE file or at
|
||||
+ * https://opensource.org/licenses/BSD-3-Clause.
|
||||
+ */
|
||||
+
|
||||
+#include "timer_el1.h"
|
||||
+
|
||||
+#include "hf/dlog.h"
|
||||
+
|
||||
+#include "msr.h"
|
||||
+#include "sysregs.h"
|
||||
+
|
||||
+/*
|
||||
+ * Physical timer (CNTP) register encodings as defined in
|
||||
+ * table D13-8 of the ARMv8 ARM (DDI0487F).
|
||||
+ * TYPE, op0, op1, crn, crm, op2
|
||||
+ * The register names are the concatenation of
|
||||
+ * "CNTP_", TYPE and "_EL2".
|
||||
+ */
|
||||
+#define CNTP_REGISTERS \
|
||||
+ X(CTL, 3, 3, 14, 2, 1) \
|
||||
+ X(CVAL, 3, 3, 14, 2, 2) \
|
||||
+ X(TVAL, 3, 3, 14, 2, 0) \
|
||||
+
|
||||
+bool timer_el1_is_register_access(uintreg_t esr)
|
||||
+{
|
||||
+ uintreg_t sys_register = GET_ISS_SYSREG(esr);
|
||||
+ bool is_timer_access;
|
||||
+ switch (sys_register) {
|
||||
+#define X(type, op0, op1, crn, crm, op2) \
|
||||
+ case (GET_ISS_ENCODING(op0, op1, crn, crm, op2)): \
|
||||
+ is_timer_access = true; \
|
||||
+ break;
|
||||
+ CNTP_REGISTERS
|
||||
+#undef X
|
||||
+ case (GET_ISS_ENCODING(3, 3, 14, 0, 1)):
|
||||
+ is_timer_access = true;
|
||||
+ break;
|
||||
+ default:
|
||||
+ is_timer_access = false;
|
||||
+ }
|
||||
+
|
||||
+ return is_timer_access;
|
||||
+}
|
||||
+
|
||||
+/* Accesses to CNTP timer emulated with CNTHPS */
|
||||
+bool timer_el1_process_access(struct vcpu *vcpu, ffa_vm_id_t vm_id,
|
||||
+ uintreg_t esr)
|
||||
+{
|
||||
+ uintreg_t sys_register = GET_ISS_SYSREG(esr);
|
||||
+ uintreg_t rt_register = GET_ISS_RT(esr);
|
||||
+ uintreg_t value;
|
||||
+
|
||||
+ if (ISS_IS_READ(esr)) {
|
||||
+ switch (sys_register) {
|
||||
+#define X(type, op0, op1, crn, crm, op2) \
|
||||
+ case (GET_ISS_ENCODING(op0, op1, crn, crm, op2)): \
|
||||
+ value = read_msr(MSR_CNTHPS_##type##_EL2); \
|
||||
+ vcpu->regs.r[rt_register] = value; \
|
||||
+ break;
|
||||
+ CNTP_REGISTERS
|
||||
+#undef X
|
||||
+ case (GET_ISS_ENCODING(3, 3, 14, 0, 1)):
|
||||
+ value = read_msr(cntpct_el0);
|
||||
+ vcpu->regs.r[rt_register] = value;
|
||||
+ break;
|
||||
+ default:
|
||||
+ dlog_notice(
|
||||
+ "Unsupported timer register "
|
||||
+ "read: "
|
||||
+ "op0=%d, op1=%d, crn=%d, crm=%d, op2=%d, "
|
||||
+ "rt=%d.\n",
|
||||
+ GET_ISS_OP0(esr), GET_ISS_OP1(esr),
|
||||
+ GET_ISS_CRN(esr), GET_ISS_CRM(esr),
|
||||
+ GET_ISS_OP2(esr), GET_ISS_RT(esr));
|
||||
+ break;
|
||||
+ }
|
||||
+ } else {
|
||||
+ value = vcpu->regs.r[rt_register];
|
||||
+ switch (sys_register) {
|
||||
+#define X(type, op0, op1, crn, crm, op2) \
|
||||
+ case (GET_ISS_ENCODING(op0, op1, crn, crm, op2)): \
|
||||
+ write_msr(MSR_CNTHPS_##type##_EL2, value); \
|
||||
+ break;
|
||||
+ CNTP_REGISTERS
|
||||
+#undef X
|
||||
+ default:
|
||||
+ dlog_notice(
|
||||
+ "Unsupported timer register "
|
||||
+ "write: "
|
||||
+ "op0=%d, op1=%d, crn=%d, crm=%d, op2=%d, "
|
||||
+ "rt=%d, value=%d.\n",
|
||||
+ GET_ISS_OP0(esr), GET_ISS_OP1(esr),
|
||||
+ GET_ISS_CRN(esr), GET_ISS_CRM(esr),
|
||||
+ GET_ISS_OP2(esr), GET_ISS_RT(esr), value);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
diff --git a/src/arch/aarch64/hypervisor/timer_el1.h b/src/arch/aarch64/hypervisor/timer_el1.h
|
||||
new file mode 100644
|
||||
index 00000000..04a43b6c
|
||||
--- /dev/null
|
||||
+++ b/src/arch/aarch64/hypervisor/timer_el1.h
|
||||
@@ -0,0 +1,20 @@
|
||||
+/*
|
||||
+ * Copyright 2022 The Hafnium Authors.
|
||||
+ *
|
||||
+ * Use of this source code is governed by a BSD-style
|
||||
+ * license that can be found in the LICENSE file or at
|
||||
+ * https://opensource.org/licenses/BSD-3-Clause.
|
||||
+ */
|
||||
+
|
||||
+#pragma once
|
||||
+
|
||||
+#include "hf/arch/types.h"
|
||||
+
|
||||
+#include "hf/cpu.h"
|
||||
+
|
||||
+#include "vmapi/hf/ffa.h"
|
||||
+
|
||||
+bool timer_el1_is_register_access(uintreg_t esr);
|
||||
+
|
||||
+bool timer_el1_process_access(struct vcpu *vcpu, ffa_vm_id_t vm_id,
|
||||
+ uintreg_t esr);
|
||||
diff --git a/src/arch/aarch64/msr.h b/src/arch/aarch64/msr.h
|
||||
index cd6778b4..55e78330 100644
|
||||
--- a/src/arch/aarch64/msr.h
|
||||
+++ b/src/arch/aarch64/msr.h
|
||||
@@ -126,3 +126,11 @@
|
||||
#define MSR_ELR_EL12 S3_5_C4_C0_1
|
||||
|
||||
#endif
|
||||
+
|
||||
+/*
|
||||
+ * Secure EL2 Physical timer (CNTHPS) register encodings as defined in
|
||||
+ * table D13-8 of the ARMv8 ARM (DDI0487F).
|
||||
+ */
|
||||
+#define MSR_CNTHPS_CTL_EL2 S3_4_C14_C5_1
|
||||
+#define MSR_CNTHPS_CVAL_EL2 S3_4_C14_C5_2
|
||||
+#define MSR_CNTHPS_TVAL_EL2 S3_4_C14_C5_0
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
From 613dea068fa546956717ce0b60328e39d451f661 Mon Sep 17 00:00:00 2001
|
||||
From: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
|
||||
Date: Fri, 29 Apr 2022 20:07:50 +0100
|
||||
Subject: [PATCH] tc: increase heap pages
|
||||
|
||||
Upstream-Status: Pending
|
||||
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
|
||||
---
|
||||
BUILD.gn | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/BUILD.gn b/BUILD.gn
|
||||
index 6b9b383..62ba763 100644
|
||||
--- a/BUILD.gn
|
||||
+++ b/BUILD.gn
|
||||
@@ -235,7 +235,7 @@ aarch64_toolchains("secure_tc") {
|
||||
gicd_base_address = "0x30000000"
|
||||
gicr_base_address = "0x30080000"
|
||||
gicr_frames = 8
|
||||
- heap_pages = 60
|
||||
+ heap_pages = 120
|
||||
max_cpus = 8
|
||||
max_vms = 16
|
||||
branch_protection = "standard"
|
||||
--
|
||||
2.30.2
|
||||
|
||||
+157
@@ -0,0 +1,157 @@
|
||||
From 97a8ca1835f5d9512dacda497540d5523e56c7dd Mon Sep 17 00:00:00 2001
|
||||
From: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
|
||||
Date: Tue, 26 Apr 2022 14:43:58 +0100
|
||||
Subject: [PATCH] feat: emulate interrupt controller register access
|
||||
|
||||
This emulates ICC_SGI1R_EL1 and ICC_IGRPEN1_EL1 register
|
||||
|
||||
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
|
||||
Change-Id: I0c11f034f3676067597461a183a341c809adcaa4
|
||||
Upstream-Status: Inappropriate [Experimental feature]
|
||||
---
|
||||
src/arch/aarch64/hypervisor/handler.c | 5 ++
|
||||
src/arch/aarch64/hypervisor/perfmon.c | 84 +++++++++++++++++++++++++++
|
||||
src/arch/aarch64/hypervisor/perfmon.h | 5 ++
|
||||
src/arch/aarch64/msr.h | 3 +
|
||||
4 files changed, 97 insertions(+)
|
||||
|
||||
diff --git a/src/arch/aarch64/hypervisor/handler.c b/src/arch/aarch64/hypervisor/handler.c
|
||||
index 4c1b6e48..cd5146bd 100644
|
||||
--- a/src/arch/aarch64/hypervisor/handler.c
|
||||
+++ b/src/arch/aarch64/hypervisor/handler.c
|
||||
@@ -1283,6 +1283,11 @@ void handle_system_register_access(uintreg_t esr_el2)
|
||||
inject_el1_unknown_exception(vcpu, esr_el2);
|
||||
return;
|
||||
}
|
||||
+ } else if (intr_ctrl_is_register_access(esr_el2)) {
|
||||
+ if (!intr_ctrl_el1_process_access(vcpu, vm_id, esr_el2)) {
|
||||
+ inject_el1_unknown_exception(vcpu, esr_el2);
|
||||
+ return;
|
||||
+ }
|
||||
} else {
|
||||
inject_el1_unknown_exception(vcpu, esr_el2);
|
||||
return;
|
||||
diff --git a/src/arch/aarch64/hypervisor/perfmon.c b/src/arch/aarch64/hypervisor/perfmon.c
|
||||
index f13b0354..05e216c8 100644
|
||||
--- a/src/arch/aarch64/hypervisor/perfmon.c
|
||||
+++ b/src/arch/aarch64/hypervisor/perfmon.c
|
||||
@@ -116,6 +116,10 @@
|
||||
X(PMEVTYPER30_EL0 , 3, 3, 14, 15, 6) \
|
||||
X(PMCCFILTR_EL0 , 3, 3, 14, 15, 7)
|
||||
|
||||
+#define INTR_CTRL_REGISTERS \
|
||||
+ X(ICC_IGRPEN1_EL1 , 3, 0, 12, 12, 7) \
|
||||
+ X(ICC_SGI1R_EL1 , 3, 0, 12, 11, 5) \
|
||||
+
|
||||
/* clang-format on */
|
||||
|
||||
/**
|
||||
@@ -232,3 +236,83 @@ uintreg_t perfmon_get_pmccfiltr_el0_init_value(ffa_vm_id_t vm_id)
|
||||
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+bool intr_ctrl_is_register_access(uintreg_t esr)
|
||||
+{
|
||||
+ uintreg_t op0 = GET_ISS_OP0(esr);
|
||||
+ uintreg_t op1 = GET_ISS_OP1(esr);
|
||||
+ uintreg_t crn = GET_ISS_CRN(esr);
|
||||
+ uintreg_t crm = GET_ISS_CRM(esr);
|
||||
+
|
||||
+ if (op0 == 3 && op1 == 0 && crn == 12 && crm == 12) {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ if (op0 == 3 && op1 == 0 && crn == 12 && crm == 11) {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+bool intr_ctrl_el1_process_access(struct vcpu *vcpu, ffa_vm_id_t vm_id,
|
||||
+ uintreg_t esr)
|
||||
+{
|
||||
+ uintreg_t sys_register = GET_ISS_SYSREG(esr);
|
||||
+ uintreg_t rt_register = GET_ISS_RT(esr);
|
||||
+ uintreg_t value;
|
||||
+
|
||||
+ /* +1 because Rt can access register XZR */
|
||||
+ CHECK(rt_register < NUM_GP_REGS + 1);
|
||||
+
|
||||
+ if (ISS_IS_READ(esr)) {
|
||||
+ switch (sys_register) {
|
||||
+#define X(reg_name, op0, op1, crn, crm, op2) \
|
||||
+ case (GET_ISS_ENCODING(op0, op1, crn, crm, op2)): \
|
||||
+ value = read_msr(reg_name); \
|
||||
+ break;
|
||||
+ INTR_CTRL_REGISTERS
|
||||
+#undef X
|
||||
+ default:
|
||||
+ value = vcpu->regs.r[rt_register];
|
||||
+ dlog_notice(
|
||||
+ "Unsupported interrupt control register "
|
||||
+ "read: "
|
||||
+ "op0=%d, op1=%d, crn=%d, crm=%d, op2=%d, "
|
||||
+ "rt=%d.\n",
|
||||
+ GET_ISS_OP0(esr), GET_ISS_OP1(esr),
|
||||
+ GET_ISS_CRN(esr), GET_ISS_CRM(esr),
|
||||
+ GET_ISS_OP2(esr), GET_ISS_RT(esr));
|
||||
+ break;
|
||||
+ }
|
||||
+ if (rt_register != RT_REG_XZR) {
|
||||
+ vcpu->regs.r[rt_register] = value;
|
||||
+ }
|
||||
+ } else {
|
||||
+ if (rt_register != RT_REG_XZR) {
|
||||
+ value = vcpu->regs.r[rt_register];
|
||||
+ } else {
|
||||
+ value = 0;
|
||||
+ }
|
||||
+ switch (sys_register) {
|
||||
+#define X(reg_name, op0, op1, crn, crm, op2) \
|
||||
+ case (GET_ISS_ENCODING(op0, op1, crn, crm, op2)): \
|
||||
+ write_msr(reg_name, value); \
|
||||
+ break;
|
||||
+ INTR_CTRL_REGISTERS
|
||||
+#undef X
|
||||
+ default:
|
||||
+ dlog_notice(
|
||||
+ "Unsupported interrupt control register "
|
||||
+ "write: "
|
||||
+ "op0=%d, op1=%d, crn=%d, crm=%d, op2=%d, "
|
||||
+ "rt=%d.\n",
|
||||
+ GET_ISS_OP0(esr), GET_ISS_OP1(esr),
|
||||
+ GET_ISS_CRN(esr), GET_ISS_CRM(esr),
|
||||
+ GET_ISS_OP2(esr), GET_ISS_RT(esr));
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
diff --git a/src/arch/aarch64/hypervisor/perfmon.h b/src/arch/aarch64/hypervisor/perfmon.h
|
||||
index 81669ba1..c90d45bf 100644
|
||||
--- a/src/arch/aarch64/hypervisor/perfmon.h
|
||||
+++ b/src/arch/aarch64/hypervisor/perfmon.h
|
||||
@@ -70,3 +70,8 @@ bool perfmon_process_access(struct vcpu *vcpu, ffa_vm_id_t vm_id,
|
||||
uintreg_t esr_el2);
|
||||
|
||||
uintreg_t perfmon_get_pmccfiltr_el0_init_value(ffa_vm_id_t vm_id);
|
||||
+
|
||||
+bool intr_ctrl_is_register_access(uintreg_t esr);
|
||||
+
|
||||
+bool intr_ctrl_el1_process_access(struct vcpu *vcpu, ffa_vm_id_t vm_id,
|
||||
+ uintreg_t esr);
|
||||
diff --git a/src/arch/aarch64/msr.h b/src/arch/aarch64/msr.h
|
||||
index 55e78330..82aa8846 100644
|
||||
--- a/src/arch/aarch64/msr.h
|
||||
+++ b/src/arch/aarch64/msr.h
|
||||
@@ -134,3 +134,6 @@
|
||||
#define MSR_CNTHPS_CTL_EL2 S3_4_C14_C5_1
|
||||
#define MSR_CNTHPS_CVAL_EL2 S3_4_C14_C5_2
|
||||
#define MSR_CNTHPS_TVAL_EL2 S3_4_C14_C5_0
|
||||
+
|
||||
+#define ICC_IGRPEN1_EL1 S3_0_C12_C12_7
|
||||
+#define ICC_SGI1R_EL1 S3_0_C12_C11_5
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
From 1fef5bd2504ce3a203c56a3b66dba773cd4893c6 Mon Sep 17 00:00:00 2001
|
||||
From: Davidson K <davidson.kumaresan@arm.com>
|
||||
Date: Thu, 8 Sep 2022 10:47:10 +0530
|
||||
Subject: [PATCH] feat(vhe): enable vhe and disable branch protection for TC
|
||||
|
||||
Signed-off-by: Davidson K <davidson.kumaresan@arm.com>
|
||||
Change-Id: I60cd607d9f2bf0114b482980e7ca68e24aaf4d1f
|
||||
Upstream-Status: Pending [Not submitted to upstream yet]
|
||||
---
|
||||
BUILD.gn | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/BUILD.gn b/BUILD.gn
|
||||
index 62ba763..f26ce03 100644
|
||||
--- a/BUILD.gn
|
||||
+++ b/BUILD.gn
|
||||
@@ -238,7 +238,6 @@ aarch64_toolchains("secure_tc") {
|
||||
heap_pages = 120
|
||||
max_cpus = 8
|
||||
max_vms = 16
|
||||
- branch_protection = "standard"
|
||||
toolchain_args = {
|
||||
plat_ffa = "//src/arch/aarch64/plat/ffa:spmc"
|
||||
plat_psci = "//src/arch/aarch64/plat/psci:spmc"
|
||||
@@ -247,5 +246,6 @@ aarch64_toolchains("secure_tc") {
|
||||
secure_world = "1"
|
||||
pl011_base_address = "0x7ff80000"
|
||||
enable_mte = "1"
|
||||
+ enable_vhe = "1"
|
||||
}
|
||||
}
|
||||
+318
@@ -0,0 +1,318 @@
|
||||
From 1c4d28493faed6cf189c75fa91d19131e6a34e04 Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Deprez <olivier.deprez@arm.com>
|
||||
Date: Mon, 8 Aug 2022 19:14:23 +0200
|
||||
Subject: [PATCH] feat: disable alignment check for EL0 partitions
|
||||
|
||||
Relax hw alignment check specifically for (S-)EL0 partitions when
|
||||
Hafnium runs with VHE enabled. EL1 partitions have a specific control
|
||||
for EL1 and EL0 with respect to alignment check.
|
||||
Create a hyp_state structure (from already defined flying registers)
|
||||
within the vCPU context to hold the Hypervisor EL2 static configuration
|
||||
applied when a vCPU runs. This state is switched back and forth when
|
||||
running the Hypervisor or the VM.
|
||||
Add SCTLR_EL2 to this context. An EL0 partition context is initialized
|
||||
with SCTLR_EL2.A=0 such that alignment check is disabled when EL0 runs
|
||||
in the EL2&0 translation regime. SCTLR_EL2.A is set back when returning
|
||||
to the Hypervisor such that Hypervisor execution runs with aligment
|
||||
check enabled at EL2.
|
||||
Remove HCR_EL2 saving from vCPU exit path provided this register state
|
||||
is static and doesn't change while a vCPU runs.
|
||||
The rationale for such change is to permit running upstream SW stacks
|
||||
such as the EDKII/StandaloneMm [1] for which default build assumes
|
||||
unaligned accesses are permitted. Similar query exists for running
|
||||
Trusted Services on top of Hafnium [2].
|
||||
|
||||
[1] https://github.com/tianocore/edk2/tree/master/StandaloneMmPkg
|
||||
[2] https://trusted-services.readthedocs.io/en/integration/
|
||||
|
||||
Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
|
||||
Change-Id: I2906f4c712425fcfb31adbf89e2e3b9ca293f181
|
||||
Upstream-Status: Submitted [https://review.trustedfirmware.org/c/hafnium/hafnium/+/16195]
|
||||
---
|
||||
src/arch/aarch64/hypervisor/cpu.c | 9 ++++---
|
||||
src/arch/aarch64/hypervisor/exceptions.S | 32 ++++++++++++++++--------
|
||||
src/arch/aarch64/hypervisor/feature_id.c | 6 ++---
|
||||
src/arch/aarch64/hypervisor/handler.c | 18 +++++++------
|
||||
src/arch/aarch64/inc/hf/arch/types.h | 9 +++++--
|
||||
src/arch/aarch64/mm.c | 2 +-
|
||||
src/arch/aarch64/sysregs.c | 11 ++++++--
|
||||
src/arch/aarch64/sysregs.h | 2 +-
|
||||
8 files changed, 59 insertions(+), 30 deletions(-)
|
||||
|
||||
diff --git a/src/arch/aarch64/hypervisor/cpu.c b/src/arch/aarch64/hypervisor/cpu.c
|
||||
index d2df77d8..a000159b 100644
|
||||
--- a/src/arch/aarch64/hypervisor/cpu.c
|
||||
+++ b/src/arch/aarch64/hypervisor/cpu.c
|
||||
@@ -115,7 +115,9 @@ void arch_regs_reset(struct vcpu *vcpu)
|
||||
}
|
||||
}
|
||||
|
||||
- r->hcr_el2 = get_hcr_el2_value(vm_id, vcpu->vm->el0_partition);
|
||||
+ r->hyp_state.hcr_el2 =
|
||||
+ get_hcr_el2_value(vm_id, vcpu->vm->el0_partition);
|
||||
+ r->hyp_state.sctlr_el2 = get_sctlr_el2_value(vcpu->vm->el0_partition);
|
||||
r->lazy.cnthctl_el2 = cnthctl;
|
||||
if (vcpu->vm->el0_partition) {
|
||||
CHECK(has_vhe_support());
|
||||
@@ -125,10 +127,11 @@ void arch_regs_reset(struct vcpu *vcpu)
|
||||
* are ignored and treated as 0. There is no need to mask the
|
||||
* VMID (used as asid) to only 8 bits.
|
||||
*/
|
||||
- r->ttbr0_el2 = pa_addr(table) | ((uint64_t)vm_id << 48);
|
||||
+ r->hyp_state.ttbr0_el2 =
|
||||
+ pa_addr(table) | ((uint64_t)vm_id << 48);
|
||||
r->spsr = PSR_PE_MODE_EL0T;
|
||||
} else {
|
||||
- r->ttbr0_el2 = read_msr(ttbr0_el2);
|
||||
+ r->hyp_state.ttbr0_el2 = read_msr(ttbr0_el2);
|
||||
r->lazy.vtcr_el2 = arch_mm_get_vtcr_el2();
|
||||
r->lazy.vttbr_el2 = pa_addr(table) | ((uint64_t)vm_id << 48);
|
||||
#if SECURE_WORLD == 1
|
||||
diff --git a/src/arch/aarch64/hypervisor/exceptions.S b/src/arch/aarch64/hypervisor/exceptions.S
|
||||
index 539e196d..d3732f86 100644
|
||||
--- a/src/arch/aarch64/hypervisor/exceptions.S
|
||||
+++ b/src/arch/aarch64/hypervisor/exceptions.S
|
||||
@@ -20,6 +20,9 @@
|
||||
#define ID_AA64PFR0_SVE_SHIFT (32)
|
||||
#define ID_AA64PFR0_SVE_LENGTH (4)
|
||||
|
||||
+#define SCTLR_EL2_A_SHIFT (1)
|
||||
+#define HCR_EL2_TGE_SHIFT (27)
|
||||
+
|
||||
/**
|
||||
* Saves the volatile registers into the register buffer of the current vCPU.
|
||||
*/
|
||||
@@ -51,8 +54,6 @@
|
||||
mrs x1, elr_el2
|
||||
mrs x2, spsr_el2
|
||||
stp x1, x2, [x18, #VCPU_REGS + 8 * 31]
|
||||
- mrs x1, hcr_el2
|
||||
- str x1, [x18, #VCPU_REGS + 8 * 33]
|
||||
.endm
|
||||
|
||||
/**
|
||||
@@ -871,12 +872,13 @@ vcpu_restore_volatile_and_run:
|
||||
msr elr_el2, x1
|
||||
msr spsr_el2, x2
|
||||
|
||||
- ldr x1, [x0, #VCPU_REGS + 8 * 33]
|
||||
+ ldp x1, x2, [x0, #VCPU_REGS + 8 * 33]
|
||||
msr hcr_el2, x1
|
||||
+ msr ttbr0_el2, x2
|
||||
isb
|
||||
|
||||
- ldr x1, [x0, #VCPU_REGS + 8 * 34]
|
||||
- msr ttbr0_el2, x1
|
||||
+ ldr x1, [x0, #VCPU_REGS + 8 * 35]
|
||||
+ msr sctlr_el2, x1
|
||||
isb
|
||||
|
||||
/* Restore x0..x3, which we have used as scratch before. */
|
||||
@@ -886,15 +888,17 @@ vcpu_restore_volatile_and_run:
|
||||
|
||||
#if ENABLE_VHE
|
||||
enable_vhe_tge:
|
||||
+ mrs x0, id_aa64mmfr1_el1
|
||||
+ tst x0, #0xf00
|
||||
+ b.eq 1f
|
||||
+
|
||||
/**
|
||||
* Switch to host mode ({E2H, TGE} = {1,1}) when VHE is enabled.
|
||||
* Note that E2H is always set when VHE is enabled.
|
||||
*/
|
||||
- mrs x0, id_aa64mmfr1_el1
|
||||
- tst x0, #0xf00
|
||||
- b.eq 1f
|
||||
- orr x1, x1, #(1 << 27)
|
||||
- msr hcr_el2, x1
|
||||
+ mrs x0, hcr_el2
|
||||
+ orr x0, x0, #(1 << HCR_EL2_TGE_SHIFT)
|
||||
+ msr hcr_el2, x0
|
||||
isb
|
||||
|
||||
/**
|
||||
@@ -905,6 +909,14 @@ enable_vhe_tge:
|
||||
ldr x0, [x0]
|
||||
msr ttbr0_el2, x0
|
||||
isb
|
||||
+
|
||||
+ /**
|
||||
+ * Enable alignment check while Hypervisor runs.
|
||||
+ */
|
||||
+ mrs x0, sctlr_el2
|
||||
+ orr x0, x0, #(1 << SCTLR_EL2_A_SHIFT)
|
||||
+ msr sctlr_el2, x0
|
||||
+ isb
|
||||
1:
|
||||
ret
|
||||
#endif
|
||||
diff --git a/src/arch/aarch64/hypervisor/feature_id.c b/src/arch/aarch64/hypervisor/feature_id.c
|
||||
index ed3bf8f1..57f32627 100644
|
||||
--- a/src/arch/aarch64/hypervisor/feature_id.c
|
||||
+++ b/src/arch/aarch64/hypervisor/feature_id.c
|
||||
@@ -175,7 +175,7 @@ void feature_set_traps(struct vm *vm, struct arch_regs *regs)
|
||||
~(ID_AA64MMFR1_EL1_VH_MASK << ID_AA64MMFR1_EL1_VH_SHIFT);
|
||||
|
||||
if (features & HF_FEATURE_RAS) {
|
||||
- regs->hcr_el2 |= HCR_EL2_TERR;
|
||||
+ regs->hyp_state.hcr_el2 |= HCR_EL2_TERR;
|
||||
vm->arch.tid3_masks.id_aa64mmfr1_el1 &=
|
||||
~ID_AA64MMFR1_EL1_SPEC_SEI;
|
||||
vm->arch.tid3_masks.id_aa64pfr0_el1 &= ~ID_AA64PFR0_EL1_RAS;
|
||||
@@ -221,14 +221,14 @@ void feature_set_traps(struct vm *vm, struct arch_regs *regs)
|
||||
}
|
||||
|
||||
if (features & HF_FEATURE_LOR) {
|
||||
- regs->hcr_el2 |= HCR_EL2_TLOR;
|
||||
+ regs->hyp_state.hcr_el2 |= HCR_EL2_TLOR;
|
||||
|
||||
vm->arch.tid3_masks.id_aa64mmfr1_el1 &= ~ID_AA64MMFR1_EL1_LO;
|
||||
}
|
||||
|
||||
if (features & HF_FEATURE_PAUTH) {
|
||||
/* APK and API bits *enable* trapping when cleared. */
|
||||
- regs->hcr_el2 &= ~(HCR_EL2_APK | HCR_EL2_API);
|
||||
+ regs->hyp_state.hcr_el2 &= ~(HCR_EL2_APK | HCR_EL2_API);
|
||||
|
||||
vm->arch.tid3_masks.id_aa64isar1_el1 &= ~ID_AA64ISAR1_EL1_GPI;
|
||||
vm->arch.tid3_masks.id_aa64isar1_el1 &= ~ID_AA64ISAR1_EL1_GPA;
|
||||
diff --git a/src/arch/aarch64/hypervisor/handler.c b/src/arch/aarch64/hypervisor/handler.c
|
||||
index cd5146bd..8a3d6289 100644
|
||||
--- a/src/arch/aarch64/hypervisor/handler.c
|
||||
+++ b/src/arch/aarch64/hypervisor/handler.c
|
||||
@@ -272,9 +272,9 @@ noreturn void sync_current_exception_noreturn(uintreg_t elr, uintreg_t spsr)
|
||||
static void set_virtual_irq(struct arch_regs *r, bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
- r->hcr_el2 |= HCR_EL2_VI;
|
||||
+ r->hyp_state.hcr_el2 |= HCR_EL2_VI;
|
||||
} else {
|
||||
- r->hcr_el2 &= ~HCR_EL2_VI;
|
||||
+ r->hyp_state.hcr_el2 &= ~HCR_EL2_VI;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,14 +283,15 @@ static void set_virtual_irq(struct arch_regs *r, bool enable)
|
||||
*/
|
||||
static void set_virtual_irq_current(bool enable)
|
||||
{
|
||||
- uintreg_t hcr_el2 = current()->regs.hcr_el2;
|
||||
+ struct vcpu *vcpu = current();
|
||||
+ uintreg_t hcr_el2 = vcpu->regs.hyp_state.hcr_el2;
|
||||
|
||||
if (enable) {
|
||||
hcr_el2 |= HCR_EL2_VI;
|
||||
} else {
|
||||
hcr_el2 &= ~HCR_EL2_VI;
|
||||
}
|
||||
- current()->regs.hcr_el2 = hcr_el2;
|
||||
+ vcpu->regs.hyp_state.hcr_el2 = hcr_el2;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -300,9 +301,9 @@ static void set_virtual_irq_current(bool enable)
|
||||
static void set_virtual_fiq(struct arch_regs *r, bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
- r->hcr_el2 |= HCR_EL2_VF;
|
||||
+ r->hyp_state.hcr_el2 |= HCR_EL2_VF;
|
||||
} else {
|
||||
- r->hcr_el2 &= ~HCR_EL2_VF;
|
||||
+ r->hyp_state.hcr_el2 &= ~HCR_EL2_VF;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,14 +312,15 @@ static void set_virtual_fiq(struct arch_regs *r, bool enable)
|
||||
*/
|
||||
static void set_virtual_fiq_current(bool enable)
|
||||
{
|
||||
- uintreg_t hcr_el2 = current()->regs.hcr_el2;
|
||||
+ struct vcpu *vcpu = current();
|
||||
+ uintreg_t hcr_el2 = vcpu->regs.hyp_state.hcr_el2;
|
||||
|
||||
if (enable) {
|
||||
hcr_el2 |= HCR_EL2_VF;
|
||||
} else {
|
||||
hcr_el2 &= ~HCR_EL2_VF;
|
||||
}
|
||||
- current()->regs.hcr_el2 = hcr_el2;
|
||||
+ vcpu->regs.hyp_state.hcr_el2 = hcr_el2;
|
||||
}
|
||||
|
||||
#if SECURE_WORLD == 1
|
||||
diff --git a/src/arch/aarch64/inc/hf/arch/types.h b/src/arch/aarch64/inc/hf/arch/types.h
|
||||
index 6379d73e..6b8b24f1 100644
|
||||
--- a/src/arch/aarch64/inc/hf/arch/types.h
|
||||
+++ b/src/arch/aarch64/inc/hf/arch/types.h
|
||||
@@ -79,8 +79,13 @@ struct arch_regs {
|
||||
uintreg_t r[NUM_GP_REGS];
|
||||
uintreg_t pc;
|
||||
uintreg_t spsr;
|
||||
- uintreg_t hcr_el2;
|
||||
- uintreg_t ttbr0_el2;
|
||||
+
|
||||
+ /* Hypervisor configuration while a vCPU runs. */
|
||||
+ struct {
|
||||
+ uintreg_t hcr_el2;
|
||||
+ uintreg_t ttbr0_el2;
|
||||
+ uintreg_t sctlr_el2;
|
||||
+ } hyp_state;
|
||||
|
||||
/*
|
||||
* System registers.
|
||||
diff --git a/src/arch/aarch64/mm.c b/src/arch/aarch64/mm.c
|
||||
index 8ee65ca0..487ae353 100644
|
||||
--- a/src/arch/aarch64/mm.c
|
||||
+++ b/src/arch/aarch64/mm.c
|
||||
@@ -886,7 +886,7 @@ bool arch_mm_init(paddr_t table)
|
||||
#endif
|
||||
(0xff << (8 * STAGE1_NORMALINDX)),
|
||||
|
||||
- .sctlr_el2 = get_sctlr_el2_value(),
|
||||
+ .sctlr_el2 = get_sctlr_el2_value(false),
|
||||
.vstcr_el2 = (1U << 31) | /* RES1. */
|
||||
(0 << 30) | /* SA. */
|
||||
(0 << 29) | /* SW. */
|
||||
diff --git a/src/arch/aarch64/sysregs.c b/src/arch/aarch64/sysregs.c
|
||||
index e8c154b1..087ba4ed 100644
|
||||
--- a/src/arch/aarch64/sysregs.c
|
||||
+++ b/src/arch/aarch64/sysregs.c
|
||||
@@ -159,7 +159,7 @@ uintreg_t get_cptr_el2_value(void)
|
||||
/**
|
||||
* Returns the value for SCTLR_EL2 for the CPU.
|
||||
*/
|
||||
-uintreg_t get_sctlr_el2_value(void)
|
||||
+uintreg_t get_sctlr_el2_value(bool is_el0_partition)
|
||||
{
|
||||
uintreg_t sctlr_el2_value = 0;
|
||||
|
||||
@@ -173,7 +173,14 @@ uintreg_t get_sctlr_el2_value(void)
|
||||
|
||||
/* MMU-related bits. */
|
||||
sctlr_el2_value |= SCTLR_EL2_M;
|
||||
- sctlr_el2_value |= SCTLR_EL2_A;
|
||||
+
|
||||
+ /*
|
||||
+ * Alignment check enabled, but in the case of an EL0 partition
|
||||
+ * with VHE enabled.
|
||||
+ */
|
||||
+ if (!(has_vhe_support() && is_el0_partition)) {
|
||||
+ sctlr_el2_value |= SCTLR_EL2_A;
|
||||
+ }
|
||||
sctlr_el2_value |= SCTLR_EL2_C;
|
||||
sctlr_el2_value |= SCTLR_EL2_SA;
|
||||
sctlr_el2_value |= SCTLR_EL2_I;
|
||||
diff --git a/src/arch/aarch64/sysregs.h b/src/arch/aarch64/sysregs.h
|
||||
index babd2375..6fdab58e 100644
|
||||
--- a/src/arch/aarch64/sysregs.h
|
||||
+++ b/src/arch/aarch64/sysregs.h
|
||||
@@ -668,7 +668,7 @@ uintreg_t get_mdcr_el2_value(void);
|
||||
|
||||
uintreg_t get_cptr_el2_value(void);
|
||||
|
||||
-uintreg_t get_sctlr_el2_value(void);
|
||||
+uintreg_t get_sctlr_el2_value(bool is_el0_partition);
|
||||
|
||||
/**
|
||||
* Branch Target Identification mechanism support in AArch64 state.
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
From 4b59905d2fec01cc17038b1c167b4e57e7835adf Mon Sep 17 00:00:00 2001
|
||||
From: Davidson K <davidson.kumaresan@arm.com>
|
||||
Date: Thu, 7 Oct 2021 12:20:08 +0530
|
||||
Subject: [PATCH] feat(vhe): set STAGE1_NS while mapping memory from NWd to SWd
|
||||
|
||||
If the memory is shared by a VM executing in non secure world, attribute
|
||||
MM_MODE_NS had to be set while mapping that in a S-EL0 SP executing in
|
||||
secure world. It will not be needed for a S-EL1 SP since the NS bit is
|
||||
available only for the stage 1 translations and the stage 1 translations
|
||||
for a S-EL1 SP will be handled by a trusted OS running in S-EL1.
|
||||
|
||||
Signed-off-by: Davidson K <davidson.kumaresan@arm.com>
|
||||
Change-Id: I074e2d5a50a659bd3c097d797c4901f08d210b1b
|
||||
Upstream-Status: Pending [Not submitted to upstream yet]
|
||||
---
|
||||
src/ffa_memory.c | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
diff --git a/src/ffa_memory.c b/src/ffa_memory.c
|
||||
index 048cca9c..8910cc79 100644
|
||||
--- a/src/ffa_memory.c
|
||||
+++ b/src/ffa_memory.c
|
||||
@@ -2483,6 +2483,18 @@ struct ffa_value ffa_memory_retrieve(struct vm_locked to_locked,
|
||||
|
||||
memory_to_attributes = ffa_memory_permissions_to_mode(
|
||||
permissions, share_state->sender_orig_mode);
|
||||
+
|
||||
+ if (to_locked.vm->el0_partition) {
|
||||
+ /*
|
||||
+ * Get extra mapping attributes for the given VM ID.
|
||||
+ * If the memory is shared by a VM executing in non secure
|
||||
+ * world, attribute MM_MODE_NS had to be set while mapping
|
||||
+ * that in a SP executing in secure world.
|
||||
+ */
|
||||
+ memory_to_attributes |= arch_mm_extra_attributes_from_vm(
|
||||
+ retrieve_request->sender);
|
||||
+ }
|
||||
+
|
||||
ret = ffa_retrieve_check_update(
|
||||
to_locked, memory_region->sender, share_state->fragments,
|
||||
share_state->fragment_constituent_counts,
|
||||
@@ -0,0 +1,25 @@
|
||||
# TC specific configuration
|
||||
|
||||
COMPATIBLE_MACHINE = "(tc?)"
|
||||
HAFNIUM_PLATFORM = "secure_tc"
|
||||
|
||||
# Intermediate SHA with 2.7 baseline version
|
||||
SRCREV = "dd0561820946fe23bcd57cc129140437f72102a5"
|
||||
PV = "2.7+git${SRCPV}"
|
||||
|
||||
FILESEXTRAPATHS:prepend:tc := "${THISDIR}/files/tc:"
|
||||
|
||||
SRC_URI:remove = "file://0003-Fix-build-with-clang-15.patch"
|
||||
|
||||
SRC_URI:append = " \
|
||||
file://0001-feat-emulate-cntp-timer-register-accesses-using-cnth.patch \
|
||||
file://0002-feat-emulate-interrupt-controller-register-access.patch \
|
||||
file://0003-feat-disable-alignment-check-for-EL0-partitions.patch \
|
||||
file://0004-feat-vhe-set-STAGE1_NS-while-mapping-memory-from-NWd.patch \
|
||||
file://0001-tc-increase-heap-pages.patch;patchdir=project/reference \
|
||||
file://0002-feat-vhe-enable-vhe-and-disable-branch-protection-fo.patch;patchdir=project/reference \
|
||||
"
|
||||
|
||||
do_compile() {
|
||||
PATH="${S}/prebuilts/linux-x64/clang/bin:$PATH" oe_runmake -C ${S}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
# Machine specific configurations
|
||||
|
||||
MACHINE_HAFNIUM_REQUIRE ?= ""
|
||||
MACHINE_HAFNIUM_REQUIRE:tc = "hafnium-tc.inc"
|
||||
|
||||
require ${MACHINE_HAFNIUM_REQUIRE}
|
||||
Reference in New Issue
Block a user