KVM/arm64 fixes for 6.16, take #

- Remove the last leftovers from the ill-fated FPSIMD host state
   mapping at EL2 stage-1
 
 - Fix unexpected advertisement to the guest of unimplemented S2 base
   granule sizes
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEn9UcU+C1Yxj9lZw9I9DQutE9ekMFAmhmU4cACgkQI9DQutE9
 ekNxIA//WhMHtHouX8i9lZ1Zt8GHmjVRzPEiZYaTDCjF9R1whqP8c91DMuzSreHE
 eQnsGLqVQYH8QM3f4hDYZuJOXl1kBcSQyx/2KsZ4jsI5Wy35k+vi1VJM5sIANh2p
 i4u0hQGJ/8IOvSRzrG2ps4vuEp9snBnuRWw0WzmCxHd6rVN9SdTCyOH1tt39vDtn
 S18ArW6QcoLjJtY6tSIYU/iRVl2yg5yVmM+J+heN4ugkYyswvdYYJo+zAPfiwTkr
 N2uKKiMTSM95vubvON3htasyaWTcDbxxk6wzSxW0+iBGbO/t7zx/0HgvXk+kH/kM
 y/Hn0fRX1JcxAKDp6XXUKiBQF+TT/XCiCq7YcY6FN0zYHOzR1F5gwfovcgTWKmk6
 bA3ki+1Mn2TLQRu28UmcVLEJX+LRigSmF4cw/F5DNELUboyqc304tz5f4Vyyutus
 KEK2z248VcSveU6KRhh/EsApofnpjFaN1NzQ/E7KKArYmAXHu7C/nz5+YZWWvK8/
 gpy3RUIqWVd1muUHuMKVu13s4/Z3X1zeNnwBlqaNbKpqXoLMticj3IWEAxs+RZ6z
 3ekvlxrPwdCelFpPs2fnktVlAU/iC4N0N9l2rXMOxExLTJsjGg7ZmzOEt1inKjWp
 IFBlDfyVGIWnE/D9NfHYJscXPTfKH1vUgoo8epT/AWwI6k4yPl0=
 =H+oh
 -----END PGP SIGNATURE-----

Merge tag 'kvmarm-fixes-6.16-5' of https://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD

KVM/arm64 fixes for 6.16, take #

- Remove the last leftovers from the ill-fated FPSIMD host state
  mapping at EL2 stage-1

- Fix unexpected advertisement to the guest of unimplemented S2 base
  granule sizes
This commit is contained in:
Paolo Bonzini 2025-07-08 10:48:21 -04:00
commit 7e7a7bf212
4 changed files with 23 additions and 34 deletions

View File

@ -1480,7 +1480,6 @@ int kvm_vm_ioctl_get_reg_writable_masks(struct kvm *kvm,
struct reg_mask_range *range);
/* Guest/host FPSIMD coordination helpers */
int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu);
void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu);
void kvm_arch_vcpu_ctxflush_fp(struct kvm_vcpu *vcpu);
void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu);

View File

@ -825,10 +825,6 @@ int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
if (!kvm_arm_vcpu_is_finalized(vcpu))
return -EPERM;
ret = kvm_arch_vcpu_run_map_fp(vcpu);
if (ret)
return ret;
if (likely(vcpu_has_run_once(vcpu)))
return 0;

View File

@ -14,32 +14,6 @@
#include <asm/kvm_mmu.h>
#include <asm/sysreg.h>
/*
* Called on entry to KVM_RUN unless this vcpu previously ran at least
* once and the most recent prior KVM_RUN for this vcpu was called from
* the same task as current (highly likely).
*
* This is guaranteed to execute before kvm_arch_vcpu_load_fp(vcpu),
* such that on entering hyp the relevant parts of current are already
* mapped.
*/
int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu)
{
struct user_fpsimd_state *fpsimd = &current->thread.uw.fpsimd_state;
int ret;
/* pKVM has its own tracking of the host fpsimd state. */
if (is_protected_kvm_enabled())
return 0;
/* Make sure the host task fpsimd state is visible to hyp: */
ret = kvm_share_hyp(fpsimd, fpsimd + 1);
if (ret)
return ret;
return 0;
}
/*
* Prepare vcpu for saving the host's FPSIMD state and loading the guest's.
* The actual loading is done by the FPSIMD access trap taken to hyp.

View File

@ -1402,6 +1402,21 @@ static void kvm_map_l1_vncr(struct kvm_vcpu *vcpu)
}
}
#define has_tgran_2(__r, __sz) \
({ \
u64 _s1, _s2, _mmfr0 = __r; \
\
_s2 = SYS_FIELD_GET(ID_AA64MMFR0_EL1, \
TGRAN##__sz##_2, _mmfr0); \
\
_s1 = SYS_FIELD_GET(ID_AA64MMFR0_EL1, \
TGRAN##__sz, _mmfr0); \
\
((_s2 != ID_AA64MMFR0_EL1_TGRAN##__sz##_2_NI && \
_s2 != ID_AA64MMFR0_EL1_TGRAN##__sz##_2_TGRAN##__sz) || \
(_s2 == ID_AA64MMFR0_EL1_TGRAN##__sz##_2_TGRAN##__sz && \
_s1 != ID_AA64MMFR0_EL1_TGRAN##__sz##_NI)); \
})
/*
* Our emulated CPU doesn't support all the possible features. For the
* sake of simplicity (and probably mental sanity), wipe out a number
@ -1411,6 +1426,8 @@ static void kvm_map_l1_vncr(struct kvm_vcpu *vcpu)
*/
u64 limit_nv_id_reg(struct kvm *kvm, u32 reg, u64 val)
{
u64 orig_val = val;
switch (reg) {
case SYS_ID_AA64ISAR0_EL1:
/* Support everything but TME */
@ -1480,13 +1497,16 @@ u64 limit_nv_id_reg(struct kvm *kvm, u32 reg, u64 val)
*/
switch (PAGE_SIZE) {
case SZ_4K:
val |= SYS_FIELD_PREP_ENUM(ID_AA64MMFR0_EL1, TGRAN4_2, IMP);
if (has_tgran_2(orig_val, 4))
val |= SYS_FIELD_PREP_ENUM(ID_AA64MMFR0_EL1, TGRAN4_2, IMP);
fallthrough;
case SZ_16K:
val |= SYS_FIELD_PREP_ENUM(ID_AA64MMFR0_EL1, TGRAN16_2, IMP);
if (has_tgran_2(orig_val, 16))
val |= SYS_FIELD_PREP_ENUM(ID_AA64MMFR0_EL1, TGRAN16_2, IMP);
fallthrough;
case SZ_64K:
val |= SYS_FIELD_PREP_ENUM(ID_AA64MMFR0_EL1, TGRAN64_2, IMP);
if (has_tgran_2(orig_val, 64))
val |= SYS_FIELD_PREP_ENUM(ID_AA64MMFR0_EL1, TGRAN64_2, IMP);
break;
}