linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/13] KVM: arm64: Fixed features for protected VMs
@ 2021-06-15 13:39 Fuad Tabba
  2021-06-15 13:39 ` [PATCH v2 01/13] KVM: arm64: Remove trailing whitespace in comments Fuad Tabba
                   ` (12 more replies)
  0 siblings, 13 replies; 32+ messages in thread
From: Fuad Tabba @ 2021-06-15 13:39 UTC (permalink / raw)
  To: kvmarm
  Cc: maz, will, james.morse, alexandru.elisei, suzuki.poulose,
	mark.rutland, christoffer.dall, pbonzini, drjones, qperret, kvm,
	linux-arm-kernel, kernel-team, tabba

Hi,

Changes since v1 [0]:
- Restrict protected VM features based on an allowed features rather than
  rejected ones (Drew)
- Add more background describing protected KVM to the cover letter (Alex)
- Rebase on the latest kvmarm/next

This patch series adds support for restricting CPU features for protected VMs
in KVM (pKVM) [1].

Various feature configurations are allowed in KVM/arm64. Supporting all
these features in pKVM is difficult, as it either involves moving much of
the handling code to EL2, which adds bloat and results in a less verifiable
trusted code base. Or it involves leaving the code handling at EL1, which
risks having an untrusted host kernel feeding wrong information to the EL2
and to the protected guests.

This series attempts to mitigate this by reducing the configuration space,
providing a reduced amount of feature support at EL2 with the least amount of
compromise of protected guests' capabilities.

This is done by restricting CPU features exposed to protected guests through
feature registers. These restrictions are enforced by trapping register
accesses as well as instructions associated with these features, and injecting
an undefined exception into the guest if it attempts to use a restricted
feature.

The features being restricted (only for protected VMs in protected mode) are
the following:
- Debug, Trace, and DoubleLock
- Performance Monitoring (PMU)
- Statistical Profiling (SPE)
- Scalable Vector Extension (SVE)
- Memory Partitioning and Monitoring (MPAM)
- Activity Monitoring (AMU)
- Memory Tagging (MTE)
- Limited Ordering Regions (LOR)
- AArch32 State
- Generic Interrupt Controller (GIC) (depending on rVIC support)
- Nested Virtualization (NV)
- Reliability, Availability, and Serviceability (RAS) above V1
- Implementation-defined Features

Remaining features currently supported by KVM are allowed. If new hardware
features become supported by KVM, they would need to be explicitly allowed
for protected VMs.

This series is based on kvmarm/next and Will's patches for an Initial pKVM user
ABI [2]. You can find the applied series here [3].

Cheers,
/fuad

[0] https://lore.kernel.org/kvmarm/20210608141141.997398-1-tabba@google.com/

[1] Once complete, protected KVM adds the ability to create protected VMs.
These protected VMs are protected from the host Linux kernel (and from other
VMs), where the host does not have access to guest memory,even if compromised.
Normal (nVHE) guests can still be created and run in parallel with protected
VMs. Their functionality should not be affected.

For protected VMs, the host should not even have access to a protected guest's
state or anything that would enable it to manipulate it (e.g., vcpu register
context and el2 system registers); only hyp would have that access. If the host
could access that state, then it might be able to get around the protection
provided.  Therefore, anything that is sensitive and that would require such
access needs to happen at hyp, hence the code in nvhe running only at hyp.

For more details about pKVM, please refer to Will's talk at KVM Forum 2020:
https://mirrors.edge.kernel.org/pub/linux/kernel/people/will/slides/kvmforum-2020-edited.pdf
https://www.youtube.com/watch?v=edqJSzsDRxk

[2] https://lore.kernel.org/kvmarm/20210603183347.1695-1-will@kernel.org/

[3] https://android-kvm.googlesource.com/linux/+/refs/heads/tabba/el2_fixed_feature_v2

Fuad Tabba (13):
  KVM: arm64: Remove trailing whitespace in comments
  KVM: arm64: MDCR_EL2 is a 64-bit register
  KVM: arm64: Fix names of config register fields
  KVM: arm64: Refactor sys_regs.h,c for nVHE reuse
  KVM: arm64: Restore mdcr_el2 from vcpu
  KVM: arm64: Add feature register flag definitions
  KVM: arm64: Add config register bit definitions
  KVM: arm64: Guest exit handlers for nVHE hyp
  KVM: arm64: Add trap handlers for protected VMs
  KVM: arm64: Move sanitized copies of CPU features
  KVM: arm64: Trap access to pVM restricted features
  KVM: arm64: Handle protected guests at 32 bits
  KVM: arm64: Check vcpu features at pVM creation

 arch/arm64/include/asm/kvm_arm.h        |  53 ++-
 arch/arm64/include/asm/kvm_asm.h        |   2 +-
 arch/arm64/include/asm/kvm_host.h       |   2 +-
 arch/arm64/include/asm/kvm_hyp.h        |   3 +
 arch/arm64/include/asm/sysreg.h         |   9 +
 arch/arm64/kvm/arm.c                    |   3 +
 arch/arm64/kvm/debug.c                  |   5 +-
 arch/arm64/kvm/hyp/include/hyp/switch.h |  42 +++
 arch/arm64/kvm/hyp/nvhe/Makefile        |   2 +-
 arch/arm64/kvm/hyp/nvhe/debug-sr.c      |   2 +-
 arch/arm64/kvm/hyp/nvhe/mem_protect.c   |   6 -
 arch/arm64/kvm/hyp/nvhe/switch.c        | 125 ++++++-
 arch/arm64/kvm/hyp/nvhe/sys_regs.c      | 477 ++++++++++++++++++++++++
 arch/arm64/kvm/hyp/vhe/debug-sr.c       |   2 +-
 arch/arm64/kvm/pkvm.c                   |  43 +++
 arch/arm64/kvm/sys_regs.c               |  34 +-
 arch/arm64/kvm/sys_regs.h               |  35 ++
 17 files changed, 784 insertions(+), 61 deletions(-)
 create mode 100644 arch/arm64/kvm/hyp/nvhe/sys_regs.c


base-commit: bc63d9369b320fd3c85ee13a029af9dc0ddac0ea
-- 
2.32.0.272.g935e593368-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH v2 01/13] KVM: arm64: Remove trailing whitespace in comments
  2021-06-15 13:39 [PATCH v2 00/13] KVM: arm64: Fixed features for protected VMs Fuad Tabba
@ 2021-06-15 13:39 ` Fuad Tabba
  2021-07-01 12:55   ` Will Deacon
  2021-06-15 13:39 ` [PATCH v2 02/13] KVM: arm64: MDCR_EL2 is a 64-bit register Fuad Tabba
                   ` (11 subsequent siblings)
  12 siblings, 1 reply; 32+ messages in thread
From: Fuad Tabba @ 2021-06-15 13:39 UTC (permalink / raw)
  To: kvmarm
  Cc: maz, will, james.morse, alexandru.elisei, suzuki.poulose,
	mark.rutland, christoffer.dall, pbonzini, drjones, qperret, kvm,
	linux-arm-kernel, kernel-team, tabba

Editing this file later, and my editor always cleans up trailing
whitespace. Removing it earler for clearer future patches.

No functional change intended.

Signed-off-by: Fuad Tabba <tabba@google.com>
---
 arch/arm64/kvm/sys_regs.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 1a7968ad078c..15c247fc9f0c 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -318,14 +318,14 @@ static bool trap_dbgauthstatus_el1(struct kvm_vcpu *vcpu,
 /*
  * We want to avoid world-switching all the DBG registers all the
  * time:
- * 
+ *
  * - If we've touched any debug register, it is likely that we're
  *   going to touch more of them. It then makes sense to disable the
  *   traps and start doing the save/restore dance
  * - If debug is active (DBG_MDSCR_KDE or DBG_MDSCR_MDE set), it is
  *   then mandatory to save/restore the registers, as the guest
  *   depends on them.
- * 
+ *
  * For this, we use a DIRTY bit, indicating the guest has modified the
  * debug registers, used as follow:
  *
-- 
2.32.0.272.g935e593368-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH v2 02/13] KVM: arm64: MDCR_EL2 is a 64-bit register
  2021-06-15 13:39 [PATCH v2 00/13] KVM: arm64: Fixed features for protected VMs Fuad Tabba
  2021-06-15 13:39 ` [PATCH v2 01/13] KVM: arm64: Remove trailing whitespace in comments Fuad Tabba
@ 2021-06-15 13:39 ` Fuad Tabba
  2021-07-01 12:53   ` Will Deacon
  2021-06-15 13:39 ` [PATCH v2 03/13] KVM: arm64: Fix names of config register fields Fuad Tabba
                   ` (10 subsequent siblings)
  12 siblings, 1 reply; 32+ messages in thread
From: Fuad Tabba @ 2021-06-15 13:39 UTC (permalink / raw)
  To: kvmarm
  Cc: maz, will, james.morse, alexandru.elisei, suzuki.poulose,
	mark.rutland, christoffer.dall, pbonzini, drjones, qperret, kvm,
	linux-arm-kernel, kernel-team, tabba

Fix the places in KVM that treat MDCR_EL2 as a 32-bit register.
More recent features (e.g., FEAT_SPEv1p2) use bits above 31.

No functional change intended.

Signed-off-by: Fuad Tabba <tabba@google.com>
---
 arch/arm64/include/asm/kvm_arm.h   | 20 ++++++++++----------
 arch/arm64/include/asm/kvm_asm.h   |  2 +-
 arch/arm64/include/asm/kvm_host.h  |  2 +-
 arch/arm64/kvm/debug.c             |  5 +++--
 arch/arm64/kvm/hyp/nvhe/debug-sr.c |  2 +-
 arch/arm64/kvm/hyp/vhe/debug-sr.c  |  2 +-
 6 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 692c9049befa..25d8a61888e4 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -280,18 +280,18 @@
 /* Hyp Debug Configuration Register bits */
 #define MDCR_EL2_E2TB_MASK	(UL(0x3))
 #define MDCR_EL2_E2TB_SHIFT	(UL(24))
-#define MDCR_EL2_TTRF		(1 << 19)
-#define MDCR_EL2_TPMS		(1 << 14)
+#define MDCR_EL2_TTRF		(UL(1) << 19)
+#define MDCR_EL2_TPMS		(UL(1) << 14)
 #define MDCR_EL2_E2PB_MASK	(UL(0x3))
 #define MDCR_EL2_E2PB_SHIFT	(UL(12))
-#define MDCR_EL2_TDRA		(1 << 11)
-#define MDCR_EL2_TDOSA		(1 << 10)
-#define MDCR_EL2_TDA		(1 << 9)
-#define MDCR_EL2_TDE		(1 << 8)
-#define MDCR_EL2_HPME		(1 << 7)
-#define MDCR_EL2_TPM		(1 << 6)
-#define MDCR_EL2_TPMCR		(1 << 5)
-#define MDCR_EL2_HPMN_MASK	(0x1F)
+#define MDCR_EL2_TDRA		(UL(1) << 11)
+#define MDCR_EL2_TDOSA		(UL(1) << 10)
+#define MDCR_EL2_TDA		(UL(1) << 9)
+#define MDCR_EL2_TDE		(UL(1) << 8)
+#define MDCR_EL2_HPME		(UL(1) << 7)
+#define MDCR_EL2_TPM		(UL(1) << 6)
+#define MDCR_EL2_TPMCR		(UL(1) << 5)
+#define MDCR_EL2_HPMN_MASK	(UL(0x1F))
 
 /* For compatibility with fault code shared with 32-bit */
 #define FSC_FAULT	ESR_ELx_FSC_FAULT
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 5e9b33cbac51..d88a5550552c 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -209,7 +209,7 @@ extern u64 __vgic_v3_read_vmcr(void);
 extern void __vgic_v3_write_vmcr(u32 vmcr);
 extern void __vgic_v3_init_lrs(void);
 
-extern u32 __kvm_get_mdcr_el2(void);
+extern u64 __kvm_get_mdcr_el2(void);
 
 #define __KVM_EXTABLE(from, to)						\
 	"	.pushsection	__kvm_ex_table, \"a\"\n"		\
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 5645af2a1431..45fdd0b7063f 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -286,7 +286,7 @@ struct kvm_vcpu_arch {
 
 	/* HYP configuration */
 	u64 hcr_el2;
-	u32 mdcr_el2;
+	u64 mdcr_el2;
 
 	/* Exception Information */
 	struct kvm_vcpu_fault_info fault;
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index d5e79d7ee6e9..f7385bfbc9e4 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -21,7 +21,7 @@
 				DBG_MDSCR_KDE | \
 				DBG_MDSCR_MDE)
 
-static DEFINE_PER_CPU(u32, mdcr_el2);
+static DEFINE_PER_CPU(u64, mdcr_el2);
 
 /**
  * save/restore_guest_debug_regs
@@ -154,7 +154,8 @@ void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu)
 
 void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
 {
-	unsigned long mdscr, orig_mdcr_el2 = vcpu->arch.mdcr_el2;
+	unsigned long mdscr;
+	u64 orig_mdcr_el2 = vcpu->arch.mdcr_el2;
 
 	trace_kvm_arm_setup_debug(vcpu, vcpu->guest_debug);
 
diff --git a/arch/arm64/kvm/hyp/nvhe/debug-sr.c b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
index 7d3f25868cae..df361d839902 100644
--- a/arch/arm64/kvm/hyp/nvhe/debug-sr.c
+++ b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
@@ -109,7 +109,7 @@ void __debug_switch_to_host(struct kvm_vcpu *vcpu)
 	__debug_switch_to_host_common(vcpu);
 }
 
-u32 __kvm_get_mdcr_el2(void)
+u64 __kvm_get_mdcr_el2(void)
 {
 	return read_sysreg(mdcr_el2);
 }
diff --git a/arch/arm64/kvm/hyp/vhe/debug-sr.c b/arch/arm64/kvm/hyp/vhe/debug-sr.c
index f1e2e5a00933..289689b2682d 100644
--- a/arch/arm64/kvm/hyp/vhe/debug-sr.c
+++ b/arch/arm64/kvm/hyp/vhe/debug-sr.c
@@ -20,7 +20,7 @@ void __debug_switch_to_host(struct kvm_vcpu *vcpu)
 	__debug_switch_to_host_common(vcpu);
 }
 
-u32 __kvm_get_mdcr_el2(void)
+u64 __kvm_get_mdcr_el2(void)
 {
 	return read_sysreg(mdcr_el2);
 }
-- 
2.32.0.272.g935e593368-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH v2 03/13] KVM: arm64: Fix names of config register fields
  2021-06-15 13:39 [PATCH v2 00/13] KVM: arm64: Fixed features for protected VMs Fuad Tabba
  2021-06-15 13:39 ` [PATCH v2 01/13] KVM: arm64: Remove trailing whitespace in comments Fuad Tabba
  2021-06-15 13:39 ` [PATCH v2 02/13] KVM: arm64: MDCR_EL2 is a 64-bit register Fuad Tabba
@ 2021-06-15 13:39 ` Fuad Tabba
  2021-07-01 13:01   ` Will Deacon
  2021-06-15 13:39 ` [PATCH v2 04/13] KVM: arm64: Refactor sys_regs.h,c for nVHE reuse Fuad Tabba
                   ` (9 subsequent siblings)
  12 siblings, 1 reply; 32+ messages in thread
From: Fuad Tabba @ 2021-06-15 13:39 UTC (permalink / raw)
  To: kvmarm
  Cc: maz, will, james.morse, alexandru.elisei, suzuki.poulose,
	mark.rutland, christoffer.dall, pbonzini, drjones, qperret, kvm,
	linux-arm-kernel, kernel-team, tabba

Change the names of hcr_el2 register fields to match the Arm
Architecture Reference Manual. Easier for cross-referencing and
for grepping.

Also, change the name of CPTR_EL2_RES1 to CPTR_NVHE_EL2_RES1,
because res1 bits are different for VHE.

No functional change intended.

Signed-off-by: Fuad Tabba <tabba@google.com>
---
 arch/arm64/include/asm/kvm_arm.h | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 25d8a61888e4..bee1ba6773fb 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -31,9 +31,9 @@
 #define HCR_TVM		(UL(1) << 26)
 #define HCR_TTLB	(UL(1) << 25)
 #define HCR_TPU		(UL(1) << 24)
-#define HCR_TPC		(UL(1) << 23)
+#define HCR_TPCP	(UL(1) << 23)
 #define HCR_TSW		(UL(1) << 22)
-#define HCR_TAC		(UL(1) << 21)
+#define HCR_TACR	(UL(1) << 21)
 #define HCR_TIDCP	(UL(1) << 20)
 #define HCR_TSC		(UL(1) << 19)
 #define HCR_TID3	(UL(1) << 18)
@@ -60,7 +60,7 @@
  * The bits we set in HCR:
  * TLOR:	Trap LORegion register accesses
  * RW:		64bit by default, can be overridden for 32bit VMs
- * TAC:		Trap ACTLR
+ * TACR:	Trap ACTLR
  * TSC:		Trap SMC
  * TSW:		Trap cache operations by set/way
  * TWE:		Trap WFE
@@ -75,7 +75,7 @@
  * PTW:		Take a stage2 fault if a stage1 walk steps in device memory
  */
 #define HCR_GUEST_FLAGS (HCR_TSC | HCR_TSW | HCR_TWE | HCR_TWI | HCR_VM | \
-			 HCR_BSU_IS | HCR_FB | HCR_TAC | \
+			 HCR_BSU_IS | HCR_FB | HCR_TACR | \
 			 HCR_AMO | HCR_SWIO | HCR_TIDCP | HCR_RW | HCR_TLOR | \
 			 HCR_FMO | HCR_IMO | HCR_PTW )
 #define HCR_VIRT_EXCP_MASK (HCR_VSE | HCR_VI | HCR_VF)
@@ -274,8 +274,8 @@
 #define CPTR_EL2_TTA	(1 << 20)
 #define CPTR_EL2_TFP	(1 << CPTR_EL2_TFP_SHIFT)
 #define CPTR_EL2_TZ	(1 << 8)
