* [PATCH v2 0/3] KVM: arm64: Control visibility of S1PIE related sysregs to userspace
@ 2024-08-21 23:35 Mark Brown
2024-08-21 23:35 ` [PATCH v2 1/3] KVM: arm64: Define helper for EL2 registers with custom visibility Mark Brown
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Mark Brown @ 2024-08-21 23:35 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, James Morse, Suzuki K Poulose,
Catalin Marinas, Will Deacon, Joey Gouly
Cc: linux-arm-kernel, kvmarm, linux-kernel, Mark Brown,
20240813144738.2048302-1-maz
While looking at the KVM system register code I noticed that we do not
have visibility operations for TCR2 or the S1PIE registers, I may be
missing some reason why they are not required but in case I'm not I
figured the most direct way to ask was to propose adding the operations.
This is based on Marc Zyngier's series:
https://lore.kernel.org/all/20240813144738.2048302-4-maz@kernel.org/
Signed-off-by: Mark Brown <broonie@kernel.org>
---
Changes in v2:
- Rebase on top of Marc's series adding EL2 S1PIE support.
- Handle EL2 versions of registers.
- Link to v1: https://lore.kernel.org/r/20240821-kvm-arm64-hide-pie-regs-v1-0-08cb3c79cb57@kernel.org
---
Mark Brown (3):
KVM: arm64: Define helper for EL2 registers with custom visibility
KVM: arm64: Hide TCR2_EL1 from userspace when disabled for guests
KVM: arm64: Hide S1PIE registers from userspace when disabled for guests
arch/arm64/include/asm/kvm_host.h | 6 +++
arch/arm64/kvm/sys_regs.c | 77 ++++++++++++++++++++++++++++++++++-----
2 files changed, 73 insertions(+), 10 deletions(-)
---
base-commit: 6998fa93fbbf237b518bf921f8c21e71514e5aed
change-id: 20240820-kvm-arm64-hide-pie-regs-2236f70703ab
prerequisite-message-id: 20240813144738.2048302-1-maz@kernel.org
prerequisite-patch-id: 7e65cb84e9a1ac67ec6174bc2c8e6f8a3cd7a2b8
prerequisite-patch-id: 0e79993ba049d517f676a461104379fa0c34f963
prerequisite-patch-id: 075ad9eb54d31d099a9e30ad914e29e927156ee9
prerequisite-patch-id: d61f24087c8e4c6c650969ed2db55681aa0a5562
prerequisite-patch-id: abb476d6ac155c9060656eb383e4f42cf3465c10
prerequisite-patch-id: f0cace2aabf2385d74514a3733ddbbdb1e6d575d
prerequisite-patch-id: 62ce04c9f054610b9a992a2c65d30c6cb0a0c23b
prerequisite-patch-id: efc96c4b2c999e86de8e8cbd2e5a66a3640ee187
prerequisite-patch-id: df53b3c1bc3339de587651f1f884f2bcad11a36f
prerequisite-patch-id: 58095341c1baa606c91dac8b2fc1446f5d5178de
Best regards,
--
Mark Brown <broonie@kernel.org>
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 1/3] KVM: arm64: Define helper for EL2 registers with custom visibility
2024-08-21 23:35 [PATCH v2 0/3] KVM: arm64: Control visibility of S1PIE related sysregs to userspace Mark Brown
@ 2024-08-21 23:35 ` Mark Brown
2024-08-21 23:35 ` [PATCH v2 2/3] KVM: arm64: Hide TCR2_EL1 from userspace when disabled for guests Mark Brown
2024-08-21 23:35 ` [PATCH v2 3/3] KVM: arm64: Hide S1PIE registers " Mark Brown
2 siblings, 0 replies; 5+ messages in thread
From: Mark Brown @ 2024-08-21 23:35 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, James Morse, Suzuki K Poulose,
Catalin Marinas, Will Deacon, Joey Gouly
Cc: linux-arm-kernel, kvmarm, linux-kernel, Mark Brown,
20240813144738.2048302-1-maz
In preparation for adding more visibility filtering for EL2 registers add
a helper macro like EL2_REG() which allows specification of a custom
visibility operation.
Signed-off-by: Mark Brown <broonie@kernel.org>
---
arch/arm64/kvm/sys_regs.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index d0b4509e59cb..1af15140e067 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -2136,6 +2136,15 @@ static bool bad_redir_trap(struct kvm_vcpu *vcpu,
.val = v, \
}
+#define EL2_REG_FILTERED(name, acc, rst, v, filter) { \
+ SYS_DESC(SYS_##name), \
+ .access = acc, \
+ .reset = rst, \
+ .reg = name, \
+ .visibility = filter, \
+ .val = v, \
+}
+
#define EL2_REG_VNCR(name, rst, v) EL2_REG(name, bad_vncr_trap, rst, v)
#define EL2_REG_REDIR(name, rst, v) EL2_REG(name, bad_redir_trap, rst, v)
@@ -2803,8 +2812,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
EL2_REG_VNCR(HFGITR_EL2, reset_val, 0),
EL2_REG_VNCR(HACR_EL2, reset_val, 0),
- { SYS_DESC(SYS_ZCR_EL2), .access = access_zcr_el2, .reset = reset_val,
- .visibility = sve_el2_visibility, .reg = ZCR_EL2 },
+ EL2_REG_FILTERED(ZCR_EL2, access_zcr_el2, reset_val, 0,
+ sve_el2_visibility),
EL2_REG_VNCR(HCRX_EL2, reset_val, 0),
--
2.39.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v2 2/3] KVM: arm64: Hide TCR2_EL1 from userspace when disabled for guests
2024-08-21 23:35 [PATCH v2 0/3] KVM: arm64: Control visibility of S1PIE related sysregs to userspace Mark Brown
2024-08-21 23:35 ` [PATCH v2 1/3] KVM: arm64: Define helper for EL2 registers with custom visibility Mark Brown
@ 2024-08-21 23:35 ` Mark Brown
2024-09-02 19:12 ` Marc Zyngier
2024-08-21 23:35 ` [PATCH v2 3/3] KVM: arm64: Hide S1PIE registers " Mark Brown
2 siblings, 1 reply; 5+ messages in thread
From: Mark Brown @ 2024-08-21 23:35 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, James Morse, Suzuki K Poulose,
Catalin Marinas, Will Deacon, Joey Gouly
Cc: linux-arm-kernel, kvmarm, linux-kernel, Mark Brown,
20240813144738.2048302-1-maz
When the guest does not support FEAT_TCR2 we should not allow any access
to it in order to ensure that we do not create spurious issues with guest
migration. Add a visibility operation for it.
Fixes: fbff56068232 ("KVM: arm64: Save/restore TCR2_EL1")
Signed-off-by: Mark Brown <broonie@kernel.org>
---
arch/arm64/include/asm/kvm_host.h | 3 +++
arch/arm64/kvm/sys_regs.c | 29 ++++++++++++++++++++++++++---
2 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index ab4c675b491d..7889e5f4009f 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -1476,4 +1476,7 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val);
(pa + pi + pa3) == 1; \
})
+#define kvm_has_tcr2(k) \
+ (kvm_has_feat((k), ID_AA64MMFR3_EL1, TCRX, IMP))
+
#endif /* __ARM64_KVM_HOST_H__ */
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 1af15140e067..6d5f43781042 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -2319,6 +2319,27 @@ static bool access_zcr_el2(struct kvm_vcpu *vcpu,
return true;
}
+static unsigned int tcr2_visibility(const struct kvm_vcpu *vcpu,
+ const struct sys_reg_desc *rd)
+{
+ if (kvm_has_tcr2(vcpu->kvm))
+ return 0;
+
+ return REG_HIDDEN;
+}
+
+static unsigned int tcr2_el2_visibility(const struct kvm_vcpu *vcpu,
+ const struct sys_reg_desc *rd)
+{
+ unsigned int r;
+
+ r = el2_visibility(vcpu, rd);
+ if (r)
+ return r;
+
+ return tcr2_visibility(vcpu, rd);
+}
+
/*
* Architected system registers.
* Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2
@@ -2503,7 +2524,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
{ SYS_DESC(SYS_TTBR0_EL1), access_vm_reg, reset_unknown, TTBR0_EL1 },
{ SYS_DESC(SYS_TTBR1_EL1), access_vm_reg, reset_unknown, TTBR1_EL1 },
{ SYS_DESC(SYS_TCR_EL1), access_vm_reg, reset_val, TCR_EL1, 0 },
- { SYS_DESC(SYS_TCR2_EL1), access_vm_reg, reset_val, TCR2_EL1, 0 },
+ { SYS_DESC(SYS_TCR2_EL1), access_vm_reg, reset_val, TCR2_EL1, 0,
+ .visibility = tcr2_visibility },
PTRAUTH_KEY(APIA),
PTRAUTH_KEY(APIB),
@@ -2820,7 +2842,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
EL2_REG(TTBR0_EL2, access_rw, reset_val, 0),
EL2_REG(TTBR1_EL2, access_rw, reset_val, 0),
EL2_REG(TCR_EL2, access_rw, reset_val, TCR_EL2_RES1),
- EL2_REG(TCR2_EL2, access_tcr2_el2, reset_val, TCR2_EL2_RES1),
+ EL2_REG_FILTERED(TCR2_EL2, access_tcr2_el2, reset_val, TCR2_EL2_RES1,
+ tcr2_el2_visibility),
EL2_REG_VNCR(VTTBR_EL2, reset_val, 0),
EL2_REG_VNCR(VTCR_EL2, reset_val, 0),
@@ -4626,7 +4649,7 @@ void kvm_calculate_traps(struct kvm_vcpu *vcpu)
if (kvm_has_feat(kvm, ID_AA64ISAR2_EL1, MOPS, IMP))
vcpu->arch.hcrx_el2 |= (HCRX_EL2_MSCEn | HCRX_EL2_MCE2);
- if (kvm_has_feat(kvm, ID_AA64MMFR3_EL1, TCRX, IMP))
+ if (kvm_has_tcr2(kvm))
vcpu->arch.hcrx_el2 |= HCRX_EL2_TCR2En;
}
--
2.39.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v2 3/3] KVM: arm64: Hide S1PIE registers from userspace when disabled for guests
2024-08-21 23:35 [PATCH v2 0/3] KVM: arm64: Control visibility of S1PIE related sysregs to userspace Mark Brown
2024-08-21 23:35 ` [PATCH v2 1/3] KVM: arm64: Define helper for EL2 registers with custom visibility Mark Brown
2024-08-21 23:35 ` [PATCH v2 2/3] KVM: arm64: Hide TCR2_EL1 from userspace when disabled for guests Mark Brown
@ 2024-08-21 23:35 ` Mark Brown
2 siblings, 0 replies; 5+ messages in thread
From: Mark Brown @ 2024-08-21 23:35 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, James Morse, Suzuki K Poulose,
Catalin Marinas, Will Deacon, Joey Gouly
Cc: linux-arm-kernel, kvmarm, linux-kernel, Mark Brown,
20240813144738.2048302-1-maz
When the guest does not support S1PIE we should not allow any access
to the system registers it adds in order to ensure that we do not create
spurious issues with guest migration. Add a visibility operation for these
registers.
Fixes: 86f9de9db178 ("KVM: arm64: Save/restore PIE registers")
Signed-off-by: Mark Brown <broonie@kernel.org>
---
arch/arm64/include/asm/kvm_host.h | 3 +++
arch/arm64/kvm/sys_regs.c | 35 ++++++++++++++++++++++++++++++-----
2 files changed, 33 insertions(+), 5 deletions(-)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 7889e5f4009f..fd161d41df52 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -1479,4 +1479,7 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val);
#define kvm_has_tcr2(k) \
(kvm_has_feat((k), ID_AA64MMFR3_EL1, TCRX, IMP))
+#define kvm_has_s1pie(k) \
+ (kvm_has_feat((k), ID_AA64MMFR3_EL1, S1PIE, IMP))
+
#endif /* __ARM64_KVM_HOST_H__ */
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 6d5f43781042..3824f6d13bf6 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -2340,6 +2340,27 @@ static unsigned int tcr2_el2_visibility(const struct kvm_vcpu *vcpu,
return tcr2_visibility(vcpu, rd);
}
+static unsigned int s1pie_visibility(const struct kvm_vcpu *vcpu,
+ const struct sys_reg_desc *rd)
+{
+ if (kvm_has_s1pie(vcpu->kvm))
+ return 0;
+
+ return REG_HIDDEN;
+}
+
+static unsigned int s1pie_el2_visibility(const struct kvm_vcpu *vcpu,
+ const struct sys_reg_desc *rd)
+{
+ unsigned int r;
+
+ r = el2_visibility(vcpu, rd);
+ if (r)
+ return r;
+
+ return s1pie_visibility(vcpu, rd);
+}
+
/*
* Architected system registers.
* Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2
@@ -2577,8 +2598,10 @@ static const struct sys_reg_desc sys_reg_descs[] = {
{ SYS_DESC(SYS_PMMIR_EL1), trap_raz_wi },
{ SYS_DESC(SYS_MAIR_EL1), access_vm_reg, reset_unknown, MAIR_EL1 },
- { SYS_DESC(SYS_PIRE0_EL1), NULL, reset_unknown, PIRE0_EL1 },
- { SYS_DESC(SYS_PIR_EL1), NULL, reset_unknown, PIR_EL1 },
+ { SYS_DESC(SYS_PIRE0_EL1), NULL, reset_unknown, PIRE0_EL1,
+ .visibility = s1pie_visibility },
+ { SYS_DESC(SYS_PIR_EL1), NULL, reset_unknown, PIR_EL1,
+ .visibility = s1pie_visibility },
{ SYS_DESC(SYS_AMAIR_EL1), access_vm_reg, reset_amair_el1, AMAIR_EL1 },
{ SYS_DESC(SYS_LORSA_EL1), trap_loregion },
@@ -2875,8 +2898,10 @@ static const struct sys_reg_desc sys_reg_descs[] = {
EL2_REG(HPFAR_EL2, access_rw, reset_val, 0),
EL2_REG(MAIR_EL2, access_rw, reset_val, 0),
- EL2_REG(PIRE0_EL2, check_s1pie_access_rw, reset_val, 0),
- EL2_REG(PIR_EL2, check_s1pie_access_rw, reset_val, 0),
+ EL2_REG_FILTERED(PIRE0_EL2, check_s1pie_access_rw, reset_val, 0,
+ s1pie_el2_visibility),
+ EL2_REG_FILTERED(PIR_EL2, check_s1pie_access_rw, reset_val, 0,
+ s1pie_el2_visibility),
EL2_REG(AMAIR_EL2, access_rw, reset_val, 0),
EL2_REG(VBAR_EL2, access_rw, reset_val, 0),
@@ -4691,7 +4716,7 @@ void kvm_calculate_traps(struct kvm_vcpu *vcpu)
HFGITR_EL2_TLBIRVAAE1OS |
HFGITR_EL2_TLBIRVAE1OS);
- if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, S1PIE, IMP))
+ if (!kvm_has_s1pie(kvm))
kvm->arch.fgu[HFGxTR_GROUP] |= (HFGxTR_EL2_nPIRE0_EL1 |
HFGxTR_EL2_nPIR_EL1);
--
2.39.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v2 2/3] KVM: arm64: Hide TCR2_EL1 from userspace when disabled for guests
2024-08-21 23:35 ` [PATCH v2 2/3] KVM: arm64: Hide TCR2_EL1 from userspace when disabled for guests Mark Brown
@ 2024-09-02 19:12 ` Marc Zyngier
0 siblings, 0 replies; 5+ messages in thread
From: Marc Zyngier @ 2024-09-02 19:12 UTC (permalink / raw)
To: Mark Brown
Cc: Oliver Upton, James Morse, Suzuki K Poulose, Catalin Marinas,
Will Deacon, Joey Gouly, linux-arm-kernel, kvmarm, linux-kernel,
20240813144738.2048302-1-maz
On Thu, 22 Aug 2024 00:35:37 +0100,
Mark Brown <broonie@kernel.org> wrote:
>
> When the guest does not support FEAT_TCR2 we should not allow any access
> to it in order to ensure that we do not create spurious issues with guest
> migration. Add a visibility operation for it.
>
> Fixes: fbff56068232 ("KVM: arm64: Save/restore TCR2_EL1")
> Signed-off-by: Mark Brown <broonie@kernel.org>
> ---
> arch/arm64/include/asm/kvm_host.h | 3 +++
> arch/arm64/kvm/sys_regs.c | 29 ++++++++++++++++++++++++++---
> 2 files changed, 29 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index ab4c675b491d..7889e5f4009f 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -1476,4 +1476,7 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val);
> (pa + pi + pa3) == 1; \
> })
>
> +#define kvm_has_tcr2(k) \
> + (kvm_has_feat((k), ID_AA64MMFR3_EL1, TCRX, IMP))
> +
> #endif /* __ARM64_KVM_HOST_H__ */
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 1af15140e067..6d5f43781042 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -2319,6 +2319,27 @@ static bool access_zcr_el2(struct kvm_vcpu *vcpu,
> return true;
> }
>
> +static unsigned int tcr2_visibility(const struct kvm_vcpu *vcpu,
> + const struct sys_reg_desc *rd)
> +{
> + if (kvm_has_tcr2(vcpu->kvm))
> + return 0;
> +
> + return REG_HIDDEN;
> +}
> +
> +static unsigned int tcr2_el2_visibility(const struct kvm_vcpu *vcpu,
> + const struct sys_reg_desc *rd)
> +{
> + unsigned int r;
> +
> + r = el2_visibility(vcpu, rd);
> + if (r)
> + return r;
> +
> + return tcr2_visibility(vcpu, rd);
> +}
> +
> /*
> * Architected system registers.
> * Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2
> @@ -2503,7 +2524,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
> { SYS_DESC(SYS_TTBR0_EL1), access_vm_reg, reset_unknown, TTBR0_EL1 },
> { SYS_DESC(SYS_TTBR1_EL1), access_vm_reg, reset_unknown, TTBR1_EL1 },
> { SYS_DESC(SYS_TCR_EL1), access_vm_reg, reset_val, TCR_EL1, 0 },
> - { SYS_DESC(SYS_TCR2_EL1), access_vm_reg, reset_val, TCR2_EL1, 0 },
> + { SYS_DESC(SYS_TCR2_EL1), access_vm_reg, reset_val, TCR2_EL1, 0,
> + .visibility = tcr2_visibility },
With this, we should be able to simplify the accessor, shouldn't we?
>
> PTRAUTH_KEY(APIA),
> PTRAUTH_KEY(APIB),
> @@ -2820,7 +2842,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
> EL2_REG(TTBR0_EL2, access_rw, reset_val, 0),
> EL2_REG(TTBR1_EL2, access_rw, reset_val, 0),
> EL2_REG(TCR_EL2, access_rw, reset_val, TCR_EL2_RES1),
> - EL2_REG(TCR2_EL2, access_tcr2_el2, reset_val, TCR2_EL2_RES1),
> + EL2_REG_FILTERED(TCR2_EL2, access_tcr2_el2, reset_val, TCR2_EL2_RES1,
> + tcr2_el2_visibility),
Same thing here.
Thanks,
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2024-09-02 19:14 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-08-21 23:35 [PATCH v2 0/3] KVM: arm64: Control visibility of S1PIE related sysregs to userspace Mark Brown
2024-08-21 23:35 ` [PATCH v2 1/3] KVM: arm64: Define helper for EL2 registers with custom visibility Mark Brown
2024-08-21 23:35 ` [PATCH v2 2/3] KVM: arm64: Hide TCR2_EL1 from userspace when disabled for guests Mark Brown
2024-09-02 19:12 ` Marc Zyngier
2024-08-21 23:35 ` [PATCH v2 3/3] KVM: arm64: Hide S1PIE registers " Mark Brown
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).