Skip to content

Commit 87f842c

Browse files
author
Marc Zyngier
committed
KVM: arm64: Add accessor for per-CPU state
In order to facilitate the introduction of new per-CPU state, add a new host_data_ptr() helped that hides some of the per-CPU verbosity, and make it easier to move that state around in the future. Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com> Signed-off-by: Marc Zyngier <maz@kernel.org>
1 parent 4cece76 commit 87f842c

10 files changed

Lines changed: 53 additions & 17 deletions

File tree

arch/arm64/include/asm/kvm_host.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,17 @@ struct kvm_cpu_context {
530530
u64 *vncr_array;
531531
};
532532

533+
/*
534+
* This structure is instantiated on a per-CPU basis, and contains
535+
* data that is:
536+
*
537+
* - tied to a single physical CPU, and
538+
* - either have a lifetime that does not extend past vcpu_put()
539+
* - or is an invariant for the lifetime of the system
540+
*
541+
* Use host_data_ptr(field) as a way to access a pointer to such a
542+
* field.
543+
*/
533544
struct kvm_host_data {
534545
struct kvm_cpu_context host_ctxt;
535546
};
@@ -1168,6 +1179,32 @@ struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
11681179

11691180
DECLARE_KVM_HYP_PER_CPU(struct kvm_host_data, kvm_host_data);
11701181