-#define CPTR_EL2_RES1	0x000032ff /* known RES1 bits in CPTR_EL2 */
-#define CPTR_EL2_DEFAULT	CPTR_EL2_RES1
+#define CPTR_NVHE_EL2_RES1	0x000032ff /* known RES1 bits in CPTR_EL2 (nVHE) */
+#define CPTR_EL2_DEFAULT	CPTR_NVHE_EL2_RES1
 
 /* Hyp Debug Configuration Register bits */
 #define MDCR_EL2_E2TB_MASK	(UL(0x3))
-- 
2.32.0.272.g935e593368-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH v2 04/13] KVM: arm64: Refactor sys_regs.h,c for nVHE reuse
  2021-06-15 13:39 [PATCH v2 00/13] KVM: arm64: Fixed features for protected VMs Fuad Tabba
                   ` (2 preceding siblings ...)
  2021-06-15 13:39 ` [PATCH v2 03/13] KVM: arm64: Fix names of config register fields Fuad Tabba
@ 2021-06-15 13:39 ` Fuad Tabba
  2021-07-01 13:09   ` [PATCH v2 04/13] KVM: arm64: Refactor sys_regs.h, c " Will Deacon
  2021-06-15 13:39 ` [PATCH v2 05/13] KVM: arm64: Restore mdcr_el2 from vcpu Fuad Tabba
                   ` (8 subsequent siblings)
  12 siblings, 1 reply; 32+ messages in thread
From: Fuad Tabba @ 2021-06-15 13:39 UTC (permalink / raw)
  To: kvmarm
  Cc: maz, will, james.morse, alexandru.elisei, suzuki.poulose,
	mark.rutland, christoffer.dall, pbonzini, drjones, qperret, kvm,
	linux-arm-kernel, kernel-team, tabba

Refactor sys_regs.h and sys_regs.c to make it easier to reuse
common code. It will be used in nVHE in a later patch.

No functional change intended.

Signed-off-by: Fuad Tabba <tabba@google.com>
---
 arch/arm64/kvm/sys_regs.c | 30 +-----------------------------
 arch/arm64/kvm/sys_regs.h | 35 +++++++++++++++++++++++++++++++++++
 2 files changed, 36 insertions(+), 29 deletions(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 15c247fc9f0c..826a04f27194 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -44,10 +44,6 @@
  * 64bit interface.
  */
 
-#define reg_to_encoding(x)						\
-	sys_reg((u32)(x)->Op0, (u32)(x)->Op1,				\
-		(u32)(x)->CRn, (u32)(x)->CRm, (u32)(x)->Op2)
-
 static bool read_from_write_only(struct kvm_vcpu *vcpu,
 				 struct sys_reg_params *params,
 				 const struct sys_reg_desc *r)
@@ -1026,8 +1022,6 @@ static bool access_arch_timer(struct kvm_vcpu *vcpu,
 	return true;
 }
 
-#define FEATURE(x)	(GENMASK_ULL(x##_SHIFT + 3, x##_SHIFT))
-
 /* Read a sanitised cpufeature ID register by sys_reg_desc */
 static u64 read_id_reg(const struct kvm_vcpu *vcpu,
 		struct sys_reg_desc const *r, bool raz)
@@ -2082,23 +2076,6 @@ static int check_sysreg_table(const struct sys_reg_desc *table, unsigned int n,
 	return 0;
 }
 
-static int match_sys_reg(const void *key, const void *elt)
-{
-	const unsigned long pval = (unsigned long)key;
-	const struct sys_reg_desc *r = elt;
-
-	return pval - reg_to_encoding(r);
-}
-
-static const struct sys_reg_desc *find_reg(const struct sys_reg_params *params,
-					 const struct sys_reg_desc table[],
-					 unsigned int num)
-{
-	unsigned long pval = reg_to_encoding(params);
-
-	return bsearch((void *)pval, table, num, sizeof(table[0]), match_sys_reg);
-}
-
 int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu)
 {
 	kvm_inject_undefined(vcpu);
@@ -2341,13 +2318,8 @@ int kvm_handle_sys_reg(struct kvm_vcpu *vcpu)
 
 	trace_kvm_handle_sys_reg(esr);
 
-	params.Op0 = (esr >> 20) & 3;
-	params.Op1 = (esr >> 14) & 0x7;
-	params.CRn = (esr >> 10) & 0xf;
-	params.CRm = (esr >> 1) & 0xf;
-	params.Op2 = (esr >> 17) & 0x7;
+	params = esr_sys64_to_params(esr);
 	params.regval = vcpu_get_reg(vcpu, Rt);
-	params.is_write = !(esr & 1);
 
 	ret = emulate_sys_reg(vcpu, &params);
 
diff --git a/arch/arm64/kvm/sys_regs.h b/arch/arm64/kvm/sys_regs.h
index 9d0621417c2a..b8e2a4dd830f 100644
--- a/arch/arm64/kvm/sys_regs.h
+++ b/arch/arm64/kvm/sys_regs.h
@@ -11,6 +11,12 @@
 #ifndef __ARM64_KVM_SYS_REGS_LOCAL_H__
 #define __ARM64_KVM_SYS_REGS_LOCAL_H__
 
+#include <linux/bsearch.h>
+
+#define reg_to_encoding(x)						\
+	sys_reg((u32)(x)->Op0, (u32)(x)->Op1,				\
+		(u32)(x)->CRn, (u32)(x)->CRm, (u32)(x)->Op2)
+
 struct sys_reg_params {
 	u8	Op0;
 	u8	Op1;
@@ -21,6 +27,14 @@ struct sys_reg_params {
 	bool	is_write;
 };
 
+#define esr_sys64_to_params(esr)                                               \
+	((struct sys_reg_params){ .Op0 = ((esr) >> 20) & 3,                    \
+				  .Op1 = ((esr) >> 14) & 0x7,                  \
+				  .CRn = ((esr) >> 10) & 0xf,                  \
+				  .CRm = ((esr) >> 1) & 0xf,                   \
+				  .Op2 = ((esr) >> 17) & 0x7,                  \
+				  .is_write = !((esr)&1) })
+
 struct sys_reg_desc {
 	/* Sysreg string for debug */
 	const char *name;
@@ -152,6 +166,24 @@ static inline int cmp_sys_reg(const struct sys_reg_desc *i1,
 	return i1->Op2 - i2->Op2;
 }
 
+static inline int match_sys_reg(const void *key, const void *elt)
+{
+	const unsigned long pval = (unsigned long)key;
+	const struct sys_reg_desc *r = elt;
+
+	return pval - reg_to_encoding(r);
+}
+
+static inline const struct sys_reg_desc *
+find_reg(const struct sys_reg_params *params, const struct sys_reg_desc table[],
+	 unsigned int num)
+{
+	unsigned long pval = reg_to_encoding(params);
+
+	return __inline_bsearch((void *)pval, table, num, sizeof(table[0]),
+				match_sys_reg);
+}
+
 const struct sys_reg_desc *find_reg_by_id(u64 id,
 					  struct sys_reg_params *params,
 					  const struct sys_reg_desc table[],
@@ -170,4 +202,7 @@ const struct sys_reg_desc *find_reg_by_id(u64 id,
 	CRn(sys_reg_CRn(reg)), CRm(sys_reg_CRm(reg)),	\
 	Op2(sys_reg_Op2(reg))
 
+/* Extract the feature specified from the feature id register. */
+#define FEATURE(x)	(GENMASK_ULL(x##_SHIFT + 3, x##_SHIFT))
+
 #endif /* __ARM64_KVM_SYS_REGS_LOCAL_H__ */
-- 
2.32.0.272.g935e593368-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH v2 05/13] KVM: arm64: Restore mdcr_el2 from vcpu
  2021-06-15 13:39 [PATCH v2 00/13] KVM: arm64: Fixed features for protected VMs Fuad Tabba
                   ` (3 preceding siblings ...)
  2021-06-15 13:39 ` [PATCH v2 04/13] KVM: arm64: Refactor sys_regs.h,c for nVHE reuse Fuad Tabba
@ 2021-06-15 13:39 ` Fuad Tabba
  2021-07-01 13:17   ` Will Deacon
  2021-06-15 13:39 ` [PATCH v2 06/13] KVM: arm64: Add feature register flag definitions Fuad Tabba
                   ` (7 subsequent siblings)
  12 siblings, 1 reply; 32+ messages in thread
From: Fuad Tabba @ 2021-06-15 13:39 UTC (permalink / raw)
  To: kvmarm
  Cc: maz, will, james.morse, alexandru.elisei, suzuki.poulose,
	mark.rutland, christoffer.dall, pbonzini, drjones, qperret, kvm,
	linux-arm-kernel, kernel-team, tabba

On deactivating traps, restore the value of mdcr_el2 from the
vcpu context, rather than directly reading the hardware register.
Currently, the two values are the same, i.e., the hardware
register and the vcpu one. A future patch will be changing the
value of mdcr_el2 on activating traps, and this ensures that its
value will be restored.

No functional change intended.

Signed-off-by: Fuad Tabba <tabba@google.com>
---
 arch/arm64/kvm/hyp/nvhe/switch.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index f7af9688c1f7..430b5bae8761 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -73,7 +73,7 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu)
 
 	___deactivate_traps(vcpu);
 
-	mdcr_el2 = read_sysreg(mdcr_el2);
+	mdcr_el2 = vcpu->arch.mdcr_el2;
 
 	if (cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT)) {
 		u64 val;
-- 
2.32.0.272.g935e593368-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH v2 06/13] KVM: arm64: Add feature register flag definitions
  2021-06-15 13:39 [PATCH v2 00/13] KVM: arm64: Fixed features for protected VMs Fuad Tabba
                   ` (4 preceding siblings ...)
  2021-06-15 13:39 ` [PATCH v2 05/13] KVM: arm64: Restore mdcr_el2 from vcpu Fuad Tabba
@ 2021-06-15 13:39 ` Fuad Tabba
  2021-07-01 13:22   ` Will Deacon
  2021-06-15 13:39 ` [PATCH v2 07/13] KVM: arm64: Add config register bit definitions Fuad Tabba
                   ` (6 subsequent siblings)
  12 siblings, 1 reply; 32+ messages in thread
From: Fuad Tabba @ 2021-06-15 13:39 UTC (permalink / raw)
  To: kvmarm
  Cc: maz, will, james.morse, alexandru.elisei, suzuki.poulose,
	mark.rutland, christoffer.dall, pbonzini, drjones, qperret, kvm,
	linux-arm-kernel, kernel-team, tabba

Add feature register flag definitions to clarify which features
might be supported.

No functional change intended.

Signed-off-by: Fuad Tabba <tabba@google.com>
---
 arch/arm64/include/asm/sysreg.h | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 65d15700a168..42bcc5102d10 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -789,6 +789,10 @@
 #define ID_AA64PFR0_FP_SUPPORTED	0x0
 #define ID_AA64PFR0_ASIMD_NI		0xf
 #define ID_AA64PFR0_ASIMD_SUPPORTED	0x0
+#define ID_AA64PFR0_EL3_64BIT_ONLY	0x1
+#define ID_AA64PFR0_EL3_32BIT_64BIT	0x2
+#define ID_AA64PFR0_EL2_64BIT_ONLY	0x1
+#define ID_AA64PFR0_EL2_32BIT_64BIT	0x2
 #define ID_AA64PFR0_EL1_64BIT_ONLY	0x1
 #define ID_AA64PFR0_EL1_32BIT_64BIT	0x2
 #define ID_AA64PFR0_EL0_64BIT_ONLY	0x1
@@ -848,12 +852,16 @@
 #define ID_AA64MMFR0_ASID_SHIFT		4
 #define ID_AA64MMFR0_PARANGE_SHIFT	0
 
+#define ID_AA64MMFR0_ASID_8		0x0
+#define ID_AA64MMFR0_ASID_16		0x2
+
 #define ID_AA64MMFR0_TGRAN4_NI		0xf
 #define ID_AA64MMFR0_TGRAN4_SUPPORTED	0x0
 #define ID_AA64MMFR0_TGRAN64_NI		0xf
 #define ID_AA64MMFR0_TGRAN64_SUPPORTED	0x0
 #define ID_AA64MMFR0_TGRAN16_NI		0x0
 #define ID_AA64MMFR0_TGRAN16_SUPPORTED	0x1
+#define ID_AA64MMFR0_PARANGE_40		0x2
 #define ID_AA64MMFR0_PARANGE_48		0x5
 #define ID_AA64MMFR0_PARANGE_52		0x6
 
@@ -901,6 +909,7 @@
 #define ID_AA64MMFR2_CNP_SHIFT		0
 
 /* id_aa64dfr0 */
+#define ID_AA64DFR0_MTPMU_SHIFT		48
 #define ID_AA64DFR0_TRBE_SHIFT		44
 #define ID_AA64DFR0_TRACE_FILT_SHIFT	40
 #define ID_AA64DFR0_DOUBLELOCK_SHIFT	36
-- 
2.32.0.272.g935e593368-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH v2 07/13] KVM: arm64: Add config register bit definitions
  2021-06-15 13:39 [PATCH v2 00/13] KVM: arm64: Fixed features for protected VMs Fuad Tabba
                   ` (5 preceding siblings ...)
  2021-06-15 13:39 ` [PATCH v2 06/13] KVM: arm64: Add feature register flag definitions Fuad Tabba
@ 2021-06-15 13:39 ` Fuad Tabba
  2021-07-01 13:33   ` Will Deacon
  2021-06-15 13:39 ` [PATCH v2 08/13] KVM: arm64: Guest exit handlers for nVHE hyp Fuad Tabba
                   ` (5 subsequent siblings)
  12 siblings, 1 reply; 32+ messages in thread
From: Fuad Tabba @ 2021-06-15 13:39 UTC (permalink / raw)
  To: kvmarm
  Cc: maz, will, james.morse, alexandru.elisei, suzuki.poulose,
	mark.rutland, christoffer.dall, pbonzini, drjones, qperret, kvm,
	linux-arm-kernel, kernel-team, tabba

Add hardware configuration register bit definitions for HCR_EL2
and MDCR_EL2. Future patches toggle these hyp configuration
register bits to trap on certain accesses.

No functional change intended.

Signed-off-by: Fuad Tabba <tabba@google.com>
---
 arch/arm64/include/asm/kvm_arm.h | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index bee1ba6773fb..a78090071f1f 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -12,7 +12,11 @@
 #include <asm/types.h>
 
 /* Hyp Configuration Register (HCR) bits */
+#define HCR_TID5	(UL(1) << 58)
+#define HCR_DCT		(UL(1) << 57)
 #define HCR_ATA		(UL(1) << 56)
+#define HCR_AMVOFFEN	(UL(1) << 51)
+#define HCR_FIEN	(UL(1) << 47)
 #define HCR_FWB		(UL(1) << 46)
 #define HCR_API		(UL(1) << 41)
 #define HCR_APK		(UL(1) << 40)
@@ -55,6 +59,7 @@
 #define HCR_PTW		(UL(1) << 2)
 #define HCR_SWIO	(UL(1) << 1)
 #define HCR_VM		(UL(1) << 0)
+#define HCR_RES0	((UL(1) << 48) | (UL(1) << 39))
 
 /*
  * The bits we set in HCR:
@@ -276,11 +281,21 @@
 #define CPTR_EL2_TZ	(1 << 8)
 #define CPTR_NVHE_EL2_RES1	0x000032ff /* known RES1 bits in CPTR_EL2 (nVHE) */
 #define CPTR_EL2_DEFAULT	CPTR_NVHE_EL2_RES1
+#define CPTR_NVHE_EL2_RES0	(GENMASK_ULL(63, 32) |	\
+				 GENMASK_ULL(29, 21) |	\
+				 GENMASK_ULL(19, 14) |	\
+				 (UL(1) << 11))
 
 /* Hyp Debug Configuration Register bits */
 #define MDCR_EL2_E2TB_MASK	(UL(0x3))
 #define MDCR_EL2_E2TB_SHIFT	(UL(24))
+#define MDCR_EL2_HPMFZS		(UL(1) << 36)
+#define MDCR_EL2_HPMFZO		(UL(1) << 29)
+#define MDCR_EL2_MTPME		(UL(1) << 28)
+#define MDCR_EL2_TDCC		(UL(1) << 27)
+#define MDCR_EL2_HCCD		(UL(1) << 23)
 #define MDCR_EL2_TTRF		(UL(1) << 19)
+#define MDCR_EL2_HPMD		(UL(1) << 17)
 #define MDCR_EL2_TPMS		(UL(1) << 14)
 #define MDCR_EL2_E2PB_MASK	(UL(0x3))
 #define MDCR_EL2_E2PB_SHIFT	(UL(12))
@@ -292,6 +307,12 @@
 #define MDCR_EL2_TPM		(UL(1) << 6)
 #define MDCR_EL2_TPMCR		(UL(1) << 5)
 #define MDCR_EL2_HPMN_MASK	(UL(0x1F))
+#define MDCR_EL2_RES0		(GENMASK_ULL(63, 37) |	\
+				 GENMASK_ULL(35, 30) |	\
+				 GENMASK_ULL(25, 24) |	\
+				 GENMASK_ULL(22, 20) |	\
+				 (UL(1) << 18) |	\
+				 GENMASK_ULL(16, 15))
 
 /* For compatibility with fault code shared with 32-bit */
 #define FSC_FAULT	ESR_ELx_FSC_FAULT
-- 
2.32.0.272.g935e593368-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH v2 08/13] KVM: arm64: Guest exit handlers for nVHE hyp
  2021-06-15 13:39 [PATCH v2 00/13] KVM: arm64: Fixed features for protected VMs Fuad Tabba
                   ` (6 preceding siblings ...)
  2021-06-15 13:39 ` [PATCH v2 07/13] KVM: arm64: Add config register bit definitions Fuad Tabba
@ 2021-06-15 13:39 ` Fuad Tabba
  2021-07-01 13:48   ` Will Deacon
  2021-06-15 13:39 ` [PATCH v2 09/13] KVM: arm64: Add trap handlers for protected VMs Fuad Tabba
                   ` (4 subsequent siblings)
  12 siblings, 1 reply; 32+ messages in thread
