Skip to content

Commit ef3e40a

Browse files
author
Marc Zyngier
committed
KVM: arm64: Save the host's PtrAuth keys in non-preemptible context
When using the PtrAuth feature in a guest, we need to save the host's keys before allowing the guest to program them. For that, we dump them in a per-CPU data structure (the so called host context). But both call sites that do this are in preemptible context, which may end up in disaster should the vcpu thread get preempted before reentering the guest. Instead, save the keys eagerly on each vcpu_load(). This has an increased overhead, but is at least safe. Cc: [email protected] Reviewed-by: Mark Rutland <[email protected]> Signed-off-by: Marc Zyngier <[email protected]>
1 parent 7ae2f3d commit ef3e40a

File tree

3 files changed

+19
-24
lines changed

3 files changed

+19
-24
lines changed

arch/arm64/include/asm/kvm_emulate.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,6 @@ static inline void vcpu_ptrauth_disable(struct kvm_vcpu *vcpu)
112112
vcpu->arch.hcr_el2 &= ~(HCR_API | HCR_APK);
113113
}
114114

115-
static inline void vcpu_ptrauth_setup_lazy(struct kvm_vcpu *vcpu)
116-
{
117-
if (vcpu_has_ptrauth(vcpu))
118-
vcpu_ptrauth_disable(vcpu);
119-
}
120-
121115
static inline unsigned long vcpu_get_vsesr(struct kvm_vcpu *vcpu)
122116
{
123117
return vcpu->arch.vsesr_el2;

arch/arm64/kvm/arm.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,12 @@ void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu)
337337
preempt_enable();
338338
}
339339

340+
#define __ptrauth_save_key(regs, key) \
341+
({ \
342+
regs[key ## KEYLO_EL1] = read_sysreg_s(SYS_ ## key ## KEYLO_EL1); \
343+
regs[key ## KEYHI_EL1] = read_sysreg_s(SYS_ ## key ## KEYHI_EL1); \
344+
})
345+
340346
void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
341347
{
342348
int *last_ran;
@@ -370,7 +376,17 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
370376
else
371377
vcpu_set_wfx_traps(vcpu);
372378

373-
vcpu_ptrauth_setup_lazy(vcpu);
379+
if (vcpu_has_ptrauth(vcpu)) {
380+
struct kvm_cpu_context *ctxt = vcpu->arch.host_cpu_context;
381+
382+
__ptrauth_save_key(ctxt->sys_regs, APIA);
383+
__ptrauth_save_key(ctxt->sys_regs, APIB);
384+
__ptrauth_save_key(ctxt->sys_regs, APDA);
385+
__ptrauth_save_key(ctxt->sys_regs, APDB);
386+
__ptrauth_save_key(ctxt->sys_regs, APGA);
387+
388+
vcpu_ptrauth_disable(vcpu);
389+
}
374390
}
375391

376392
void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)

arch/arm64/kvm/handle_exit.c

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -162,31 +162,16 @@ static int handle_sve(struct kvm_vcpu *vcpu, struct kvm_run *run)
162162
return 1;
163163
}
164164

165-
#define __ptrauth_save_key(regs, key) \
166-
({ \
167-
regs[key ## KEYLO_EL1] = read_sysreg_s(SYS_ ## key ## KEYLO_EL1); \
168-
regs[key ## KEYHI_EL1] = read_sysreg_s(SYS_ ## key ## KEYHI_EL1); \
169-
})
170-
171165
/*
172166
* Handle the guest trying to use a ptrauth instruction, or trying to access a
173167
* ptrauth register.
174168
*/
175169
void kvm_arm_vcpu_ptrauth_trap(struct kvm_vcpu *vcpu)
176170
{
177-
struct kvm_cpu_context *ctxt;
178-
179-
if (vcpu_has_ptrauth(vcpu)) {
171+
if (vcpu_has_ptrauth(vcpu))
180172
vcpu_ptrauth_enable(vcpu);
181-
ctxt = vcpu->arch.host_cpu_context;
182-
__ptrauth_save_key(ctxt->sys_regs, APIA);
183-
__ptrauth_save_key(ctxt->sys_regs, APIB);
184-
__ptrauth_save_key(ctxt->sys_regs, APDA);
185-
__ptrauth_save_key(ctxt->sys_regs, APDB);
186-
__ptrauth_save_key(ctxt->sys_regs, APGA);
187-
} else {
173+
else
188174
kvm_inject_undefined(vcpu);
189-
}
190175
}
191176

192177
/*

0 commit comments

Comments
 (0)