1182+
/*
1183+
* How we access per-CPU host data depends on the where we access it from,
1184+
* and the mode we're in:
1185+
*
1186+
* - VHE and nVHE hypervisor bits use their locally defined instance
1187+
*
1188+
* - the rest of the kernel use either the VHE or nVHE one, depending on
1189+
* the mode we're running in.
1190+
*
1191+
* Unless we're in protected mode, fully deprivileged, and the nVHE
1192+
* per-CPU stuff is exclusively accessible to the protected EL2 code.
1193+
* In this case, the EL1 code uses the *VHE* data as its private state
1194+
* (which makes sense in a way as there shouldn't be any shared state
1195+
* between the host and the hypervisor).
1196+
*
1197+
* Yes, this is all totally trivial. Shoot me now.
1198+
*/
1199+
#if defined(__KVM_NVHE_HYPERVISOR__) || defined(__KVM_VHE_HYPERVISOR__)
1200+
#define host_data_ptr(f) (&this_cpu_ptr(&kvm_host_data)->f)
1201+
#else
1202+
#define host_data_ptr(f) \
1203+
(static_branch_unlikely(&kvm_protected_mode_initialized) ? \
1204+
&this_cpu_ptr(&kvm_host_data)->f : \
1205+
&this_cpu_ptr_hyp_sym(kvm_host_data)->f)
1206+
#endif
1207+
11711208
static inline void kvm_init_host_cpu_context(struct kvm_cpu_context *cpu_ctxt)
11721209
{
11731210
/* The host's MPIDR is immutable, so let's set it up at boot time */

arch/arm64/kvm/arm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1971,7 +1971,7 @@ static void cpu_set_hyp_vector(void)
19711971

19721972
static void cpu_hyp_init_context(void)
19731973
{
1974-
kvm_init_host_cpu_context(&this_cpu_ptr_hyp_sym(kvm_host_data)->host_ctxt);
1974+
kvm_init_host_cpu_context(host_data_ptr(host_ctxt));
19751975

19761976
if (!is_kernel_in_hyp_mode())
19771977
cpu_init_hyp_mode();

arch/arm64/kvm/hyp/include/hyp/debug-sr.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ static inline void __debug_switch_to_guest_common(struct kvm_vcpu *vcpu)
135135
if (!vcpu_get_flag(vcpu, DEBUG_DIRTY))
136136
return;
137137

138-
host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
138+
host_ctxt = host_data_ptr(host_ctxt);
139139
guest_ctxt = &vcpu->arch.ctxt;
140140
host_dbg = &vcpu->arch.host_debug_state.regs;
141141
guest_dbg = kern_hyp_va(vcpu->arch.debug_ptr);
@@ -154,7 +154,7 @@ static inline void __debug_switch_to_host_common(struct kvm_vcpu *vcpu)
154154
if (!vcpu_get_flag(vcpu, DEBUG_DIRTY))
155155
return;
156156

157-
host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
157+
host_ctxt = host_data_ptr(host_ctxt);
158158
guest_ctxt = &vcpu->arch.ctxt;
159159
host_dbg = &vcpu->arch.host_debug_state.regs;
160160
guest_dbg = kern_hyp_va(vcpu->arch.debug_ptr);

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ static inline bool cpu_has_amu(void)
155155

156156
static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
157157
{
158-
struct kvm_cpu_context *hctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
158+
struct kvm_cpu_context *hctxt = host_data_ptr(host_ctxt);
159159
struct kvm *kvm = kern_hyp_va(vcpu->kvm);
160160

161161
CHECK_FGT_MASKS(HFGRTR_EL2);
@@ -191,7 +191,7 @@ static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
191191

192192
static inline void __deactivate_traps_hfgxtr(struct kvm_vcpu *vcpu)
193193
{
194-
struct kvm_cpu_context *hctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
194+
struct kvm_cpu_context *hctxt = host_data_ptr(host_ctxt);
195195
struct kvm *kvm = kern_hyp_va(vcpu->kvm);
196196

197197
if (!cpus_have_final_cap(ARM64_HAS_FGT))
@@ -226,7 +226,7 @@ static inline void __activate_traps_common(struct kvm_vcpu *vcpu)
226226

227227
write_sysreg(0, pmselr_el0);
228228

229-
hctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
229+
hctxt = host_data_ptr(host_ctxt);
230230
ctxt_sys_reg(hctxt, PMUSERENR_EL0) = read_sysreg(pmuserenr_el0);
231231
write_sysreg(ARMV8_PMU_USERENR_MASK, pmuserenr_el0);
232232
vcpu_set_flag(vcpu, PMUSERENR_ON_CPU);
@@ -260,7 +260,7 @@ static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu)
260260
if (kvm_arm_support_pmu_v3()) {
261261
struct kvm_cpu_context *hctxt;
262262

263-
hctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
263+
hctxt = host_data_ptr(host_ctxt);
264264
write_sysreg(ctxt_sys_reg(hctxt, PMUSERENR_EL0), pmuserenr_el0);
265265
vcpu_clear_flag(vcpu, PMUSERENR_ON_CPU);
266266
}

arch/arm64/kvm/hyp/nvhe/psci-relay.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ asmlinkage void __noreturn __kvm_host_psci_cpu_entry(bool is_cpu_on)
205205
struct psci_boot_args *boot_args;
206206
struct kvm_cpu_context *host_ctxt;
207207

208-
host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
208+
host_ctxt = host_data_ptr(host_ctxt);
209209

210210
if (is_cpu_on)
211211
boot_args = this_cpu_ptr(&cpu_on_args);

arch/arm64/kvm/hyp/nvhe/setup.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,8 +257,7 @@ static int fix_hyp_pgtable_refcnt(void)
257257

258258
void __noreturn __pkvm_init_finalise(void)
259259
{
260-
struct kvm_host_data *host_data = this_cpu_ptr(&kvm_host_data);
261-
struct kvm_cpu_context *host_ctxt = &host_data->host_ctxt;
260+
struct kvm_cpu_context *host_ctxt = host_data_ptr(host_ctxt);
262261
unsigned long nr_pages, reserved_pages, pfn;
263262
int ret;
264263

arch/arm64/kvm/hyp/nvhe/switch.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
264264
pmr_sync();
265265
}
266266

267-
host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
267+
host_ctxt = host_data_ptr(host_ctxt);
268268
host_ctxt->__hyp_running_vcpu = vcpu;
269269
guest_ctxt = &vcpu->arch.ctxt;
270270

@@ -367,7 +367,7 @@ asmlinkage void __noreturn hyp_panic(void)
367367
struct kvm_cpu_context *host_ctxt;
368368
struct kvm_vcpu *vcpu;
369369

370-
host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
370+
host_ctxt = host_data_ptr(host_ctxt);
371371
vcpu = host_ctxt->__hyp_running_vcpu;
372372

373373
if (vcpu) {

arch/arm64/kvm/hyp/vhe/switch.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ static int __kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu)
221221
struct kvm_cpu_context *guest_ctxt;
222222
u64 exit_code;
223223

224-
host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
224+
host_ctxt = host_data_ptr(host_ctxt);
225225
host_ctxt->__hyp_running_vcpu = vcpu;
226226
guest_ctxt = &vcpu->arch.ctxt;
227227

@@ -306,7 +306,7 @@ static void __hyp_call_panic(u64 spsr, u64 elr, u64 par)
306306
struct kvm_cpu_context *host_ctxt;
307307
struct kvm_vcpu *vcpu;
308308

309-
host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
309+
host_ctxt = host_data_ptr(host_ctxt);
310310
vcpu = host_ctxt->__hyp_running_vcpu;
311311

312312
__deactivate_traps(vcpu);

arch/arm64/kvm/hyp/vhe/sysreg-sr.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ void __vcpu_load_switch_sysregs(struct kvm_vcpu *vcpu)
6767
struct kvm_cpu_context *guest_ctxt = &vcpu->arch.ctxt;
6868
struct kvm_cpu_context *host_ctxt;
6969

70-
host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
70+
host_ctxt = host_data_ptr(host_ctxt);
7171
__sysreg_save_user_state(host_ctxt);
7272

7373
/*
@@ -110,7 +110,7 @@ void __vcpu_put_switch_sysregs(struct kvm_vcpu *vcpu)
110110
struct kvm_cpu_context *guest_ctxt = &vcpu->arch.ctxt;
111111
struct kvm_cpu_context *host_ctxt;
112112

113-
host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
113+
host_ctxt = host_data_ptr(host_ctxt);
114114

115115
__sysreg_save_el1_state(guest_ctxt);
116116
__sysreg_save_user_state(guest_ctxt);

arch/arm64/kvm/pmu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ bool kvm_set_pmuserenr(u64 val)
232232
if (!vcpu || !vcpu_get_flag(vcpu, PMUSERENR_ON_CPU))
233233
return false;
234234

235-
hctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
235+
hctxt = host_data_ptr(host_ctxt);
236236
ctxt_sys_reg(hctxt, PMUSERENR_EL0) = val;
237237
return true;
238238
}

0 commit comments

Comments
 (0)