From: Fuad Tabba @ 2021-06-15 13:39 UTC (permalink / raw)
  To: kvmarm
  Cc: maz, will, james.morse, alexandru.elisei, suzuki.poulose,
	mark.rutland, christoffer.dall, pbonzini, drjones, qperret, kvm,
	linux-arm-kernel, kernel-team, tabba

Add an array of pointers to handlers for various trap reasons in
nVHE code.

The current code selects how to fixup a guest on exit based on a
series of if/else statements. Future patches will also require
different handling for guest exists. Create an array of handlers
to consolidate them.

No functional change intended as the array isn't populated yet.

Signed-off-by: Fuad Tabba <tabba@google.com>
---
 arch/arm64/kvm/hyp/include/hyp/switch.h | 19 ++++++++++++++
 arch/arm64/kvm/hyp/nvhe/switch.c        | 35 +++++++++++++++++++++++++
 2 files changed, 54 insertions(+)

diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index e4a2f295a394..f5d3d1da0aec 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -405,6 +405,18 @@ static inline bool __hyp_handle_ptrauth(struct kvm_vcpu *vcpu)
 	return true;
 }
 
+typedef int (*exit_handle_fn)(struct kvm_vcpu *);
+
+exit_handle_fn kvm_get_nvhe_exit_handler(struct kvm_vcpu *vcpu);
+
+static exit_handle_fn kvm_get_hyp_exit_handler(struct kvm_vcpu *vcpu)
+{
+	if (is_nvhe_hyp_code())
+		return kvm_get_nvhe_exit_handler(vcpu);
+	else
+		return NULL;
+}
+
 /*
  * Return true when we were able to fixup the guest exit and should return to
  * the guest, false when we should restore the host state and return to the
@@ -412,6 +424,8 @@ static inline bool __hyp_handle_ptrauth(struct kvm_vcpu *vcpu)
  */
 static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
 {
+	exit_handle_fn exit_handler;
+
 	if (ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ)
 		vcpu->arch.fault.esr_el2 = read_sysreg_el2(SYS_ESR);
 
@@ -492,6 +506,11 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
 			goto guest;
 	}
 
+	/* Check if there's an exit handler and allow it to handle the exit. */
+	exit_handler = kvm_get_hyp_exit_handler(vcpu);
+	if (exit_handler && exit_handler(vcpu))
+		goto guest;
+
 exit:
 	/* Return to the host kernel and handle the exit */
 	return false;
diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index 430b5bae8761..967a3ad74fbd 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -165,6 +165,41 @@ static void __pmu_switch_to_host(struct kvm_cpu_context *host_ctxt)
 		write_sysreg(pmu->events_host, pmcntenset_el0);
 }
 
+typedef int (*exit_handle_fn)(struct kvm_vcpu *);
+
+static exit_handle_fn hyp_exit_handlers[] = {
+	[0 ... ESR_ELx_EC_MAX]		= NULL,
+	[ESR_ELx_EC_WFx]		= NULL,
+	[ESR_ELx_EC_CP15_32]		= NULL,
+	[ESR_ELx_EC_CP15_64]		= NULL,
+	[ESR_ELx_EC_CP14_MR]		= NULL,
+	[ESR_ELx_EC_CP14_LS]		= NULL,
+	[ESR_ELx_EC_CP14_64]		= NULL,
+	[ESR_ELx_EC_HVC32]		= NULL,
+	[ESR_ELx_EC_SMC32]		= NULL,
+	[ESR_ELx_EC_HVC64]		= NULL,
+	[ESR_ELx_EC_SMC64]		= NULL,
+	[ESR_ELx_EC_SYS64]		= NULL,
+	[ESR_ELx_EC_SVE]		= NULL,
+	[ESR_ELx_EC_IABT_LOW]		= NULL,
+	[ESR_ELx_EC_DABT_LOW]		= NULL,
+	[ESR_ELx_EC_SOFTSTP_LOW]	= NULL,
+	[ESR_ELx_EC_WATCHPT_LOW]	= NULL,
+	[ESR_ELx_EC_BREAKPT_LOW]	= NULL,
+	[ESR_ELx_EC_BKPT32]		= NULL,
+	[ESR_ELx_EC_BRK64]		= NULL,
+	[ESR_ELx_EC_FP_ASIMD]		= NULL,
+	[ESR_ELx_EC_PAC]		= NULL,
+};
+
+exit_handle_fn kvm_get_nvhe_exit_handler(struct kvm_vcpu *vcpu)
+{
+	u32 esr = kvm_vcpu_get_esr(vcpu);
+	u8 esr_ec = ESR_ELx_EC(esr);
+
+	return hyp_exit_handlers[esr_ec];
+}
+
 /* Switch to the guest for legacy non-VHE systems */
 int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
 {
-- 
2.32.0.272.g935e593368-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH v2 09/13] KVM: arm64: Add trap handlers for protected VMs
  2021-06-15 13:39 [PATCH v2 00/13] KVM: arm64: Fixed features for protected VMs Fuad Tabba
                   ` (7 preceding siblings ...)
  2021-06-15 13:39 ` [PATCH v2 08/13] KVM: arm64: Guest exit handlers for nVHE hyp Fuad Tabba
@ 2021-06-15 13:39 ` Fuad Tabba
  2021-07-01 14:08   ` Will Deacon
  2021-06-15 13:39 ` [PATCH v2 10/13] KVM: arm64: Move sanitized copies of CPU features Fuad Tabba
                   ` (3 subsequent siblings)
  12 siblings, 1 reply; 32+ messages in thread
From: Fuad Tabba @ 2021-06-15 13:39 UTC (permalink / raw)
  To: kvmarm
  Cc: maz, will, james.morse, alexandru.elisei, suzuki.poulose,
	mark.rutland, christoffer.dall, pbonzini, drjones, qperret, kvm,
	linux-arm-kernel, kernel-team, tabba

Add trap handlers for protected VMs. These are mainly for Sys64
and debug traps.

No functional change intended as these are not hooked in yet.

Signed-off-by: Fuad Tabba <tabba@google.com>
---
 arch/arm64/include/asm/kvm_hyp.h   |   3 +
 arch/arm64/kvm/arm.c               |   3 +
 arch/arm64/kvm/hyp/nvhe/Makefile   |   2 +-
 arch/arm64/kvm/hyp/nvhe/sys_regs.c | 475 +++++++++++++++++++++++++++++
 4 files changed, 482 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/kvm/hyp/nvhe/sys_regs.c

diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
index 9d60b3006efc..7e81e42107e1 100644
--- a/arch/arm64/include/asm/kvm_hyp.h
+++ b/arch/arm64/include/asm/kvm_hyp.h
@@ -115,7 +115,10 @@ int __pkvm_init(phys_addr_t phys, unsigned long size, unsigned long nr_cpus,
 void __noreturn __host_enter(struct kvm_cpu_context *host_ctxt);
 #endif
 
+extern u64 kvm_nvhe_sym(id_aa64pfr0_el1_sys_val);
+extern u64 kvm_nvhe_sym(id_aa64pfr1_el1_sys_val);
 extern u64 kvm_nvhe_sym(id_aa64mmfr0_el1_sys_val);
 extern u64 kvm_nvhe_sym(id_aa64mmfr1_el1_sys_val);
+extern u64 kvm_nvhe_sym(id_aa64mmfr2_el1_sys_val);
 
 #endif /* __ARM64_KVM_HYP_H__ */
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index d71da6089822..363493395eba 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1751,8 +1751,11 @@ static int kvm_hyp_init_protection(u32 hyp_va_bits)
 	void *addr = phys_to_virt(hyp_mem_base);
 	int ret;
 
+	kvm_nvhe_sym(id_aa64pfr0_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
+	kvm_nvhe_sym(id_aa64pfr1_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1);
 	kvm_nvhe_sym(id_aa64mmfr0_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1);
 	kvm_nvhe_sym(id_aa64mmfr1_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1);
+	kvm_nvhe_sym(id_aa64mmfr2_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64MMFR2_EL1);
 
 	ret = create_hyp_mappings(addr, addr + hyp_mem_size, PAGE_HYP);
 	if (ret)
diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Makefile
index 5df6193fc430..a23f417a0c20 100644
--- a/arch/arm64/kvm/hyp/nvhe/Makefile
+++ b/arch/arm64/kvm/hyp/nvhe/Makefile
@@ -14,7 +14,7 @@ lib-objs := $(addprefix ../../../lib/, $(lib-objs))
 
 obj-y := timer-sr.o sysreg-sr.o debug-sr.o switch.o tlb.o hyp-init.o host.o \
 	 hyp-main.o hyp-smp.o psci-relay.o early_alloc.o stub.o page_alloc.o \
-	 cache.o setup.o mm.o mem_protect.o
+	 cache.o setup.o mm.o mem_protect.o sys_regs.o
 obj-y += ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cpuif-proxy.o ../entry.o \
 	 ../fpsimd.o ../hyp-entry.o ../exception.o ../pgtable.o
 obj-y += $(lib-objs)
diff --git a/arch/arm64/kvm/hyp/nvhe/sys_regs.c b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
new file mode 100644
index 000000000000..ab09ccc64fea
--- /dev/null
+++ b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
@@ -0,0 +1,475 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 Google LLC
+ * Author: Fuad Tabba <tabba@google.com>
+ */
+
+#include <linux/kvm_host.h>
+
+#include <asm/kvm_asm.h>
+#include <asm/kvm_emulate.h>
+#include <asm/kvm_mmu.h>
+
+#include <hyp/adjust_pc.h>
+
+#include "../../sys_regs.h"
+
+/*
+ * Copies of the host's CPU features registers holding sanitized values.
+ */
+u64 id_aa64pfr0_el1_sys_val;
+u64 id_aa64pfr1_el1_sys_val;
+u64 id_aa64mmfr2_el1_sys_val;
+
+/*
+ * Inject an undefined exception to the guest.
+ */
+static void inject_undef(struct kvm_vcpu *vcpu)
+{
+	u32 esr = (ESR_ELx_EC_UNKNOWN << ESR_ELx_EC_SHIFT);
+
+	vcpu->arch.flags |= (KVM_ARM64_EXCEPT_AA64_EL1 |
+			     KVM_ARM64_EXCEPT_AA64_ELx_SYNC |
+			     KVM_ARM64_PENDING_EXCEPTION);
+
+	__kvm_adjust_pc(vcpu);
+
+	write_sysreg_el1(esr, SYS_ESR);
+	write_sysreg_el1(read_sysreg_el2(SYS_ELR), SYS_ELR);
+	write_sysreg_el2(*vcpu_pc(vcpu), SYS_ELR);
+	write_sysreg_el2(*vcpu_cpsr(vcpu), SYS_SPSR);
+}
+
+/*
+ * Accessor for undefined accesses.
+ */
+static bool undef_access(struct kvm_vcpu *vcpu,
+			 struct sys_reg_params *p,
+			 const struct sys_reg_desc *r)
+{
+	inject_undef(vcpu);
+	return false;
+}
+
+/*
+ * Accessors for feature registers.
+ *
+ * If access is allowed, set the regval to the protected VM's view of the
+ * register and return true.
+ * Otherwise, inject an undefined exception and return false.
+ */
+
+/* Accessor for ID_AA64PFR0_EL1. */
+static bool pvm_access_id_aa64pfr0(struct kvm_vcpu *vcpu,
+				   struct sys_reg_params *p,
+				   const struct sys_reg_desc *r)
+{
+	const struct kvm *kvm = (const struct kvm *) kern_hyp_va(vcpu->kvm);
+	u64 allow_mask = 0;
+	u64 set_mask = 0;
+
+	if (p->is_write)
+		return undef_access(vcpu, p, r);
+
+	/*
+	 * Only allow:
+	 * - Floating-point
+	 * - Advanced SIMD
+	 * - Data Independent Timing
+	 */
+	allow_mask |= FEATURE(ID_AA64PFR0_FP) |
+		      FEATURE(ID_AA64PFR0_ASIMD) |
+		      FEATURE(ID_AA64PFR0_DIT);
+
+	/* - ARMv8.4-RAS (not later than v1) */
+	if (id_aa64pfr0_el1_sys_val & FEATURE(ID_AA64PFR0_RAS))
+		set_mask |= FIELD_PREP(FEATURE(ID_AA64PFR0_RAS),
+				       ID_AA64PFR0_RAS_V1);
+
+	/* - AArch64 guests */
+	set_mask |= FIELD_PREP(FEATURE(ID_AA64PFR0_EL0),
+			       ID_AA64PFR0_EL0_64BIT_ONLY) |
+		    FIELD_PREP(FEATURE(ID_AA64PFR0_EL1),
+			       ID_AA64PFR0_EL1_64BIT_ONLY) |
+		    FIELD_PREP(FEATURE(ID_AA64PFR0_EL2),
+			       ID_AA64PFR0_EL2_64BIT_ONLY);
+
+	/* (only set EL3 exception handling if EL3 exists) */
+	if (id_aa64pfr0_el1_sys_val & FEATURE(ID_AA64PFR0_EL3))
+		set_mask |= FIELD_PREP(FEATURE(ID_AA64PFR0_EL3),
+				       ID_AA64PFR0_EL3_64BIT_ONLY);
+
+	/* - Spectre and Meltdown mitigation */
+	set_mask |= FIELD_PREP(FEATURE(ID_AA64PFR0_CSV2),
+			       (u64)kvm->arch.pfr0_csv2);
+	set_mask |= FIELD_PREP(FEATURE(ID_AA64PFR0_CSV3),
+			       (u64)kvm->arch.pfr0_csv3);
+
+	p->regval = (id_aa64pfr0_el1_sys_val & allow_mask) | set_mask;
+	return true;
+}
+
+/* Accessor for ID_AA64PFR1_EL1. */
+static bool pvm_access_id_aa64pfr1(struct kvm_vcpu *vcpu,
+				   struct sys_reg_params *p,
+				   const struct sys_reg_desc *r)
+{
+	u64 allow_mask = 0;
+
+	if (p->is_write)
+		return undef_access(vcpu, p, r);
+
+	/*
+	 * Only allow:
+	 * - Branch Target Identification
+	 * - Speculative Store Bypassing
+	 */
+	allow_mask |= FEATURE(ID_AA64PFR1_BT) |
+		      FEATURE(ID_AA64PFR1_SSBS);
+
+	p->regval = id_aa64pfr1_el1_sys_val & allow_mask;
+	return true;
+}
+
+/* Accessor for ID_AA64ZFR0_EL1. */
+static bool pvm_access_id_aa64zfr0(struct kvm_vcpu *vcpu,
+				   struct sys_reg_params *p,
+				   const struct sys_reg_desc *r)
+{
+	if (p->is_write)
+		return undef_access(vcpu, p, r);
+
+	/* No support for Scalable Vectors */
+	p->regval = 0;
+	return true;
+}
+
+/* Accessor for ID_AA64DFR0_EL1. */
+static bool pvm_access_id_aa64dfr0(struct kvm_vcpu *vcpu,
+				   struct sys_reg_params *p,
+				   const struct sys_reg_desc *r)
+{
+	if (p->is_write)
+		return undef_access(vcpu, p, r);
+
+	/* No support for debug, including breakpoints, and watchpoints */
+	p->regval = 0;
+	return true;
+}
+
+/* Accessor for ID_AA64MMFR0_EL1. */
+static bool pvm_access_id_aa64mmfr0(struct kvm_vcpu *vcpu,
+				    struct sys_reg_params *p,
+				    const struct sys_reg_desc *r)
+{
+	u64 allow_mask = 0;
+	u64 set_mask = 0;
+
+	if (p->is_write)
+		return undef_access(vcpu, p, r);
+
+	/*
+	 * Only allow:
+	 * - Mixed-endian
+	 * - Distinction between Secure and Non-secure Memory
+	 * - Mixed-endian at EL0 only
+	 * - Non-context synchronizing exception entry and exit
+	 */
+	allow_mask |= FEATURE(ID_AA64MMFR0_BIGENDEL) |
+		      FEATURE(ID_AA64MMFR0_SNSMEM) |
+		      FEATURE(ID_AA64MMFR0_BIGENDEL0) |
+		      FEATURE(ID_AA64MMFR0_EXS);
+
+	/*
+	 * - 40-bit IPA
+	 * - 16-bit ASID
+	 * - 4KB granule
+	 */
+	set_mask |= FIELD_PREP(FEATURE(ID_AA64MMFR0_PARANGE),
+			       ID_AA64MMFR0_PARANGE_40) |
+		    FIELD_PREP(FEATURE(ID_AA64MMFR0_ASID),
+			       ID_AA64MMFR0_ASID_16) |
+		    FIELD_PREP(FEATURE(ID_AA64MMFR0_TGRAN64),
+			       ID_AA64MMFR0_TGRAN64_NI);
+
+	p->regval = (id_aa64mmfr0_el1_sys_val & allow_mask) | set_mask;
+	return true;
+}
+
+/* Accessor for ID_AA64MMFR1_EL1. */
+static bool pvm_access_id_aa64mmfr1(struct kvm_vcpu *vcpu,
+				    struct sys_reg_params *p,
+				    const struct sys_reg_desc *r)
+{
+	u64 allow_mask = 0;
+
+	if (p->is_write)
+		return undef_access(vcpu, p, r);
+
+	/*
+	 * Only allow:
+	 * - Hardware translation table updates to Access flag and Dirty state
+	 * - Number of VMID bits from CPU
+	 * - Hierarchical Permission Disables
+	 * - Privileged Access Never
+	 * - SError interrupt exceptions from speculative reads
+	 * - Enhanced Translation Synchronization
+	 */
+	allow_mask |= FEATURE(ID_AA64MMFR1_HADBS) |
+		      FEATURE(ID_AA64MMFR1_VMIDBITS) |
+		      FEATURE(ID_AA64MMFR1_HPD) |
+		      FEATURE(ID_AA64MMFR1_PAN) |
+		      FEATURE(ID_AA64MMFR1_SPECSEI) |
+		      FEATURE(ID_AA64MMFR1_ETS);
+
+	p->regval = id_aa64mmfr1_el1_sys_val & allow_mask;
+	return true;
+}
+
+/* Accessor for ID_AA64MMFR2_EL1. */
+static bool pvm_access_id_aa64mmfr2(struct kvm_vcpu *vcpu,
+				    struct sys_reg_params *p,
+				    const struct sys_reg_desc *r)
+{
+	u64 allow_mask = 0;
+
+	if (p->is_write)
+		return undef_access(vcpu, p, r);
+
+	/*
+	 * Only allow:
+	 * - Common not Private translations
+	 * - User Access Override
+	 * - IESB bit in the SCTLR_ELx registers
+	 * - Unaligned single-copy atomicity and atomic functions
+	 * - ESR_ELx.EC value on an exception by read access to feature ID space
+	 * - TTL field in address operations.
+	 * - Break-before-make sequences when changing translation block size
+	 * - E0PDx mechanism
+	 */
+	allow_mask |= FEATURE(ID_AA64MMFR2_CNP) |
+		      FEATURE(ID_AA64MMFR2_UAO) |
+		      FEATURE(ID_AA64MMFR2_IESB) |
+		      FEATURE(ID_AA64MMFR2_AT) |
+		      FEATURE(ID_AA64MMFR2_IDS) |
+		      FEATURE(ID_AA64MMFR2_TTL) |
+		      FEATURE(ID_AA64MMFR2_BBM) |
+		      FEATURE(ID_AA64MMFR2_E0PD);
+
+	p->regval = id_aa64mmfr2_el1_sys_val & allow_mask;
+	return true;
+}
+
+/*
+ * Accessor for AArch32 Processor Feature Registers.
+ *
+ * The value of these registers is "unknown" according to the spec if AArch32
+ * isn't supported.
+ */
+static bool pvm_access_id_aarch32(struct kvm_vcpu *vcpu,
+				  struct sys_reg_params *p,
+				  const struct sys_reg_desc *r)
+{
+	if (p->is_write)
+		return undef_access(vcpu, p, r);
+
+	/* Use 0 for architecturally "unknown" values. */
+	p->regval = 0;
+	return true;
+}
+
+/* Mark the specified system register as an AArch32 feature register. */
+#define AARCH32(REG) { SYS_DESC(REG), .access = pvm_access_id_aarch32 }
+
+/* Mark the specified system register as not being handled in hyp. */
+#define HOST_HANDLED(REG) { SYS_DESC(REG), .access = NULL }
+
+/*
+ * Architected system registers.
+ * Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2
+ *
+ * NOTE: Anything not explicitly listed here will be *restricted by default*,
+ * i.e., it will lead to injecting an exception into the guest.
+ */
+static const struct sys_reg_desc pvm_sys_reg_descs[] = {
+	/* Cache maintenance by set/way operations are restricted. */
+
+	/* Debug and Trace Registers are all restricted */
+
+	/* AArch64 mappings of the AArch32 ID registers */
+	/* CRm=1 */
+	AARCH32(SYS_ID_PFR0_EL1),
+	AARCH32(SYS_ID_PFR1_EL1),
+	AARCH32(SYS_ID_DFR0_EL1),
+	AARCH32(SYS_ID_AFR0_EL1),
+	AARCH32(SYS_ID_MMFR0_EL1),
+	AARCH32(SYS_ID_MMFR1_EL1),
+	AARCH32(SYS_ID_MMFR2_EL1),
+	AARCH32(SYS_ID_MMFR3_EL1),
+
+	/* CRm=2 */
+	AARCH32(SYS_ID_ISAR0_EL1),
+	AARCH32(SYS_ID_ISAR1_EL1),
+	AARCH32(SYS_ID_ISAR2_EL1),
+	AARCH32(SYS_ID_ISAR3_EL1),
+	AARCH32(SYS_ID_ISAR4_EL1),
+	AARCH32(SYS_ID_ISAR5_EL1),
+	AARCH32(SYS_ID_MMFR4_EL1),
+	AARCH32(SYS_ID_ISAR6_EL1),
+
+	/* CRm=3 */
+	AARCH32(SYS_MVFR0_EL1),
+	AARCH32(SYS_MVFR1_EL1),
+	AARCH32(SYS_MVFR2_EL1),
+	AARCH32(SYS_ID_PFR2_EL1),
+	AARCH32(SYS_ID_DFR1_EL1),
+	AARCH32(SYS_ID_MMFR5_EL1),
+
+	/* AArch64 ID registers */
+	/* CRm=4 */
+	{ SYS_DESC(SYS_ID_AA64PFR0_EL1), .access = pvm_access_id_aa64pfr0 },
+	{ SYS_DESC(SYS_ID_AA64PFR1_EL1), .access = pvm_access_id_aa64pfr1 },
+	{ SYS_DESC(SYS_ID_AA64ZFR0_EL1), .access = pvm_access_id_aa64zfr0 },
+	{ SYS_DESC(SYS_ID_AA64DFR0_EL1), .access = pvm_access_id_aa64dfr0 },
+	HOST_HANDLED(SYS_ID_AA64DFR1_EL1),
+	HOST_HANDLED(SYS_ID_AA64AFR0_EL1),
+	HOST_HANDLED(SYS_ID_AA64AFR1_EL1),
+	HOST_HANDLED(SYS_ID_AA64ISAR0_EL1),
+	HOST_HANDLED(SYS_ID_AA64ISAR1_EL1),
+	{ SYS_DESC(SYS_ID_AA64MMFR0_EL1), .access = pvm_access_id_aa64mmfr0 },
+	{ SYS_DESC(SYS_ID_AA64MMFR1_EL1), .access = pvm_access_id_aa64mmfr1 },
+	{ SYS_DESC(SYS_ID_AA64MMFR2_EL1), .access = pvm_access_id_aa64mmfr2 },
+
+	HOST_HANDLED(SYS_SCTLR_EL1),
+	HOST_HANDLED(SYS_ACTLR_EL1),
+	HOST_HANDLED(SYS_CPACR_EL1),
+
+	HOST_HANDLED(SYS_RGSR_EL1),
+	HOST_HANDLED(SYS_GCR_EL1),
+
+	/* Scalable Vector Registers are restricted. */
+
+	HOST_HANDLED(SYS_TTBR0_EL1),
+	HOST_HANDLED(SYS_TTBR1_EL1),
+	HOST_HANDLED(SYS_TCR_EL1),
+
+	HOST_HANDLED(SYS_APIAKEYLO_EL1),
+	HOST_HANDLED(SYS_APIAKEYHI_EL1),
+	HOST_HANDLED(SYS_APIBKEYLO_EL1),
+	HOST_HANDLED(SYS_APIBKEYHI_EL1),
+	HOST_HANDLED(SYS_APDAKEYLO_EL1),
+	HOST_HANDLED(SYS_APDAKEYHI_EL1),
+	HOST_HANDLED(SYS_APDBKEYLO_EL1),
+	HOST_HANDLED(SYS_APDBKEYHI_EL1),
+	HOST_HANDLED(SYS_APGAKEYLO_EL1),
+	HOST_HANDLED(SYS_APGAKEYHI_EL1),
+
+	HOST_HANDLED(SYS_AFSR0_EL1),
+	HOST_HANDLED(SYS_AFSR1_EL1),
+	HOST_HANDLED(SYS_ESR_EL1),
+
+	HOST_HANDLED(SYS_ERRIDR_EL1),
+	HOST_HANDLED(SYS_ERRSELR_EL1),
+	HOST_HANDLED(SYS_ERXFR_EL1),
+	HOST_HANDLED(SYS_ERXCTLR_EL1),
+	HOST_HANDLED(SYS_ERXSTATUS_EL1),
+	HOST_HANDLED(SYS_ERXADDR_EL1),
+	HOST_HANDLED(SYS_ERXMISC0_EL1),
+	HOST_HANDLED(SYS_ERXMISC1_EL1),
+
+	HOST_HANDLED(SYS_TFSR_EL1),
+	HOST_HANDLED(SYS_TFSRE0_EL1),
+
+	HOST_HANDLED(SYS_FAR_EL1),
+	HOST_HANDLED(SYS_PAR_EL1),
+
+	/* Performance Monitoring Registers are restricted. */
+
+	HOST_HANDLED(SYS_MAIR_EL1),
+	HOST_HANDLED(SYS_AMAIR_EL1),
+
+	/* Limited Ordering Regions Registers are restricted. */
+
+	HOST_HANDLED(SYS_VBAR_EL1),
+	HOST_HANDLED(SYS_DISR_EL1),
+
+	/* GIC CPU Interface registers are restricted. */
+
+	HOST_HANDLED(SYS_CONTEXTIDR_EL1),
+	HOST_HANDLED(SYS_TPIDR_EL1),
+
+	HOST_HANDLED(SYS_SCXTNUM_EL1),
+
+	HOST_HANDLED(SYS_CNTKCTL_EL1),
+
+	HOST_HANDLED(SYS_CCSIDR_EL1),
+	HOST_HANDLED(SYS_CLIDR_EL1),
+	HOST_HANDLED(SYS_CSSELR_EL1),
+	HOST_HANDLED(SYS_CTR_EL0),
+
+	/* Performance Monitoring Registers are restricted. */
+
+	HOST_HANDLED(SYS_TPIDR_EL0),
+	HOST_HANDLED(SYS_TPIDRRO_EL0),
+
+	HOST_HANDLED(SYS_SCXTNUM_EL0),
+
+	/* Activity Monitoring Registers are restricted. */
+
+	HOST_HANDLED(SYS_CNTP_TVAL_EL0),
+	HOST_HANDLED(SYS_CNTP_CTL_EL0),
+	HOST_HANDLED(SYS_CNTP_CVAL_EL0),
+
+	/* Performance Monitoring Registers are restricted. */
+
+	HOST_HANDLED(SYS_DACR32_EL2),
+	HOST_HANDLED(SYS_IFSR32_EL2),
+	HOST_HANDLED(SYS_FPEXC32_EL2),
+};
+
+/*
+ * Handler for protected VM MSR, MRS or System instruction execution in AArch64.
+ *
+ * Return 1 if handled, or 0 if not.
+ */
+int kvm_handle_pvm_sys64(struct kvm_vcpu *vcpu)
+{
+	const struct sys_reg_desc *r;
+	struct sys_reg_params params;
+	unsigned long esr = kvm_vcpu_get_esr(vcpu);
+	int Rt = kvm_vcpu_sys_get_rt(vcpu);
+
+	params = esr_sys64_to_params(esr);
+	params.regval = vcpu_get_reg(vcpu, Rt);
+
+	r = find_reg(&params, pvm_sys_reg_descs, ARRAY_SIZE(pvm_sys_reg_descs));
+
+	/* Undefined access (RESTRICTED). */
+	if (r == NULL) {
+		inject_undef(vcpu);
+		return 1;
+	}
+
+	/* Handled by the host (HOST_HANDLED) */
+	if (r->access == NULL)
+		return 0;
+
+	/* Handled by hyp: skip instruction if instructed to do so. */
+	if (r->access(vcpu, &params, r))
+		__kvm_skip_instr(vcpu);
+
+	vcpu_set_reg(vcpu, Rt, params.regval);
+	return 1;
+}
+
+/*
+ * Handler for protected VM restricted exceptions.
+ *
+ * Inject an undefined exception into the guest and return 1 to indicate that
+ * it was handled.
+ */
+int kvm_handle_pvm_restricted(struct kvm_vcpu *vcpu)
+{
+	inject_undef(vcpu);
+	return 1;
+}
-- 
2.32.0.272.g935e593368-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH v2 10/13] KVM: arm64: Move sanitized copies of CPU features
  2021-06-15 13:39 [PATCH v2 00/13] KVM: arm64: Fixed features for protected VMs Fuad Tabba
                   ` (8 preceding siblings ...)
  2021-06-15 13:39 ` [PATCH v2 09/13] KVM: arm64: Add trap handlers for protected VMs Fuad Tabba
@ 2021-06-15 13:39 ` Fuad Tabba
  2021-06-15 13:39 ` [PATCH v2 11/13] KVM: arm64: Trap access to pVM restricted features Fuad Tabba
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 32+ messages in thread
From: Fuad Tabba @ 2021-06-15 13:39 UTC (permalink / raw)
  To: kvmarm
  Cc: maz, will, james.morse, alexandru.elisei, suzuki.poulose,
	mark.rutland, christoffer.dall, pbonzini, drjones, qperret, kvm,
	linux-arm-kernel, kernel-team, tabba

Move the sanitized copies of the CPU feature registers to the
recently created sys_regs.c. This consolidates all copies in a
more relevant file.

No functional change intended.

Signed-off-by: Fuad Tabba <tabba@google.com>
---
 arch/arm64/kvm/hyp/nvhe/mem_protect.c | 6 ------
 arch/arm64/kvm/hyp/nvhe/sys_regs.c    | 2 ++
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index d938ce95d3bd..925c7db7fa34 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -25,12 +25,6 @@ struct host_kvm host_kvm;
 
 static struct hyp_pool host_s2_pool;
 
-/*
- * Copies of the host's CPU features registers holding sanitized values.
- */
-u64 id_aa64mmfr0_el1_sys_val;
-u64 id_aa64mmfr1_el1_sys_val;
-
 static const u8 pkvm_hyp_id = 1;
 
 static void *host_s2_zalloc_pages_exact(size_t size)
diff --git a/arch/arm64/kvm/hyp/nvhe/sys_regs.c b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
index ab09ccc64fea..de995a8a5eb5 100644
--- a/arch/arm64/kvm/hyp/nvhe/sys_regs.c
+++ b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
@@ -19,6 +19,8 @@
  */
 u64 id_aa64pfr0_el1_sys_val;
 u64 id_aa64pfr1_el1_sys_val;
+u64 id_aa64mmfr0_el1_sys_val;
+u64 id_aa64mmfr1_el1_sys_val;
 u64 id_aa64mmfr2_el1_sys_val;
 
 /*
-- 
2.32.0.272.g935e593368-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH v2 11/13] KVM: arm64: Trap access to pVM restricted features
  2021-06-15 13:39 [PATCH v2 00/13] KVM: arm64: Fixed features for protected VMs Fuad Tabba
                   ` (9 preceding siblings ...)
  2021-06-15 13:39 ` [PATCH v2 10/13] KVM: arm64: Move sanitized copies of CPU features Fuad Tabba
@ 2021-06-15 13:39 ` Fuad Tabba
  2021-06-15 13:39 ` [PATCH v2 12/13] KVM: arm64: Handle protected guests at 32 bits Fuad Tabba
  2021-06-15 13:39 ` [PATCH v2 13/13] KVM: arm64: Check vcpu features at pVM creation Fuad Tabba
  12 siblings, 0 replies; 32+ messages in thread
From: Fuad Tabba @ 2021-06-15 13:39 UTC (permalink / raw)
  To: kvmarm
  Cc: maz, will, james.morse, alexandru.elisei, suzuki.poulose,
	mark.rutland, christoffer.dall, pbonzini, drjones, qperret, kvm,
	linux-arm-kernel, kernel-team, tabba

Trap accesses to restricted features for VMs running in protected
mode.

Access to feature registers are emulated, and only supported
features are exposed to protected VMs.

Accesses to restricted registers as well as restricted
instructions are trapped, and an undefined exception is injected
into the protected guest.

Only affects the functionality of protected VMs. Otherwise,
should not affect non-protected VMs when KVM is running in
protected mode.

Signed-off-by: Fuad Tabba <tabba@google.com>
---
 arch/arm64/kvm/hyp/include/hyp/switch.h |   3 +
 arch/arm64/kvm/hyp/nvhe/switch.c        | 116 +++++++++++++++++++++---
 2 files changed, 105 insertions(+), 14 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index f5d3d1da0aec..d9f087ed6e02 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -33,6 +33,9 @@
 extern struct exception_table_entry __start___kvm_ex_table;
 extern struct exception_table_entry __stop___kvm_ex_table;
 
+int kvm_handle_pvm_sys64(struct kvm_vcpu *vcpu);
+int kvm_handle_pvm_restricted(struct kvm_vcpu *vcpu);
+
 /* Check whether the FP regs were dirtied while in the host-side run loop: */
 static inline bool update_fp_enabled(struct kvm_vcpu *vcpu)
 {
diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index 967a3ad74fbd..8505201e1cfb 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -34,12 +34,74 @@ DEFINE_PER_CPU(struct kvm_host_data, kvm_host_data);
 DEFINE_PER_CPU(struct kvm_cpu_context, kvm_hyp_ctxt);
 DEFINE_PER_CPU(unsigned long, kvm_hyp_vector);
 
+/*
+ * Set EL2 configuration registers to trap restricted register accesses and
+ * instructions for protected VMs.
+ *
+ * Should be called right before vcpu entry to restrict its impact only to the
+ * protected guest.
+ */
+static void __activate_traps_pvm(struct kvm_vcpu *vcpu)
+{
+	u64 hcr;
+	u64 mdcr;
+	u64 cptr;
+
+	if (!kvm_vm_is_protected(kern_hyp_va(vcpu->kvm)))
+		return;
+
+	hcr = read_sysreg(hcr_el2);
+	mdcr = read_sysreg(mdcr_el2);
+	cptr = read_sysreg(cptr_el2);
+
+	hcr |= HCR_TID3 |			/* Feature Registers */
+	       HCR_TLOR |			/* LOR */
+	       HCR_RW |	HCR_TID0 |		/* AArch64 EL1 only */
+	       HCR_TERR |			/* RAS */
+	       HCR_TID5 |			/* Memory Tagging */
+	       HCR_TACR | HCR_TIDCP | HCR_TID1; /* Implementation defined */
+
+	hcr &= ~(HCR_DCT | HCR_ATA |	/* Memory Tagging */
+		 HCR_FIEN |		/* RAS */
+		 HCR_AMVOFFEN);		/* Disable AMU register virtualization */
+
+
+	/* Debug and Trace */
+	mdcr |= MDCR_EL2_TDRA | MDCR_EL2_TDA | MDCR_EL2_TDE |
+		MDCR_EL2_TDOSA | MDCR_EL2_TDCC | MDCR_EL2_TTRF |
+		MDCR_EL2_TPM | MDCR_EL2_TPMCR |
+		MDCR_EL2_TPMS; /* SPE */
+
+	mdcr &= ~(MDCR_EL2_HPME | MDCR_EL2_MTPME |		/* PMU */
+		  (MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT));	/* SPE */
+
+	cptr |= CPTR_EL2_TTA |	/* Trace */
+		CPTR_EL2_TAM |	/* AMU */
+		CPTR_EL2_TZ;	/* SVE */
+
+	/*
+	 * Clear res0 bits and set res1 bits to trap potential new features.
+	 * It's not guaranteed, but new features are typically added with the
+	 * trapping value being the inverse of the reserved one.
+	 */
+	hcr &= ~HCR_RES0;
+	mdcr &= ~MDCR_EL2_RES0;
+	cptr &= ~CPTR_NVHE_EL2_RES0;
+	cptr |= CPTR_NVHE_EL2_RES1;
+
+	/*  __deactivate_traps() restores these registers. */
+	write_sysreg(hcr, hcr_el2);
+	write_sysreg(mdcr, mdcr_el2);
+	write_sysreg(cptr, cptr_el2);
+}
+
 static void __activate_traps(struct kvm_vcpu *vcpu)
 {
 	u64 val;
 
 	___activate_traps(vcpu);
 	__activate_traps_common(vcpu);
+	__activate_traps_pvm(vcpu);
 
 	val = CPTR_EL2_DEFAULT;
 	val |= CPTR_EL2_TTA | CPTR_EL2_TAM;
@@ -165,30 +227,56 @@ static void __pmu_switch_to_host(struct kvm_cpu_context *host_ctxt)
 		write_sysreg(pmu->events_host, pmcntenset_el0);
 }
 
+/**
+ * Handle system register accesses for protected VMs.
+ *
+ * Return 1 if handled, or 0 if not.
+ */
+static int handle_pvm_sys64(struct kvm_vcpu *vcpu)
+{
+	if (kvm_vm_is_protected(kern_hyp_va(vcpu->kvm)))
+		return kvm_handle_pvm_sys64(vcpu);
+	else
+		return 0;
+}
+
+/**
+ * Handle restricted feature accesses for protected VMs.
+ *
+ * Return 1 if handled, or 0 if not.
+ */
+static int handle_pvm_restricted(struct kvm_vcpu *vcpu)
+{
+	if (kvm_vm_is_protected(kern_hyp_va(vcpu->kvm)))
+		return kvm_handle_pvm_restricted(vcpu);
+	else
+		return 0;
+}
+
 typedef int (*exit_handle_fn)(struct kvm_vcpu *);
 
 static exit_handle_fn hyp_exit_handlers[] = {
-	[0 ... ESR_ELx_EC_MAX]		= NULL,
+	[0 ... ESR_ELx_EC_MAX]		= handle_pvm_restricted,
 	[ESR_ELx_EC_WFx]		= NULL,
-	[ESR_ELx_EC_CP15_32]		= NULL,
-	[ESR_ELx_EC_CP15_64]		= NULL,
-	[ESR_ELx_EC_CP14_MR]		= NULL,
-	[ESR_ELx_EC_CP14_LS]		= NULL,
-	[ESR_ELx_EC_CP14_64]		= NULL,
+	[ESR_ELx_EC_CP15_32]		= handle_pvm_restricted,
+	[ESR_ELx_EC_CP15_64]		= handle_pvm_restricted,
+	[ESR_ELx_EC_CP14_MR]		= handle_pvm_restricted,
+	[ESR_ELx_EC_CP14_LS]		= handle_pvm_restricted,
+	[ESR_ELx_EC_CP14_64]		= handle_pvm_restricted,
 	[ESR_ELx_EC_HVC32]		= NULL,
 	[ESR_ELx_EC_SMC32]		= NULL,
 	[ESR_ELx_EC_HVC64]		= NULL,
 	[ESR_ELx_EC_SMC64]		= NULL,
-	[ESR_ELx_EC_SYS64]		= NULL,
-	[ESR_ELx_EC_SVE]		= NULL,
+	[ESR_ELx_EC_SYS64]		= handle_pvm_sys64,
+	[ESR_ELx_EC_SVE]		= handle_pvm_restricted,
 	[ESR_ELx_EC_IABT_LOW]		= NULL,
 	[ESR_ELx_EC_DABT_LOW]		= NULL,
-	[ESR_ELx_EC_SOFTSTP_LOW]	= NULL,
-	[ESR_ELx_EC_WATCHPT_LOW]	= NULL,
-	[ESR_ELx_EC_BREAKPT_LOW]	= NULL,
-	[ESR_ELx_EC_BKPT32]		= NULL,
-	[ESR_ELx_EC_BRK64]		= NULL,
-	[ESR_ELx_EC_FP_ASIMD]		= NULL,
+	[ESR_ELx_EC_SOFTSTP_LOW]	= handle_pvm_restricted,
+	[ESR_ELx_EC_WATCHPT_LOW]	= handle_pvm_restricted,
+	[ESR_ELx_EC_BREAKPT_LOW]	= handle_pvm_restricted,
+	[ESR_ELx_EC_BKPT32]		= handle_pvm_restricted,
+	[ESR_ELx_EC_BRK64]		= handle_pvm_restricted,
+	[ESR_ELx_EC_FP_ASIMD]		= handle_pvm_restricted,
 	[ESR_ELx_EC_PAC]		= NULL,
 };
 
-- 
2.32.0.272.g935e593368-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH v2 12/13] KVM: arm64: Handle protected guests at 32 bits
  2021-06-15 13:39 [PATCH v2 00/13] KVM: arm64: Fixed features for protected VMs Fuad Tabba
                   ` (10 preceding siblings ...)
  2021-06-15 13:39 ` [PATCH v2 11/13] KVM: arm64: Trap access to pVM restricted features Fuad Tabba
@ 2021-06-15 13:39 ` Fuad Tabba
  2021-06-15 13:39 ` [PATCH v2 13/13] KVM: arm64: Check vcpu features at pVM creation Fuad Tabba
  12 siblings, 0 replies; 32+ messages in thread
From: Fuad Tabba @ 2021-06-15 13:39 UTC (permalink / raw)
  To: kvmarm
  Cc: maz, will, james.morse, alexandru.elisei, suzuki.poulose,
	mark.rutland, christoffer.dall, pbonzini, drjones, qperret, kvm,
	linux-arm-kernel, kernel-team, tabba

Protected KVM does not support protected AArch32 guests. However,
it is possible for the guest to force run AArch32, potentially
causing problems. Add an extra check so that if the hypervisor
catches the guest doing that, it can prevent the guest from
running again by resetting vcpu->arch.target and returning
ARM_EXCEPTION_IL.

Adapted from commit 22f553842b14 ("KVM: arm64: Handle Asymmetric
AArch32 systems")

Signed-off-by: Fuad Tabba <tabba@google.com>
---
 arch/arm64/kvm/hyp/include/hyp/switch.h | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index d9f087ed6e02..672801f79579 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -447,6 +447,26 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
 			write_sysreg_el2(read_sysreg_el2(SYS_ELR) - 4, SYS_ELR);
 	}
 
+	/*
+	 * Protected VMs are not allowed to run in AArch32. The check below is
+	 * based on the one in kvm_arch_vcpu_ioctl_run().
+	 * The ARMv8 architecture doesn't give the hypervisor a mechanism to
+	 * prevent a guest from dropping to AArch32 EL0 if implemented by the
+	 * CPU. If the hypervisor spots a guest in such a state ensure it is
+	 * handled, and don't trust the host to spot or fix it.
+	 */
+	if (unlikely(is_nvhe_hyp_code() &&
+		     kvm_vm_is_protected(kern_hyp_va(vcpu->kvm)) &&
+		     vcpu_mode_is_32bit(vcpu))) {
+		/*
+		 * As we have caught the guest red-handed, decide that it isn't
+		 * fit for purpose anymore by making the vcpu invalid.
+		 */
+		vcpu->arch.target = -1;
+		*exit_code = ARM_EXCEPTION_IL;
+		goto exit;
+	}
+
 	/*
 	 * We're using the raw exception code in order to only process
 	 * the trap if no SError is pending. We will come back to the
-- 
2.32.0.272.g935e593368-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH v2 13/13] KVM: arm64: Check vcpu features at pVM creation
  2021-06-15 13:39 [PATCH v2 00/13] KVM: arm64: Fixed features for protected VMs Fuad Tabba
                   ` (11 preceding siblings ...)
  2021-06-15 13:39 ` [PATCH v2 12/13] KVM: arm64: Handle protected guests at 32 bits Fuad Tabba
@ 2021-06-15 13:39 ` Fuad Tabba
  12 siblings, 0 replies; 32+ messages in thread
From: Fuad Tabba @ 2021-06-15 13:39 UTC (permalink / raw)
  To: kvmarm
  Cc: maz, will, james.morse, alexandru.elisei, suzuki.poulose,
	mark.rutland, christoffer.dall, pbonzini, drjones, qperret, kvm,
	linux-arm-kernel, kernel-team, tabba

Check that a protected VM enabled only supported features when
created.

Signed-off-by: Fuad Tabba <tabba@google.com>
---
 arch/arm64/kvm/pkvm.c | 43 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c
index cf624350fb27..15a92f3fdd44 100644
--- a/arch/arm64/kvm/pkvm.c
+++ b/arch/arm64/kvm/pkvm.c
@@ -88,10 +88,53 @@ static void pkvm_teardown_firmware_slot(struct kvm *kvm)
 	kvm->arch.pkvm.firmware_slot = NULL;
 }
 
+/*
+ * Check that only supported features are enabled for the protected VM's vcpus.
+ *
+ * Return 0 if all features enabled for all vcpus are supported, or -EINVAL if
+ * one or more vcpus has one or more unsupported features.
+ */
+static int pkvm_check_features(struct kvm *kvm)
+{
+	int i;
+	const struct kvm_vcpu *vcpu;
+	DECLARE_BITMAP(allowed_features, KVM_VCPU_MAX_FEATURES);
+
+	bitmap_zero(allowed_features, KVM_VCPU_MAX_FEATURES);
+
+	/*
+	 * Support for:
+	 * - CPU starting in poweroff state
+	 * - PSCI v0.2
+	 * - Pointer authentication: address or generic
+	 *
+	 * No support for remaining features, i.e.,:
+	 * - AArch32 state
+	 * - Performance Monitoring
+	 * - Scalable Vectors
+	 */
+	set_bit(KVM_ARM_VCPU_POWER_OFF, allowed_features);
+	set_bit(KVM_ARM_VCPU_PSCI_0_2, allowed_features);
+	set_bit(KVM_ARM_VCPU_PTRAUTH_ADDRESS, allowed_features);
+	set_bit(KVM_ARM_VCPU_PTRAUTH_GENERIC, allowed_features);
+
+	kvm_for_each_vcpu(i, vcpu, kvm) {
+		if (!bitmap_subset(vcpu->arch.features, allowed_features,
+				   KVM_VCPU_MAX_FEATURES))
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int pkvm_enable(struct kvm *kvm, u64 slotid)
 {
 	int ret;
 
+	ret = pkvm_check_features(kvm);
+	if (ret)
+		return ret;
+
 	ret = pkvm_init_firmware_slot(kvm, slotid);
 	if (ret)
 		return ret;
-- 
2.32.0.272.g935e593368-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* Re: [PATCH v2 02/13] KVM: arm64: MDCR_EL2 is a 64-bit register
  2021-06-15 13:39 ` [PATCH v2 02/13] KVM: arm64: MDCR_EL2 is a 64-bit register Fuad Tabba
@ 2021-07-01 12:53   ` Will Deacon
  2021-07-01 13:24     ` Fuad Tabba
  0 siblings, 1 reply; 32+ messages in thread
From: Will Deacon @ 2021-07-01 12:53 UTC (permalink / raw)
  To: Fuad Tabba
  Cc: kvmarm, maz, james.morse, alexandru.elisei, suzuki.poulose,
	mark.rutland, christoffer.dall, pbonzini, drjones, qperret, kvm,
	linux-arm-kernel, kernel-team

On Tue, Jun 15, 2021 at 02:39:39PM +0100, Fuad Tabba wrote:
> Fix the places in KVM that treat MDCR_EL2 as a 32-bit register.
> More recent features (e.g., FEAT_SPEv1p2) use bits above 31.
> 
> No functional change intended.
> 
> Signed-off-by: Fuad Tabba <tabba@google.com>
> ---
>  arch/arm64/include/asm/kvm_arm.h   | 20 ++++++++++----------
>  arch/arm64/include/asm/kvm_asm.h   |  2 +-
>  arch/arm64/include/asm/kvm_host.h  |  2 +-
>  arch/arm64/kvm/debug.c             |  5 +++--
>  arch/arm64/kvm/hyp/nvhe/debug-sr.c |  2 +-
>  arch/arm64/kvm/hyp/vhe/debug-sr.c  |  2 +-
>  6 files changed, 17 insertions(+), 16 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
> index 692c9049befa..25d8a61888e4 100644
> --- a/arch/arm64/include/asm/kvm_arm.h
> +++ b/arch/arm64/include/asm/kvm_arm.h
> @@ -280,18 +280,18 @@
>  /* Hyp Debug Configuration Register bits */
>  #define MDCR_EL2_E2TB_MASK	(UL(0x3))
>  #define MDCR_EL2_E2TB_SHIFT	(UL(24))
> -#define MDCR_EL2_TTRF		(1 << 19)
> -#define MDCR_EL2_TPMS		(1 << 14)
> +#define MDCR_EL2_TTRF		(UL(1) << 19)
> +#define MDCR_EL2_TPMS		(UL(1) << 14)
>  #define MDCR_EL2_E2PB_MASK	(UL(0x3))
>  #define MDCR_EL2_E2PB_SHIFT	(UL(12))
> -#define MDCR_EL2_TDRA		(1 << 11)
> -#define MDCR_EL2_TDOSA		(1 << 10)
> -#define MDCR_EL2_TDA		(1 << 9)
> -#define MDCR_EL2_TDE		(1 << 8)
> -#define MDCR_EL2_HPME		(1 << 7)
> -#define MDCR_EL2_TPM		(1 << 6)
> -#define MDCR_EL2_TPMCR		(1 << 5)
> -#define MDCR_EL2_HPMN_MASK	(0x1F)
> +#define MDCR_EL2_TDRA		(UL(1) << 11)
> +#define MDCR_EL2_TDOSA		(UL(1) << 10)
> +#define MDCR_EL2_TDA		(UL(1) << 9)
> +#define MDCR_EL2_TDE		(UL(1) << 8)
> +#define MDCR_EL2_HPME		(UL(1) << 7)
> +#define MDCR_EL2_TPM		(UL(1) << 6)
> +#define MDCR_EL2_TPMCR		(UL(1) << 5)
> +#define MDCR_EL2_HPMN_MASK	(UL(0x1F))

Personally, I prefer to use the BIT() macro for these things, but what
you've got here is consistent with the rest of the file and I think that's
more important.

>  /* For compatibility with fault code shared with 32-bit */
>  #define FSC_FAULT	ESR_ELx_FSC_FAULT
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index 5e9b33cbac51..d88a5550552c 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -209,7 +209,7 @@ extern u64 __vgic_v3_read_vmcr(void);
>  extern void __vgic_v3_write_vmcr(u32 vmcr);
>  extern void __vgic_v3_init_lrs(void);
>  
> -extern u32 __kvm_get_mdcr_el2(void);
> +extern u64 __kvm_get_mdcr_el2(void);
>  
>  #define __KVM_EXTABLE(from, to)						\
>  	"	.pushsection	__kvm_ex_table, \"a\"\n"		\
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 5645af2a1431..45fdd0b7063f 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -286,7 +286,7 @@ struct kvm_vcpu_arch {
>  
>  	/* HYP configuration */
>  	u64 hcr_el2;
> -	u32 mdcr_el2;
> +	u64 mdcr_el2;
>  
>  	/* Exception Information */
>  	struct kvm_vcpu_fault_info fault;
> diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
> index d5e79d7ee6e9..f7385bfbc9e4 100644
> --- a/arch/arm64/kvm/debug.c
> +++ b/arch/arm64/kvm/debug.c
> @@ -21,7 +21,7 @@
>  				DBG_MDSCR_KDE | \
>  				DBG_MDSCR_MDE)
>  
> -static DEFINE_PER_CPU(u32, mdcr_el2);
> +static DEFINE_PER_CPU(u64, mdcr_el2);
>  
>  /**
>   * save/restore_guest_debug_regs
> @@ -154,7 +154,8 @@ void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu)
>  
>  void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
>  {
> -	unsigned long mdscr, orig_mdcr_el2 = vcpu->arch.mdcr_el2;
> +	unsigned long mdscr;
> +	u64 orig_mdcr_el2 = vcpu->arch.mdcr_el2;

This is arm64 code, so 'unsigned long' is fine here and you can leave the
existing code as-is.

With that:

Acked-by: Will Deacon <will@kernel.org>

Will

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v2 01/13] KVM: arm64: Remove trailing whitespace in comments
  2021-06-15 13:39 ` [PATCH v2 01/13] KVM: arm64: Remove trailing whitespace in comments Fuad Tabba
@ 2021-07-01 12:55   ` Will Deacon
  2021-07-01 13:24     ` Fuad Tabba
  0 siblings, 1 reply; 32+ messages in thread
From: Will Deacon @ 2021-07-01 12:55 UTC (permalink / raw)
  To: Fuad Tabba
  Cc: kvmarm, maz, james.morse, alexandru.elisei, suzuki.poulose,
	mark.rutland, christoffer.dall, pbonzini, drjones, qperret, kvm,
	linux-arm-kernel, kernel-team

On Tue, Jun 15, 2021 at 02:39:38PM +0100, Fuad Tabba wrote:
> Editing this file later, and my editor always cleans up trailing
> whitespace. Removing it earler for clearer future patches.

s/earler/earlier/

Although the commit message is probably better as:

  "Remove trailing whitespace from comment in trap_dbgauthstatus_el1()."

Will

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v2 03/13] KVM: arm64: Fix names of config register fields
  2021-06-15 13:39 ` [PATCH v2 03/13] KVM: arm64: Fix names of config register fields Fuad Tabba
@ 2021-07-01 13:01   ` Will Deacon
  2021-07-01 13:44     ` Fuad Tabba
  0 siblings, 1 reply; 32+ messages in thread
From: Will Deacon @ 2021-07-01 13:01 UTC (permalink / raw)
  To: Fuad Tabba
  Cc: kvmarm, maz, james.morse, alexandru.elisei, suzuki.poulose,
	mark.rutland, christoffer.dall, pbonzini, drjones, qperret, kvm,
	linux-arm-kernel, kernel-team

On Tue, Jun 15, 2021 at 02:39:40PM +0100, Fuad Tabba wrote:
> Change the names of hcr_el2 register fields to match the Arm
> Architecture Reference Manual. Easier for cross-referencing and
> for grepping.
> 
> Also, change the name of CPTR_EL2_RES1 to CPTR_NVHE_EL2_RES1,
> because res1 bits are different for VHE.
> 
> No functional change intended.
> 
> Signed-off-by: Fuad Tabba <tabba@google.com>
> ---
>  arch/arm64/include/asm/kvm_arm.h | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
> index 25d8a61888e4..bee1ba6773fb 100644
> --- a/arch/arm64/include/asm/kvm_arm.h
> +++ b/arch/arm64/include/asm/kvm_arm.h
> @@ -31,9 +31,9 @@
>  #define HCR_TVM		(UL(1) << 26)
>  #define HCR_TTLB	(UL(1) << 25)
>  #define HCR_TPU		(UL(1) << 24)
> -#define HCR_TPC		(UL(1) << 23)
> +#define HCR_TPCP	(UL(1) << 23)

This one is a bit weird: the field is called TPCP if the CPU supports
FEAT_DPB but is called TPC otherwise! So I don't think renaming it like
this really makes anything better. Perhaps add a comment:

  #define HCR_TPC	(UL(1) << 23)	/* TPCP if FEAT_DPB */

?

Rest of the patch looks good:

Acked-by: Will Deacon <will@kernel.org>

Will

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v2 04/13] KVM: arm64: Refactor sys_regs.h, c for nVHE reuse
  2021-06-15 13:39 ` [PATCH v2 04/13] KVM: arm64: Refactor sys_regs.h,c for nVHE reuse Fuad Tabba
@ 2021-07-01 13:09   ` Will Deacon
  2021-07-01 14:04     ` Fuad Tabba
  0 siblings, 1 reply; 32+ messages in thread
From: Will Deacon @ 2021-07-01 13:09 UTC (permalink / raw)
  To: Fuad Tabba
  Cc: kvmarm, maz, james.morse, alexandru.elisei, suzuki.poulose,
	mark.rutland, christoffer.dall, pbonzini, drjones, qperret, kvm,
	linux-arm-kernel, kernel-team

On Tue, Jun 15, 2021 at 02:39:41PM +0100, Fuad Tabba wrote:
> Refactor sys_regs.h and sys_regs.c to make it easier to reuse
> common code. It will be used in nVHE in a later patch.
> 
> No functional change intended.
> 
> Signed-off-by: Fuad Tabba <tabba@google.com>
> ---
>  arch/arm64/kvm/sys_regs.c | 30 +-----------------------------
>  arch/arm64/kvm/sys_regs.h | 35 +++++++++++++++++++++++++++++++++++
>  2 files changed, 36 insertions(+), 29 deletions(-)

[...]

> diff --git a/arch/arm64/kvm/sys_regs.h b/arch/arm64/kvm/sys_regs.h
> index 9d0621417c2a..b8e2a4dd830f 100644
> --- a/arch/arm64/kvm/sys_regs.h
> +++ b/arch/arm64/kvm/sys_regs.h
> @@ -11,6 +11,12 @@
>  #ifndef __ARM64_KVM_SYS_REGS_LOCAL_H__
>  #define __ARM64_KVM_SYS_REGS_LOCAL_H__
>  
> +#include <linux/bsearch.h>
> +
> +#define reg_to_encoding(x)						\
> +	sys_reg((u32)(x)->Op0, (u32)(x)->Op1,				\
> +		(u32)(x)->CRn, (u32)(x)->CRm, (u32)(x)->Op2)
> +
>  struct sys_reg_params {
>  	u8	Op0;
>  	u8	Op1;
> @@ -21,6 +27,14 @@ struct sys_reg_params {
>  	bool	is_write;
>  };
>  
> +#define esr_sys64_to_params(esr)                                               \
> +	((struct sys_reg_params){ .Op0 = ((esr) >> 20) & 3,                    \
> +				  .Op1 = ((esr) >> 14) & 0x7,                  \
> +				  .CRn = ((esr) >> 10) & 0xf,                  \
> +				  .CRm = ((esr) >> 1) & 0xf,                   \
> +				  .Op2 = ((esr) >> 17) & 0x7,                  \
> +				  .is_write = !((esr)&1) })

Formatting has gone funny here (need spaces around the '&' in that last
entry).

> +
>  struct sys_reg_desc {
>  	/* Sysreg string for debug */
>  	const char *name;
> @@ -152,6 +166,24 @@ static inline int cmp_sys_reg(const struct sys_reg_desc *i1,
>  	return i1->Op2 - i2->Op2;
>  }
>  
> +static inline int match_sys_reg(const void *key, const void *elt)
> +{
> +	const unsigned long pval = (unsigned long)key;
> +	const struct sys_reg_desc *r = elt;
> +
> +	return pval - reg_to_encoding(r);
> +}
> +
> +static inline const struct sys_reg_desc *
> +find_reg(const struct sys_reg_params *params, const struct sys_reg_desc table[],
> +	 unsigned int num)
> +{
> +	unsigned long pval = reg_to_encoding(params);
> +
> +	return __inline_bsearch((void *)pval, table, num, sizeof(table[0]),
> +				match_sys_reg);

You don't mention why you change bsearch() to __inline_bsearch().

Will

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v2 05/13] KVM: arm64: Restore mdcr_el2 from vcpu
  2021-06-15 13:39 ` [PATCH v2 05/13] KVM: arm64: Restore mdcr_el2 from vcpu Fuad Tabba
@ 2021-07-01 13:17   ` Will Deacon
  2021-07-01 14:05     ` Fuad Tabba
  0 siblings, 1 reply; 32+ messages in thread
From: Will Deacon @ 2021-07-01 13:17 UTC (permalink / raw)
  To: Fuad Tabba
  Cc: kvmarm, maz, james.morse, alexandru.elisei, suzuki.poulose,
	mark.rutland, christoffer.dall, pbonzini, drjones, qperret, kvm,
	linux-arm-kernel, kernel-team

On Tue, Jun 15, 2021 at 02:39:42PM +0100, Fuad Tabba wrote:
> On deactivating traps, restore the value of mdcr_el2 from the
> vcpu context, rather than directly reading the hardware register.
> Currently, the two values are the same, i.e., the hardware
> register and the vcpu one. A future patch will be changing the
> value of mdcr_el2 on activating traps, and this ensures that its
> value will be restored.
> 
> No functional change intended.
> 
> Signed-off-by: Fuad Tabba <tabba@google.com>
> ---
>  arch/arm64/kvm/hyp/nvhe/switch.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
> index f7af9688c1f7..430b5bae8761 100644
> --- a/arch/arm64/kvm/hyp/nvhe/switch.c
> +++ b/arch/arm64/kvm/hyp/nvhe/switch.c
> @@ -73,7 +73,7 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu)
>  
>  	___deactivate_traps(vcpu);
>  
> -	mdcr_el2 = read_sysreg(mdcr_el2);
> +	mdcr_el2 = vcpu->arch.mdcr_el2;

Do you need to change the VHE code too?

Will

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v2 06/13] KVM: arm64: Add feature register flag definitions
  2021-06-15 13:39 ` [PATCH v2 06/13] KVM: arm64: Add feature register flag definitions Fuad Tabba
@ 2021-07-01 13:22   ` Will Deacon
  2021-07-01 14:31     ` Fuad Tabba
  0 siblings, 1 reply; 32+ messages in thread
From: Will Deacon @ 2021-07-01 13:22 UTC (permalink / raw)
  To: Fuad Tabba
  Cc: kvmarm, maz, james.morse, alexandru.elisei, suzuki.poulose,
	mark.rutland, christoffer.dall, pbonzini, drjones, qperret, kvm,
	linux-arm-kernel, kernel-team

On Tue, Jun 15, 2021 at 02:39:43PM +0100, Fuad Tabba wrote:
> Add feature register flag definitions to clarify which features
> might be supported.
> 
> No functional change intended.
> 
> Signed-off-by: Fuad Tabba <tabba@google.com>
> ---
>  arch/arm64/include/asm/sysreg.h | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index 65d15700a168..42bcc5102d10 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -789,6 +789,10 @@
>  #define ID_AA64PFR0_FP_SUPPORTED	0x0
>  #define ID_AA64PFR0_ASIMD_NI		0xf
>  #define ID_AA64PFR0_ASIMD_SUPPORTED	0x0
> +#define ID_AA64PFR0_EL3_64BIT_ONLY	0x1
> +#define ID_AA64PFR0_EL3_32BIT_64BIT	0x2
> +#define ID_AA64PFR0_EL2_64BIT_ONLY	0x1
> +#define ID_AA64PFR0_EL2_32BIT_64BIT	0x2
>  #define ID_AA64PFR0_EL1_64BIT_ONLY	0x1
>  #define ID_AA64PFR0_EL1_32BIT_64BIT	0x2
>  #define ID_AA64PFR0_EL0_64BIT_ONLY	0x1

Maybe just consolidate all of these into two definitions:

  #define ID_AA64PFR0_ELx_64BIT_ONLY   0x1
  #define ID_AA64PFR0_ELx_32BIT_64BIT  0x2

?

Will

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v2 01/13] KVM: arm64: Remove trailing whitespace in comments
  2021-07-01 12:55   ` Will Deacon
@ 2021-07-01 13:24     ` Fuad Tabba
  0 siblings, 0 replies; 32+ messages in thread
From: Fuad Tabba @ 2021-07-01 13:24 UTC (permalink / raw)
  To: Will Deacon
  Cc: kvmarm, maz, james.morse, alexandru.elisei, suzuki.poulose,
	mark.rutland, christoffer.dall, pbonzini, drjones, qperret, kvm,
	linux-arm-kernel, kernel-team

Hi Will,

On Thu, Jul 1, 2021 at 1:56 PM Will Deacon <will@kernel.org> wrote:
>
> On Tue, Jun 15, 2021 at 02:39:38PM +0100, Fuad Tabba wrote:
> > Editing this file later, and my editor always cleans up trailing
> > whitespace. Removing it earler for clearer future patches.
>
> s/earler/earlier/

Will fix this.

> Although the commit message is probably better as:
>
>   "Remove trailing whitespace from comment in trap_dbgauthstatus_el1()."

Will change the commit message.

Thanks,
/fuad

> Will

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v2 02/13] KVM: arm64: MDCR_EL2 is a 64-bit register
  2021-07-01 12:53   ` Will Deacon
@ 2021-07-01 13:24     ` Fuad Tabba
  0 siblings, 0 replies; 32+ messages in thread
From: Fuad Tabba @ 2021-07-01 13:24 UTC (permalink / raw)
  To: Will Deacon
  Cc: kvmarm, maz, james.morse, alexandru.elisei, suzuki.poulose,
	mark.rutland, christoffer.dall, pbonzini, drjones, qperret, kvm,
	linux-arm-kernel, kernel-team

Hi Will,

On Thu, Jul 1, 2021 at 1:53 PM Will Deacon <will@kernel.org> wrote:
>
> On Tue, Jun 15, 2021 at 02:39:39PM +0100, Fuad Tabba wrote:
> > Fix the places in KVM that treat MDCR_EL2 as a 32-bit register.
> > More recent features (e.g., FEAT_SPEv1p2) use bits above 31.
> >
> > No functional change intended.
> >
> > Signed-off-by: Fuad Tabba <tabba@google.com>
> > ---
> >  arch/arm64/include/asm/kvm_arm.h   | 20 ++++++++++----------
> >  arch/arm64/include/asm/kvm_asm.h   |  2 +-
> >  arch/arm64/include/asm/kvm_host.h  |  2 +-
> >  arch/arm64/kvm/debug.c             |  5 +++--
> >  arch/arm64/kvm/hyp/nvhe/debug-sr.c |  2 +-
> >  arch/arm64/kvm/hyp/vhe/debug-sr.c  |  2 +-
> >  6 files changed, 17 insertions(+), 16 deletions(-)
> >
> > diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
> > index 692c9049befa..25d8a61888e4 100644
> > --- a/arch/arm64/include/asm/kvm_arm.h
> > +++ b/arch/arm64/include/asm/kvm_arm.h
> > @@ -280,18 +280,18 @@
> >  /* Hyp Debug Configuration Register bits */
> >  #define MDCR_EL2_E2TB_MASK   (UL(0x3))
> >  #define MDCR_EL2_E2TB_SHIFT  (UL(24))
> > -#define MDCR_EL2_TTRF                (1 << 19)
> > -#define MDCR_EL2_TPMS                (1 << 14)
> > +#define MDCR_EL2_TTRF                (UL(1) << 19)
> > +#define MDCR_EL2_TPMS                (UL(1) << 14)
> >  #define MDCR_EL2_E2PB_MASK   (UL(0x3))
> >  #define MDCR_EL2_E2PB_SHIFT  (UL(12))
> > -#define MDCR_EL2_TDRA                (1 << 11)
> > -#define MDCR_EL2_TDOSA               (1 << 10)
> > -#define MDCR_EL2_TDA         (1 << 9)
> > -#define MDCR_EL2_TDE         (1 << 8)
> > -#define MDCR_EL2_HPME                (1 << 7)
> > -#define MDCR_EL2_TPM         (1 << 6)
> > -#define MDCR_EL2_TPMCR               (1 << 5)
> > -#define MDCR_EL2_HPMN_MASK   (0x1F)
> > +#define MDCR_EL2_TDRA                (UL(1) << 11)
> > +#define MDCR_EL2_TDOSA               (UL(1) << 10)
> > +#define MDCR_EL2_TDA         (UL(1) << 9)
> > +#define MDCR_EL2_TDE         (UL(1) << 8)
> > +#define MDCR_EL2_HPME                (UL(1) << 7)
> > +#define MDCR_EL2_TPM         (UL(1) << 6)
> > +#define MDCR_EL2_TPMCR               (UL(1) << 5)
> > +#define MDCR_EL2_HPMN_MASK   (UL(0x1F))
>
> Personally, I prefer to use the BIT() macro for these things, but what
> you've got here is consistent with the rest of the file and I think that's
> more important.
>
> >  /* For compatibility with fault code shared with 32-bit */
> >  #define FSC_FAULT    ESR_ELx_FSC_FAULT
> > diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> > index 5e9b33cbac51..d88a5550552c 100644
> > --- a/arch/arm64/include/asm/kvm_asm.h
> > +++ b/arch/arm64/include/asm/kvm_asm.h
> > @@ -209,7 +209,7 @@ extern u64 __vgic_v3_read_vmcr(void);
> >  extern void __vgic_v3_write_vmcr(u32 vmcr);
> >  extern void __vgic_v3_init_lrs(void);
> >
> > -extern u32 __kvm_get_mdcr_el2(void);
> > +extern u64 __kvm_get_mdcr_el2(void);
> >
> >  #define __KVM_EXTABLE(from, to)                                              \
> >       "       .pushsection    __kvm_ex_table, \"a\"\n"                \
> > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > index 5645af2a1431..45fdd0b7063f 100644
> > --- a/arch/arm64/include/asm/kvm_host.h
> > +++ b/arch/arm64/include/asm/kvm_host.h
> > @@ -286,7 +286,7 @@ struct kvm_vcpu_arch {
> >
> >       /* HYP configuration */
> >       u64 hcr_el2;
> > -     u32 mdcr_el2;
> > +     u64 mdcr_el2;
> >
> >       /* Exception Information */
> >       struct kvm_vcpu_fault_info fault;
> > diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
> > index d5e79d7ee6e9..f7385bfbc9e4 100644
> > --- a/arch/arm64/kvm/debug.c
> > +++ b/arch/arm64/kvm/debug.c
> > @@ -21,7 +21,7 @@
> >                               DBG_MDSCR_KDE | \
> >                               DBG_MDSCR_MDE)
> >
> > -static DEFINE_PER_CPU(u32, mdcr_el2);
> > +static DEFINE_PER_CPU(u64, mdcr_el2);
> >
> >  /**
> >   * save/restore_guest_debug_regs
> > @@ -154,7 +154,8 @@ void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu)
> >
> >  void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
> >  {
> > -     unsigned long mdscr, orig_mdcr_el2 = vcpu->arch.mdcr_el2;
> > +     unsigned long mdscr;
> > +     u64 orig_mdcr_el2 = vcpu->arch.mdcr_el2;
>
> This is arm64 code, so 'unsigned long' is fine here and you can leave the
> existing code as-is.

I'll keep the existing code as it is.

Thanks,
/fuad


> With that:
>
> Acked-by: Will Deacon <will@kernel.org>
>
> Will

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v2 07/13] KVM: arm64: Add config register bit definitions
  2021-06-15 13:39 ` [PATCH v2 07/13] KVM: arm64: Add config register bit definitions Fuad Tabba
@ 2021-07-01 13:33   ` Will Deacon
  2021-07-01 14:52     ` Fuad Tabba
  0 siblings, 1 reply; 32+ messages in thread
From: Will Deacon @ 2021-07-01 13:33 UTC (permalink / raw)
  To: Fuad Tabba
  Cc: kvmarm, maz, james.morse, alexandru.elisei, suzuki.poulose,
	mark.rutland, christoffer.dall, pbonzini, drjones, qperret, kvm,
	linux-arm-kernel, kernel-team

On Tue, Jun 15, 2021 at 02:39:44PM +0100, Fuad Tabba wrote:
> Add hardware configuration register bit definitions for HCR_EL2
> and MDCR_EL2. Future patches toggle these hyp configuration
> register bits to trap on certain accesses.
> 
> No functional change intended.
> 
> Signed-off-by: Fuad Tabba <tabba@google.com>
> ---
>  arch/arm64/include/asm/kvm_arm.h | 21 +++++++++++++++++++++
>  1 file changed, 21 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
> index bee1ba6773fb..a78090071f1f 100644
> --- a/arch/arm64/include/asm/kvm_arm.h
> +++ b/arch/arm64/include/asm/kvm_arm.h
> @@ -12,7 +12,11 @@
>  #include <asm/types.h>
>  
>  /* Hyp Configuration Register (HCR) bits */
> +#define HCR_TID5	(UL(1) << 58)
> +#define HCR_DCT		(UL(1) << 57)
>  #define HCR_ATA		(UL(1) << 56)
> +#define HCR_AMVOFFEN	(UL(1) << 51)
> +#define HCR_FIEN	(UL(1) << 47)
>  #define HCR_FWB		(UL(1) << 46)
>  #define HCR_API		(UL(1) << 41)
>  #define HCR_APK		(UL(1) << 40)
> @@ -55,6 +59,7 @@
>  #define HCR_PTW		(UL(1) << 2)
>  #define HCR_SWIO	(UL(1) << 1)
>  #define HCR_VM		(UL(1) << 0)
> +#define HCR_RES0	((UL(1) << 48) | (UL(1) << 39))
>  
>  /*
>   * The bits we set in HCR:
> @@ -276,11 +281,21 @@
>  #define CPTR_EL2_TZ	(1 << 8)
>  #define CPTR_NVHE_EL2_RES1	0x000032ff /* known RES1 bits in CPTR_EL2 (nVHE) */
>  #define CPTR_EL2_DEFAULT	CPTR_NVHE_EL2_RES1
> +#define CPTR_NVHE_EL2_RES0	(GENMASK_ULL(63, 32) |	\
> +				 GENMASK_ULL(29, 21) |	\
> +				 GENMASK_ULL(19, 14) |	\
> +				 (UL(1) << 11))
>  
>  /* Hyp Debug Configuration Register bits */
>  #define MDCR_EL2_E2TB_MASK	(UL(0x3))
>  #define MDCR_EL2_E2TB_SHIFT	(UL(24))
> +#define MDCR_EL2_HPMFZS		(UL(1) << 36)
> +#define MDCR_EL2_HPMFZO		(UL(1) << 29)
> +#define MDCR_EL2_MTPME		(UL(1) << 28)
> +#define MDCR_EL2_TDCC		(UL(1) << 27)
> +#define MDCR_EL2_HCCD		(UL(1) << 23)
>  #define MDCR_EL2_TTRF		(UL(1) << 19)
> +#define MDCR_EL2_HPMD		(UL(1) << 17)
>  #define MDCR_EL2_TPMS		(UL(1) << 14)
>  #define MDCR_EL2_E2PB_MASK	(UL(0x3))
>  #define MDCR_EL2_E2PB_SHIFT	(UL(12))
> @@ -292,6 +307,12 @@
>  #define MDCR_EL2_TPM		(UL(1) << 6)
>  #define MDCR_EL2_TPMCR		(UL(1) << 5)
>  #define MDCR_EL2_HPMN_MASK	(UL(0x1F))
> +#define MDCR_EL2_RES0		(GENMASK_ULL(63, 37) |	\
> +				 GENMASK_ULL(35, 30) |	\
> +				 GENMASK_ULL(25, 24) |	\
> +				 GENMASK_ULL(22, 20) |	\
> +				 (UL(1) << 18) |	\
> +				 GENMASK_ULL(16, 15))

There's an inconsistent mix of ULL and UL here. Given we're on arm64,
maybe just use GENMASK() and BIT() for these RES0 regions?

Anyway, the bit positions all look fine. You're missing HLP in bit 26,
but I guess that's not something you care about?

Will

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v2 03/13] KVM: arm64: Fix names of config register fields
  2021-07-01 13:01   ` Will Deacon
@ 2021-07-01 13:44     ` Fuad Tabba
  0 siblings, 0 replies; 32+ messages in thread
