Skip to content

Commit c5bac1e

Browse files
Marc Zyngieroupton
authored andcommitted
KVM: arm64: Move existing feature disabling over to FGU infrastructure
We already trap a bunch of existing features for the purpose of disabling them (MAIR2, POR, ACCDATA, SME...). Let's move them over to our brand new FGU infrastructure. Reviewed-by: Joey Gouly <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Oliver Upton <[email protected]>
1 parent f5a5a40 commit c5bac1e

File tree

4 files changed

+36
-14
lines changed

4 files changed

+36
-14
lines changed

arch/arm64/include/asm/kvm_host.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,8 @@ struct kvm_arch {
297297
#define KVM_ARCH_FLAG_TIMER_PPIS_IMMUTABLE 6
298298
/* Initial ID reg values loaded */
299299
#define KVM_ARCH_FLAG_ID_REGS_INITIALIZED 7
300+
/* Fine-Grained UNDEF initialised */
301+
#define KVM_ARCH_FLAG_FGU_INITIALIZED 8
300302
unsigned long flags;
301303

302304
/* VM-wide vCPU feature set */
@@ -1107,6 +1109,8 @@ int __init populate_nv_trap_config(void);
11071109
bool lock_all_vcpus(struct kvm *kvm);
11081110
void unlock_all_vcpus(struct kvm *kvm);
11091111

1112+
void kvm_init_sysreg(struct kvm_vcpu *);
1113+
11101114
/* MMIO helpers */
11111115
void kvm_mmio_write_buf(void *buf, unsigned int len, unsigned long data);
11121116
unsigned long kvm_mmio_read_buf(const void *buf, unsigned int len);

arch/arm64/kvm/arm.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,12 @@ int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
675675
return ret;
676676
}
677677

678+
/*
679+
* This needs to happen after NV has imposed its own restrictions on
680+
* the feature set
681+
*/
682+
kvm_init_sysreg(vcpu);
683+
678684
ret = kvm_timer_enable(vcpu);
679685
if (ret)
680686
return ret;

arch/arm64/kvm/hyp/include/hyp/switch.h

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
157157
{
158158
struct kvm_cpu_context *hctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
159159
struct kvm *kvm = kern_hyp_va(vcpu->kvm);
160-
u64 r_clr = 0, w_clr = 0, r_set = 0, w_set = 0, tmp;
160+
u64 r_clr = 0, w_clr = 0, r_set = 0, w_set = 0;
161161
u64 r_val, w_val;
162162

163163
CHECK_FGT_MASKS(HFGRTR_EL2);
@@ -174,13 +174,6 @@ static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
174174
ctxt_sys_reg(hctxt, HFGRTR_EL2) = read_sysreg_s(SYS_HFGRTR_EL2);
175175
ctxt_sys_reg(hctxt, HFGWTR_EL2) = read_sysreg_s(SYS_HFGWTR_EL2);
176176

177-
if (cpus_have_final_cap(ARM64_SME)) {
178-
tmp = HFGxTR_EL2_nSMPRI_EL1_MASK | HFGxTR_EL2_nTPIDR2_EL0_MASK;
179-
180-
r_clr |= tmp;
181-
w_clr |= tmp;
182-
}
183-
184177
/*
185178
* Trap guest writes to TCR_EL1 to prevent it from enabling HA or HD.
186179
*/
@@ -195,15 +188,11 @@ static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
195188
compute_undef_clr_set(vcpu, kvm, HFGRTR_EL2, r_clr, r_set);
196189
compute_undef_clr_set(vcpu, kvm, HFGWTR_EL2, w_clr, w_set);
197190

198-
/* The default to trap everything not handled or supported in KVM. */
199-
tmp = HFGxTR_EL2_nAMAIR2_EL1 | HFGxTR_EL2_nMAIR2_EL1 | HFGxTR_EL2_nS2POR_EL1 |
200-
HFGxTR_EL2_nPOR_EL1 | HFGxTR_EL2_nPOR_EL0 | HFGxTR_EL2_nACCDATA_EL1;
201-
202-
r_val = __HFGRTR_EL2_nMASK & ~tmp;
191+
r_val = __HFGRTR_EL2_nMASK;
203192
r_val |= r_set;
204193
r_val &= ~r_clr;
205194

206-
w_val = __HFGWTR_EL2_nMASK & ~tmp;
195+
w_val = __HFGWTR_EL2_nMASK;
207196
w_val |= w_set;
208197
w_val &= ~w_clr;
209198

arch/arm64/kvm/sys_regs.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3942,6 +3942,29 @@ int kvm_vm_ioctl_get_reg_writable_masks(struct kvm *kvm, struct reg_mask_range *
39423942
return 0;
39433943
}
39443944

3945+
void kvm_init_sysreg(struct kvm_vcpu *vcpu)
3946+
{
3947+
struct kvm *kvm = vcpu->kvm;
3948+
3949+
mutex_lock(&kvm->arch.config_lock);
3950+
3951+
if (test_bit(KVM_ARCH_FLAG_FGU_INITIALIZED, &kvm->arch.flags))
3952+
goto out;
3953+
3954+
kvm->arch.fgu[HFGxTR_GROUP] = (HFGxTR_EL2_nAMAIR2_EL1 |
3955+
HFGxTR_EL2_nMAIR2_EL1 |
3956+
HFGxTR_EL2_nS2POR_EL1 |
3957+
HFGxTR_EL2_nPOR_EL1 |
3958+
HFGxTR_EL2_nPOR_EL0 |
3959+
HFGxTR_EL2_nACCDATA_EL1 |
3960+
HFGxTR_EL2_nSMPRI_EL1_MASK |
3961+
HFGxTR_EL2_nTPIDR2_EL0_MASK);
3962+
3963+
set_bit(KVM_ARCH_FLAG_FGU_INITIALIZED, &kvm->arch.flags);
3964+
out:
3965+
mutex_unlock(&kvm->arch.config_lock);
3966+
}
3967+
39453968
int __init kvm_sys_reg_table_init(void)
39463969
{
39473970
struct sys_reg_params params;

0 commit comments

Comments
 (0)