From: Fuad Tabba @ 2021-07-01 13:44 UTC (permalink / raw)
  To: Will Deacon
  Cc: kvmarm, maz, james.morse, alexandru.elisei, suzuki.poulose,
	mark.rutland, christoffer.dall, pbonzini, drjones, qperret, kvm,
	linux-arm-kernel, kernel-team

Hi Will,

On Thu, Jul 1, 2021 at 2:01 PM Will Deacon <will@kernel.org> wrote:
>
> On Tue, Jun 15, 2021 at 02:39:40PM +0100, Fuad Tabba wrote:
> > Change the names of hcr_el2 register fields to match the Arm
> > Architecture Reference Manual. Easier for cross-referencing and
> > for grepping.
> >
> > Also, change the name of CPTR_EL2_RES1 to CPTR_NVHE_EL2_RES1,
> > because res1 bits are different for VHE.
> >
> > No functional change intended.
> >
> > Signed-off-by: Fuad Tabba <tabba@google.com>
> > ---
> >  arch/arm64/include/asm/kvm_arm.h | 12 ++++++------
> >  1 file changed, 6 insertions(+), 6 deletions(-)
> >
> > diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
> > index 25d8a61888e4..bee1ba6773fb 100644
> > --- a/arch/arm64/include/asm/kvm_arm.h
> > +++ b/arch/arm64/include/asm/kvm_arm.h
> > @@ -31,9 +31,9 @@
> >  #define HCR_TVM              (UL(1) << 26)
> >  #define HCR_TTLB     (UL(1) << 25)
> >  #define HCR_TPU              (UL(1) << 24)
> > -#define HCR_TPC              (UL(1) << 23)
> > +#define HCR_TPCP     (UL(1) << 23)
>
> This one is a bit weird: the field is called TPCP if the CPU supports
> FEAT_DPB but is called TPC otherwise! So I don't think renaming it like
> this really makes anything better. Perhaps add a comment:
>
>   #define HCR_TPC       (UL(1) << 23)   /* TPCP if FEAT_DPB */

I missed that. That's why it's referred to as Bit[23] in the diagram.
I'll add the comment and revert its name.

Thanks,
/fuad

> ?
>
> Rest of the patch looks good:
>
> Acked-by: Will Deacon <will@kernel.org>
>
> Will

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v2 08/13] KVM: arm64: Guest exit handlers for nVHE hyp
  2021-06-15 13:39 ` [PATCH v2 08/13] KVM: arm64: Guest exit handlers for nVHE hyp Fuad Tabba
@ 2021-07-01 13:48   ` Will Deacon
  2021-07-01 14:58     ` Fuad Tabba
  0 siblings, 1 reply; 32+ messages in thread
From: Will Deacon @ 2021-07-01 13:48 UTC (permalink / raw)
  To: Fuad Tabba
  Cc: kvmarm, maz, james.morse, alexandru.elisei, suzuki.poulose,
	mark.rutland, christoffer.dall, pbonzini, drjones, qperret, kvm,
	linux-arm-kernel, kernel-team

On Tue, Jun 15, 2021 at 02:39:45PM +0100, Fuad Tabba wrote:
> Add an array of pointers to handlers for various trap reasons in
> nVHE code.
> 
> The current code selects how to fixup a guest on exit based on a
> series of if/else statements. Future patches will also require
> different handling for guest exists. Create an array of handlers
> to consolidate them.
> 
> No functional change intended as the array isn't populated yet.
> 
> Signed-off-by: Fuad Tabba <tabba@google.com>
> ---
>  arch/arm64/kvm/hyp/include/hyp/switch.h | 19 ++++++++++++++
>  arch/arm64/kvm/hyp/nvhe/switch.c        | 35 +++++++++++++++++++++++++
>  2 files changed, 54 insertions(+)
> 
> diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
> index e4a2f295a394..f5d3d1da0aec 100644
> --- a/arch/arm64/kvm/hyp/include/hyp/switch.h
> +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
> @@ -405,6 +405,18 @@ static inline bool __hyp_handle_ptrauth(struct kvm_vcpu *vcpu)
>  	return true;
>  }
>  
> +typedef int (*exit_handle_fn)(struct kvm_vcpu *);
> +
> +exit_handle_fn kvm_get_nvhe_exit_handler(struct kvm_vcpu *vcpu);
> +
> +static exit_handle_fn kvm_get_hyp_exit_handler(struct kvm_vcpu *vcpu)
> +{
> +	if (is_nvhe_hyp_code())
> +		return kvm_get_nvhe_exit_handler(vcpu);
> +	else
> +		return NULL;
> +}

nit: might be a bit tidier with a ternary if (?:).

But either way:

Acked-by: Will Deacon <will@kernel.org>

Will

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v2 04/13] KVM: arm64: Refactor sys_regs.h, c for nVHE reuse
  2021-07-01 13:09   ` [PATCH v2 04/13] KVM: arm64: Refactor sys_regs.h, c " Will Deacon
@ 2021-07-01 14:04     ` Fuad Tabba
  0 siblings, 0 replies; 32+ messages in thread
From: Fuad Tabba @ 2021-07-01 14:04 UTC (permalink / raw)
  To: Will Deacon
  Cc: kvmarm, maz, james.morse, alexandru.elisei, suzuki.poulose,
	mark.rutland, christoffer.dall, pbonzini, drjones, qperret, kvm,
	linux-arm-kernel, kernel-team

Hi Will,

On Thu, Jul 1, 2021 at 2:09 PM Will Deacon <will@kernel.org> wrote:
>
> On Tue, Jun 15, 2021 at 02:39:41PM +0100, Fuad Tabba wrote:
> > Refactor sys_regs.h and sys_regs.c to make it easier to reuse
> > common code. It will be used in nVHE in a later patch.
> >
> > No functional change intended.
> >
> > Signed-off-by: Fuad Tabba <tabba@google.com>
> > ---
> >  arch/arm64/kvm/sys_regs.c | 30 +-----------------------------
> >  arch/arm64/kvm/sys_regs.h | 35 +++++++++++++++++++++++++++++++++++
> >  2 files changed, 36 insertions(+), 29 deletions(-)
>
> [...]
>
> > diff --git a/arch/arm64/kvm/sys_regs.h b/arch/arm64/kvm/sys_regs.h
> > index 9d0621417c2a..b8e2a4dd830f 100644
> > --- a/arch/arm64/kvm/sys_regs.h
> > +++ b/arch/arm64/kvm/sys_regs.h
> > @@ -11,6 +11,12 @@
> >  #ifndef __ARM64_KVM_SYS_REGS_LOCAL_H__
> >  #define __ARM64_KVM_SYS_REGS_LOCAL_H__
> >
> > +#include <linux/bsearch.h>
> > +
> > +#define reg_to_encoding(x)                                           \
> > +     sys_reg((u32)(x)->Op0, (u32)(x)->Op1,                           \
> > +             (u32)(x)->CRn, (u32)(x)->CRm, (u32)(x)->Op2)
> > +
> >  struct sys_reg_params {
> >       u8      Op0;
> >       u8      Op1;
> > @@ -21,6 +27,14 @@ struct sys_reg_params {
> >       bool    is_write;
> >  };
> >
> > +#define esr_sys64_to_params(esr)                                               \
> > +     ((struct sys_reg_params){ .Op0 = ((esr) >> 20) & 3,                    \
> > +                               .Op1 = ((esr) >> 14) & 0x7,                  \
> > +                               .CRn = ((esr) >> 10) & 0xf,                  \
> > +                               .CRm = ((esr) >> 1) & 0xf,                   \
> > +                               .Op2 = ((esr) >> 17) & 0x7,                  \
> > +                               .is_write = !((esr)&1) })
>
> Formatting has gone funny here (need spaces around the '&' in that last
> entry).

Will fix this.

> > +
> >  struct sys_reg_desc {
> >       /* Sysreg string for debug */
> >       const char *name;
> > @@ -152,6 +166,24 @@ static inline int cmp_sys_reg(const struct sys_reg_desc *i1,
> >       return i1->Op2 - i2->Op2;
> >  }
> >
> > +static inline int match_sys_reg(const void *key, const void *elt)
> > +{
> > +     const unsigned long pval = (unsigned long)key;
> > +     const struct sys_reg_desc *r = elt;
> > +
> > +     return pval - reg_to_encoding(r);
> > +}
> > +
> > +static inline const struct sys_reg_desc *
> > +find_reg(const struct sys_reg_params *params, const struct sys_reg_desc table[],
> > +      unsigned int num)
> > +{
> > +     unsigned long pval = reg_to_encoding(params);
> > +
> > +     return __inline_bsearch((void *)pval, table, num, sizeof(table[0]),
> > +                             match_sys_reg);
>
> You don't mention why you change bsearch() to __inline_bsearch().

It's because of linking with nvhe. Rather than copy the bsearch code
for nvhe, I thought I'd use the inline version of bsearch. I'll update
the comment to explain that.

Thanks,
/fuad

> Will

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v2 05/13] KVM: arm64: Restore mdcr_el2 from vcpu
  2021-07-01 13:17   ` Will Deacon
@ 2021-07-01 14:05     ` Fuad Tabba
  0 siblings, 0 replies; 32+ messages in thread
From: Fuad Tabba @ 2021-07-01 14:05 UTC (permalink / raw)
  To: Will Deacon
  Cc: kvmarm, maz, james.morse, alexandru.elisei, suzuki.poulose,
	mark.rutland, christoffer.dall, pbonzini, drjones, qperret, kvm,
	linux-arm-kernel, kernel-team

Hi Will,

On Thu, Jul 1, 2021 at 2:17 PM Will Deacon <will@kernel.org> wrote:
>
> On Tue, Jun 15, 2021 at 02:39:42PM +0100, Fuad Tabba wrote:
> > On deactivating traps, restore the value of mdcr_el2 from the
> > vcpu context, rather than directly reading the hardware register.
> > Currently, the two values are the same, i.e., the hardware
> > register and the vcpu one. A future patch will be changing the
> > value of mdcr_el2 on activating traps, and this ensures that its
> > value will be restored.
> >
> > No functional change intended.
> >
> > Signed-off-by: Fuad Tabba <tabba@google.com>
> > ---
> >  arch/arm64/kvm/hyp/nvhe/switch.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
> > index f7af9688c1f7..430b5bae8761 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/switch.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/switch.c
> > @@ -73,7 +73,7 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu)
> >
> >       ___deactivate_traps(vcpu);
> >
> > -     mdcr_el2 = read_sysreg(mdcr_el2);
> > +     mdcr_el2 = vcpu->arch.mdcr_el2;
>
> Do you need to change the VHE code too?

No. The code that would toggle mdcr_el2 only affects nvhe and only in
protected mode.

Cheers,
/fuad

>
> Will

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v2 09/13] KVM: arm64: Add trap handlers for protected VMs
  2021-06-15 13:39 ` [PATCH v2 09/13] KVM: arm64: Add trap handlers for protected VMs Fuad Tabba
@ 2021-07-01 14:08   ` Will Deacon
  2021-07-14 20:01     ` Andrew Jones
  0 siblings, 1 reply; 32+ messages in thread
From: Will Deacon @ 2021-07-01 14:08 UTC (permalink / raw)
  To: Fuad Tabba
  Cc: kvmarm, maz, james.morse, alexandru.elisei, suzuki.poulose,
	mark.rutland, christoffer.dall, pbonzini, drjones, qperret, kvm,
	linux-arm-kernel, kernel-team

On Tue, Jun 15, 2021 at 02:39:46PM +0100, Fuad Tabba wrote:
> Add trap handlers for protected VMs. These are mainly for Sys64
> and debug traps.

I think one big thing missing from this patch is some rationale around
which features are advertised and which are not. Further, when traps
are enabled later on, there doesn't seem to be one place which drives the
logic, so it's quite hard to reason about.

So I think we need both some documentation to describe the architectural
environment provided to protected VMs, but also a way to couple the logic
which says "We hide this feature from the ID registers because of foo"
with the logic that says "And here is the control bit to trap this feature".

Otherwise, it's very hard to ensure that this is (and remains) consistent.
It would also make it easier to review :)

> No functional change intended as these are not hooked in yet.
> 
> Signed-off-by: Fuad Tabba <tabba@google.com>
> ---
>  arch/arm64/include/asm/kvm_hyp.h   |   3 +
>  arch/arm64/kvm/arm.c               |   3 +
>  arch/arm64/kvm/hyp/nvhe/Makefile   |   2 +-
>  arch/arm64/kvm/hyp/nvhe/sys_regs.c | 475 +++++++++++++++++++++++++++++
>  4 files changed, 482 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm64/kvm/hyp/nvhe/sys_regs.c
> 
> diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
> index 9d60b3006efc..7e81e42107e1 100644
> --- a/arch/arm64/include/asm/kvm_hyp.h
> +++ b/arch/arm64/include/asm/kvm_hyp.h
> @@ -115,7 +115,10 @@ int __pkvm_init(phys_addr_t phys, unsigned long size, unsigned long nr_cpus,
>  void __noreturn __host_enter(struct kvm_cpu_context *host_ctxt);
>  #endif
>  
> +extern u64 kvm_nvhe_sym(id_aa64pfr0_el1_sys_val);
> +extern u64 kvm_nvhe_sym(id_aa64pfr1_el1_sys_val);
>  extern u64 kvm_nvhe_sym(id_aa64mmfr0_el1_sys_val);
>  extern u64 kvm_nvhe_sym(id_aa64mmfr1_el1_sys_val);
> +extern u64 kvm_nvhe_sym(id_aa64mmfr2_el1_sys_val);
>  
>  #endif /* __ARM64_KVM_HYP_H__ */
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index d71da6089822..363493395eba 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -1751,8 +1751,11 @@ static int kvm_hyp_init_protection(u32 hyp_va_bits)
>  	void *addr = phys_to_virt(hyp_mem_base);
>  	int ret;
>  
> +	kvm_nvhe_sym(id_aa64pfr0_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
> +	kvm_nvhe_sym(id_aa64pfr1_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1);
>  	kvm_nvhe_sym(id_aa64mmfr0_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1);
>  	kvm_nvhe_sym(id_aa64mmfr1_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1);
> +	kvm_nvhe_sym(id_aa64mmfr2_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64MMFR2_EL1);
>  
>  	ret = create_hyp_mappings(addr, addr + hyp_mem_size, PAGE_HYP);
>  	if (ret)
> diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Makefile
> index 5df6193fc430..a23f417a0c20 100644
> --- a/arch/arm64/kvm/hyp/nvhe/Makefile
> +++ b/arch/arm64/kvm/hyp/nvhe/Makefile
> @@ -14,7 +14,7 @@ lib-objs := $(addprefix ../../../lib/, $(lib-objs))
>  
>  obj-y := timer-sr.o sysreg-sr.o debug-sr.o switch.o tlb.o hyp-init.o host.o \
>  	 hyp-main.o hyp-smp.o psci-relay.o early_alloc.o stub.o page_alloc.o \
> -	 cache.o setup.o mm.o mem_protect.o
> +	 cache.o setup.o mm.o mem_protect.o sys_regs.o
>  obj-y += ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cpuif-proxy.o ../entry.o \
>  	 ../fpsimd.o ../hyp-entry.o ../exception.o ../pgtable.o
>  obj-y += $(lib-objs)
> diff --git a/arch/arm64/kvm/hyp/nvhe/sys_regs.c b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
> new file mode 100644
> index 000000000000..ab09ccc64fea
> --- /dev/null
> +++ b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
> @@ -0,0 +1,475 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2021 Google LLC
> + * Author: Fuad Tabba <tabba@google.com>
> + */
> +
> +#include <linux/kvm_host.h>
> +
> +#include <asm/kvm_asm.h>
> +#include <asm/kvm_emulate.h>
> +#include <asm/kvm_mmu.h>
> +
> +#include <hyp/adjust_pc.h>
> +
> +#include "../../sys_regs.h"
> +
> +/*
> + * Copies of the host's CPU features registers holding sanitized values.
> + */
> +u64 id_aa64pfr0_el1_sys_val;
> +u64 id_aa64pfr1_el1_sys_val;
> +u64 id_aa64mmfr2_el1_sys_val;
> +
> +/*
> + * Inject an undefined exception to the guest.
> + */
> +static void inject_undef(struct kvm_vcpu *vcpu)
> +{
> +	u32 esr = (ESR_ELx_EC_UNKNOWN << ESR_ELx_EC_SHIFT);
> +
> +	vcpu->arch.flags |= (KVM_ARM64_EXCEPT_AA64_EL1 |
> +			     KVM_ARM64_EXCEPT_AA64_ELx_SYNC |
> +			     KVM_ARM64_PENDING_EXCEPTION);

Has vcpu_cpsr(vcpu) been populated as part of the trap? I couldn't spot
that, but __kvm_adjust_pc(vcpu) goes and reads that information.

> +	__kvm_adjust_pc(vcpu);
> +
> +	write_sysreg_el1(esr, SYS_ESR);
> +	write_sysreg_el1(read_sysreg_el2(SYS_ELR), SYS_ELR);
> +	write_sysreg_el2(*vcpu_pc(vcpu), SYS_ELR);
> +	write_sysreg_el2(*vcpu_cpsr(vcpu), SYS_SPSR);

Will

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v2 06/13] KVM: arm64: Add feature register flag definitions
  2021-07-01 13:22   ` Will Deacon
@ 2021-07-01 14:31     ` Fuad Tabba
  0 siblings, 0 replies; 32+ messages in thread
From: Fuad Tabba @ 2021-07-01 14:31 UTC (permalink / raw)
  To: Will Deacon
  Cc: kvmarm, maz, james.morse, alexandru.elisei, suzuki.poulose,
	mark.rutland, christoffer.dall, pbonzini, drjones, qperret, kvm,
	linux-arm-kernel, kernel-team

Hi Will,

On Thu, Jul 1, 2021 at 2:22 PM Will Deacon <will@kernel.org> wrote:
>
> On Tue, Jun 15, 2021 at 02:39:43PM +0100, Fuad Tabba wrote:
> > Add feature register flag definitions to clarify which features
> > might be supported.
> >
> > No functional change intended.
> >
> > Signed-off-by: Fuad Tabba <tabba@google.com>
> > ---
> >  arch/arm64/include/asm/sysreg.h | 9 +++++++++
> >  1 file changed, 9 insertions(+)
> >
> > diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> > index 65d15700a168..42bcc5102d10 100644
> > --- a/arch/arm64/include/asm/sysreg.h
> > +++ b/arch/arm64/include/asm/sysreg.h
> > @@ -789,6 +789,10 @@
> >  #define ID_AA64PFR0_FP_SUPPORTED     0x0
> >  #define ID_AA64PFR0_ASIMD_NI         0xf
> >  #define ID_AA64PFR0_ASIMD_SUPPORTED  0x0
> > +#define ID_AA64PFR0_EL3_64BIT_ONLY   0x1
> > +#define ID_AA64PFR0_EL3_32BIT_64BIT  0x2
> > +#define ID_AA64PFR0_EL2_64BIT_ONLY   0x1
> > +#define ID_AA64PFR0_EL2_32BIT_64BIT  0x2
> >  #define ID_AA64PFR0_EL1_64BIT_ONLY   0x1
> >  #define ID_AA64PFR0_EL1_32BIT_64BIT  0x2
> >  #define ID_AA64PFR0_EL0_64BIT_ONLY   0x1
>
> Maybe just consolidate all of these into two definitions:
>
>   #define ID_AA64PFR0_ELx_64BIT_ONLY   0x1
>   #define ID_AA64PFR0_ELx_32BIT_64BIT  0x2

Will do.

Cheers,
/fuad

> ?
>
> Will

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v2 07/13] KVM: arm64: Add config register bit definitions
  2021-07-01 13:33   ` Will Deacon
@ 2021-07-01 14:52     ` Fuad Tabba
  0 siblings, 0 replies; 32+ messages in thread
From: Fuad Tabba @ 2021-07-01 14:52 UTC (permalink / raw)
  To: Will Deacon
  Cc: kvmarm, maz, james.morse, alexandru.elisei, suzuki.poulose,
	mark.rutland, christoffer.dall, pbonzini, drjones, qperret, kvm,
	linux-arm-kernel, kernel-team

Hi Will,

On Thu, Jul 1, 2021 at 2:33 PM Will Deacon <will@kernel.org> wrote:
>
> On Tue, Jun 15, 2021 at 02:39:44PM +0100, Fuad Tabba wrote:
> > Add hardware configuration register bit definitions for HCR_EL2
> > and MDCR_EL2. Future patches toggle these hyp configuration
> > register bits to trap on certain accesses.
> >
> > No functional change intended.
> >
> > Signed-off-by: Fuad Tabba <tabba@google.com>
> > ---
> >  arch/arm64/include/asm/kvm_arm.h | 21 +++++++++++++++++++++
> >  1 file changed, 21 insertions(+)
> >
> > diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
> > index bee1ba6773fb..a78090071f1f 100644
> > --- a/arch/arm64/include/asm/kvm_arm.h
> > +++ b/arch/arm64/include/asm/kvm_arm.h
> > @@ -12,7 +12,11 @@
> >  #include <asm/types.h>
> >
> >  /* Hyp Configuration Register (HCR) bits */
> > +#define HCR_TID5     (UL(1) << 58)
> > +#define HCR_DCT              (UL(1) << 57)
> >  #define HCR_ATA              (UL(1) << 56)
> > +#define HCR_AMVOFFEN (UL(1) << 51)
> > +#define HCR_FIEN     (UL(1) << 47)
> >  #define HCR_FWB              (UL(1) << 46)
> >  #define HCR_API              (UL(1) << 41)
> >  #define HCR_APK              (UL(1) << 40)
> > @@ -55,6 +59,7 @@
> >  #define HCR_PTW              (UL(1) << 2)
> >  #define HCR_SWIO     (UL(1) << 1)
> >  #define HCR_VM               (UL(1) << 0)
> > +#define HCR_RES0     ((UL(1) << 48) | (UL(1) << 39))
> >
> >  /*
> >   * The bits we set in HCR:
> > @@ -276,11 +281,21 @@
> >  #define CPTR_EL2_TZ  (1 << 8)
> >  #define CPTR_NVHE_EL2_RES1   0x000032ff /* known RES1 bits in CPTR_EL2 (nVHE) */
> >  #define CPTR_EL2_DEFAULT     CPTR_NVHE_EL2_RES1
> > +#define CPTR_NVHE_EL2_RES0   (GENMASK_ULL(63, 32) |  \
> > +                              GENMASK_ULL(29, 21) |  \
> > +                              GENMASK_ULL(19, 14) |  \
> > +                              (UL(1) << 11))
> >
> >  /* Hyp Debug Configuration Register bits */
> >  #define MDCR_EL2_E2TB_MASK   (UL(0x3))
> >  #define MDCR_EL2_E2TB_SHIFT  (UL(24))
> > +#define MDCR_EL2_HPMFZS              (UL(1) << 36)
> > +#define MDCR_EL2_HPMFZO              (UL(1) << 29)
> > +#define MDCR_EL2_MTPME               (UL(1) << 28)
> > +#define MDCR_EL2_TDCC                (UL(1) << 27)
> > +#define MDCR_EL2_HCCD                (UL(1) << 23)
> >  #define MDCR_EL2_TTRF                (UL(1) << 19)
> > +#define MDCR_EL2_HPMD                (UL(1) << 17)
> >  #define MDCR_EL2_TPMS                (UL(1) << 14)
> >  #define MDCR_EL2_E2PB_MASK   (UL(0x3))
> >  #define MDCR_EL2_E2PB_SHIFT  (UL(12))
> > @@ -292,6 +307,12 @@
> >  #define MDCR_EL2_TPM         (UL(1) << 6)
> >  #define MDCR_EL2_TPMCR               (UL(1) << 5)
> >  #define MDCR_EL2_HPMN_MASK   (UL(0x1F))
> > +#define MDCR_EL2_RES0                (GENMASK_ULL(63, 37) |  \
> > +                              GENMASK_ULL(35, 30) |  \
> > +                              GENMASK_ULL(25, 24) |  \
> > +                              GENMASK_ULL(22, 20) |  \
> > +                              (UL(1) << 18) |        \
> > +                              GENMASK_ULL(16, 15))
>
> There's an inconsistent mix of ULL and UL here. Given we're on arm64,
> maybe just use GENMASK() and BIT() for these RES0 regions?

The reason I use GENMASK_ULL instead of GENMASK, and UL()<< instead of
BIT is to remain consistent with the rest of this file. It would
definitely be clearer here, as you point out. I'll fix it.

> Anyway, the bit positions all look fine. You're missing HLP in bit 26,
> but I guess that's not something you care about?

I don't need that bit. I could add it for completeness, but there are
a few others that aren't here either...

Cheers,
/fuad

> Will

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v2 08/13] KVM: arm64: Guest exit handlers for nVHE hyp
  2021-07-01 13:48   ` Will Deacon
@ 2021-07-01 14:58     ` Fuad Tabba
  0 siblings, 0 replies; 32+ messages in thread
From: Fuad Tabba @ 2021-07-01 14:58 UTC (permalink / raw)
  To: Will Deacon
  Cc: kvmarm, maz, james.morse, alexandru.elisei, suzuki.poulose,
	mark.rutland, christoffer.dall, pbonzini, drjones, qperret, kvm,
	linux-arm-kernel, kernel-team

Hi Will,

On Thu, Jul 1, 2021 at 2:48 PM Will Deacon <will@kernel.org> wrote:
>
> On Tue, Jun 15, 2021 at 02:39:45PM +0100, Fuad Tabba wrote:
> > Add an array of pointers to handlers for various trap reasons in
> > nVHE code.
> >
> > The current code selects how to fixup a guest on exit based on a
> > series of if/else statements. Future patches will also require
> > different handling for guest exists. Create an array of handlers
> > to consolidate them.
> >
> > No functional change intended as the array isn't populated yet.
> >
> > Signed-off-by: Fuad Tabba <tabba@google.com>
> > ---
> >  arch/arm64/kvm/hyp/include/hyp/switch.h | 19 ++++++++++++++
> >  arch/arm64/kvm/hyp/nvhe/switch.c        | 35 +++++++++++++++++++++++++
> >  2 files changed, 54 insertions(+)
> >
> > diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
> > index e4a2f295a394..f5d3d1da0aec 100644
> > --- a/arch/arm64/kvm/hyp/include/hyp/switch.h
> > +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
> > @@ -405,6 +405,18 @@ static inline bool __hyp_handle_ptrauth(struct kvm_vcpu *vcpu)
> >       return true;
> >  }
> >
> > +typedef int (*exit_handle_fn)(struct kvm_vcpu *);
> > +
> > +exit_handle_fn kvm_get_nvhe_exit_handler(struct kvm_vcpu *vcpu);
> > +
> > +static exit_handle_fn kvm_get_hyp_exit_handler(struct kvm_vcpu *vcpu)
> > +{
> > +     if (is_nvhe_hyp_code())
> > +             return kvm_get_nvhe_exit_handler(vcpu);
> > +     else
> > +             return NULL;
> > +}
>
> nit: might be a bit tidier with a ternary if (?:).

Sure thing.

Thanks,
/fuad

> But either way:
>
> Acked-by: Will Deacon <will@kernel.org>
>
> Will

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v2 09/13] KVM: arm64: Add trap handlers for protected VMs
  2021-07-01 14:08   ` Will Deacon
@ 2021-07-14 20:01     ` Andrew Jones
  0 siblings, 0 replies; 32+ messages in thread
From: Andrew Jones @ 2021-07-14 20:01 UTC (permalink / raw)
  To: Will Deacon
  Cc: Fuad Tabba, kvmarm, maz, james.morse, alexandru.elisei,
	suzuki.poulose, mark.rutland, christoffer.dall, pbonzini,
	qperret, kvm, linux-arm-kernel, kernel-team

On Thu, Jul 01, 2021 at 03:08:22PM +0100, Will Deacon wrote:
> On Tue, Jun 15, 2021 at 02:39:46PM +0100, Fuad Tabba wrote:
> > Add trap handlers for protected VMs. These are mainly for Sys64
> > and debug traps.
> 
> I think one big thing missing from this patch is some rationale around
> which features are advertised and which are not. Further, when traps
> are enabled later on, there doesn't seem to be one place which drives the
> logic, so it's quite hard to reason about.
> 
> So I think we need both some documentation to describe the architectural
> environment provided to protected VMs, but also a way to couple the logic
> which says "We hide this feature from the ID registers because of foo"
> with the logic that says "And here is the control bit to trap this feature".

I think it would be better to have documentation that says "We expose this
feature because foo". If the feature doesn't have any rationale to be
exposed, then it's just not. It may also make sense to document features
that should never be exposed, if there are features like that, in order to
ensure nobody comes along and exposes them later.

Thanks,
drew


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 32+ messages in thread

end of thread, other threads:[~2021-07-14 23:28 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-15 13:39 [PATCH v2 00/13] KVM: arm64: Fixed features for protected VMs Fuad Tabba
2021-06-15 13:39 ` [PATCH v2 01/13] KVM: arm64: Remove trailing whitespace in comments Fuad Tabba
2021-07-01 12:55   ` Will Deacon
2021-07-01 13:24     ` Fuad Tabba
2021-06-15 13:39 ` [PATCH v2 02/13] KVM: arm64: MDCR_EL2 is a 64-bit register Fuad Tabba
2021-07-01 12:53   ` Will Deacon
2021-07-01 13:24     ` Fuad Tabba
2021-06-15 13:39 ` [PATCH v2 03/13] KVM: arm64: Fix names of config register fields Fuad Tabba
2021-07-01 13:01   ` Will Deacon
2021-07-01 13:44     ` Fuad Tabba
2021-06-15 13:39 ` [PATCH v2 04/13] KVM: arm64: Refactor sys_regs.h,c for nVHE reuse Fuad Tabba
2021-07-01 13:09   ` [PATCH v2 04/13] KVM: arm64: Refactor sys_regs.h, c " Will Deacon
2021-07-01 14:04     ` Fuad Tabba
2021-06-15 13:39 ` [PATCH v2 05/13] KVM: arm64: Restore mdcr_el2 from vcpu Fuad Tabba
2021-07-01 13:17   ` Will Deacon
2021-07-01 14:05     ` Fuad Tabba
2021-06-15 13:39 ` [PATCH v2 06/13] KVM: arm64: Add feature register flag definitions Fuad Tabba
2021-07-01 13:22   ` Will Deacon
2021-07-01 14:31     ` Fuad Tabba
2021-06-15 13:39 ` [PATCH v2 07/13] KVM: arm64: Add config register bit definitions Fuad Tabba
2021-07-01 13:33   ` Will Deacon
2021-07-01 14:52     ` Fuad Tabba
2021-06-15 13:39 ` [PATCH v2 08/13] KVM: arm64: Guest exit handlers for nVHE hyp Fuad Tabba
2021-07-01 13:48   ` Will Deacon
2021-07-01 14:58     ` Fuad Tabba
2021-06-15 13:39 ` [PATCH v2 09/13] KVM: arm64: Add trap handlers for protected VMs Fuad Tabba
2021-07-01 14:08   ` Will Deacon
2021-07-14 20:01     ` Andrew Jones
2021-06-15 13:39 ` [PATCH v2 10/13] KVM: arm64: Move sanitized copies of CPU features Fuad Tabba
2021-06-15 13:39 ` [PATCH v2 11/13] KVM: arm64: Trap access to pVM restricted features Fuad Tabba
2021-06-15 13:39 ` [PATCH v2 12/13] KVM: arm64: Handle protected guests at 32 bits Fuad Tabba
2021-06-15 13:39 ` [PATCH v2 13/13] KVM: arm64: Check vcpu features at pVM creation Fuad Tabba

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).