Skip to content

Commit fd85b66

Browse files
author
Marc Zyngier
committed
KVM: arm64: Disintegrate SPSR array
As we're about to move SPSR_EL1 into the VNCR page, we need to disassociate it from the rest of the 32bit cruft. Let's break the array into individual fields. Reviewed-by: James Morse <[email protected]> Signed-off-by: Marc Zyngier <[email protected]>
1 parent 1bded23 commit fd85b66

File tree

5 files changed

+63
-29
lines changed

5 files changed

+63
-29
lines changed

arch/arm64/include/asm/kvm_emulate.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ static inline unsigned long vcpu_read_spsr(const struct kvm_vcpu *vcpu)
176176
if (vcpu->arch.sysregs_loaded_on_cpu)
177177
return read_sysreg_el1(SYS_SPSR);
178178
else
179-
return vcpu->arch.ctxt.spsr[KVM_SPSR_EL1];
179+
return vcpu->arch.ctxt.spsr_el1;
180180
}
181181

182182
static inline void vcpu_write_spsr(struct kvm_vcpu *vcpu, unsigned long v)
@@ -189,7 +189,7 @@ static inline void vcpu_write_spsr(struct kvm_vcpu *vcpu, unsigned long v)
189189
if (vcpu->arch.sysregs_loaded_on_cpu)
190190
write_sysreg_el1(v, SYS_SPSR);
191191
else
192-
vcpu->arch.ctxt.spsr[KVM_SPSR_EL1] = v;
192+
vcpu->arch.ctxt.spsr_el1 = v;
193193
}
194194

195195
/*

arch/arm64/include/asm/kvm_host.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,11 @@ enum vcpu_sysreg {
241241
struct kvm_cpu_context {
242242
struct user_pt_regs regs; /* sp = sp_el0 */
243243

244-
u64 spsr[KVM_NR_SPSR];
244+
u64 spsr_el1; /* aka spsr_svc */
245+
u64 spsr_abt;
246+
u64 spsr_und;
247+
u64 spsr_irq;
248+
u64 spsr_fiq;
245249

246250
struct user_fpsimd_state fp_regs;
247251

arch/arm64/kvm/guest.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,20 @@ static void *core_reg_addr(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
134134
case KVM_REG_ARM_CORE_REG(elr_el1):
135135
return __ctxt_sys_reg(&vcpu->arch.ctxt, ELR_EL1);
136136

137-
case KVM_REG_ARM_CORE_REG(spsr[0]) ...
138-
KVM_REG_ARM_CORE_REG(spsr[KVM_NR_SPSR - 1]):
139-
off -= KVM_REG_ARM_CORE_REG(spsr[0]);
140-
off /= 2;
141-
return &vcpu->arch.ctxt.spsr[off];
137+
case KVM_REG_ARM_CORE_REG(spsr[KVM_SPSR_EL1]):
138+
return &vcpu->arch.ctxt.spsr_el1;
139+
140+
case KVM_REG_ARM_CORE_REG(spsr[KVM_SPSR_ABT]):
141+
return &vcpu->arch.ctxt.spsr_abt;
142+
143+
case KVM_REG_ARM_CORE_REG(spsr[KVM_SPSR_UND]):
144+
return &vcpu->arch.ctxt.spsr_und;
145+
146+
case KVM_REG_ARM_CORE_REG(spsr[KVM_SPSR_IRQ]):
147+
return &vcpu->arch.ctxt.spsr_irq;
148+
149+
case KVM_REG_ARM_CORE_REG(spsr[KVM_SPSR_FIQ]):
150+
return &vcpu->arch.ctxt.spsr_fiq;
142151

143152
case KVM_REG_ARM_CORE_REG(fp_regs.vregs[0]) ...
144153
KVM_REG_ARM_CORE_REG(fp_regs.vregs[31]):

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

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ static inline void __sysreg_save_el1_state(struct kvm_cpu_context *ctxt)
4848

4949
ctxt_sys_reg(ctxt, SP_EL1) = read_sysreg(sp_el1);
5050
ctxt_sys_reg(ctxt, ELR_EL1) = read_sysreg_el1(SYS_ELR);
51-
ctxt->spsr[KVM_SPSR_EL1] = read_sysreg_el1(SYS_SPSR);
51+
ctxt->spsr_el1 = read_sysreg_el1(SYS_SPSR);
5252
}
5353

5454
static inline void __sysreg_save_el2_return_state(struct kvm_cpu_context *ctxt)
@@ -127,7 +127,7 @@ static inline void __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt)
127127

128128
write_sysreg(ctxt_sys_reg(ctxt, SP_EL1), sp_el1);
129129
write_sysreg_el1(ctxt_sys_reg(ctxt, ELR_EL1), SYS_ELR);
130-
write_sysreg_el1(ctxt->spsr[KVM_SPSR_EL1], SYS_SPSR);
130+
write_sysreg_el1(ctxt->spsr_el1, SYS_SPSR);
131131
}
132132

133133
static inline void __sysreg_restore_el2_return_state(struct kvm_cpu_context *ctxt)
@@ -158,17 +158,13 @@ static inline void __sysreg_restore_el2_return_state(struct kvm_cpu_context *ctx
158158

159159
static inline void __sysreg32_save_state(struct kvm_vcpu *vcpu)
160160
{
161-
u64 *spsr;
162-
163161
if (!vcpu_el1_is_32bit(vcpu))
164162
return;
165163

166-
spsr = vcpu->arch.ctxt.spsr;
167-
168-
spsr[KVM_SPSR_ABT] = read_sysreg(spsr_abt);
169-
spsr[KVM_SPSR_UND] = read_sysreg(spsr_und);
170-
spsr[KVM_SPSR_IRQ] = read_sysreg(spsr_irq);
171-
spsr[KVM_SPSR_FIQ] = read_sysreg(spsr_fiq);
164+
vcpu->arch.ctxt.spsr_abt = read_sysreg(spsr_abt);
165+
vcpu->arch.ctxt.spsr_und = read_sysreg(spsr_und);
166+
vcpu->arch.ctxt.spsr_irq = read_sysreg(spsr_irq);
167+
vcpu->arch.ctxt.spsr_fiq = read_sysreg(spsr_fiq);
172168

173169
__vcpu_sys_reg(vcpu, DACR32_EL2) = read_sysreg(dacr32_el2);
174170
__vcpu_sys_reg(vcpu, IFSR32_EL2) = read_sysreg(ifsr32_el2);
@@ -179,17 +175,13 @@ static inline void __sysreg32_save_state(struct kvm_vcpu *vcpu)
179175

180176
static inline void __sysreg32_restore_state(struct kvm_vcpu *vcpu)
181177
{
182-
u64 *spsr;
183-
184178
if (!vcpu_el1_is_32bit(vcpu))
185179
return;
186180

187-
spsr = vcpu->arch.ctxt.spsr;
188-
189-
write_sysreg(spsr[KVM_SPSR_ABT], spsr_abt);
190-
write_sysreg(spsr[KVM_SPSR_UND], spsr_und);
191-
write_sysreg(spsr[KVM_SPSR_IRQ], spsr_irq);
192-
write_sysreg(spsr[KVM_SPSR_FIQ], spsr_fiq);
181+
write_sysreg(vcpu->arch.ctxt.spsr_abt, spsr_abt);
182+
write_sysreg(vcpu->arch.ctxt.spsr_und, spsr_und);
183+
write_sysreg(vcpu->arch.ctxt.spsr_irq, spsr_irq);
184+
write_sysreg(vcpu->arch.ctxt.spsr_fiq, spsr_fiq);
193185

194186
write_sysreg(__vcpu_sys_reg(vcpu, DACR32_EL2), dacr32_el2);
195187
write_sysreg(__vcpu_sys_reg(vcpu, IFSR32_EL2), ifsr32_el2);

arch/arm64/kvm/regmap.c

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,20 @@ unsigned long vcpu_read_spsr32(const struct kvm_vcpu *vcpu)
147147
{
148148
int spsr_idx = vcpu_spsr32_mode(vcpu);
149149

150-
if (!vcpu->arch.sysregs_loaded_on_cpu)
151-
return vcpu->arch.ctxt.spsr[spsr_idx];
150+
if (!vcpu->arch.sysregs_loaded_on_cpu) {
151+
switch (spsr_idx) {
152+
case KVM_SPSR_SVC:
153+
return vcpu->arch.ctxt.spsr_el1;
154+
case KVM_SPSR_ABT:
155+
return vcpu->arch.ctxt.spsr_abt;
156+
case KVM_SPSR_UND:
157+
return vcpu->arch.ctxt.spsr_und;
158+
case KVM_SPSR_IRQ:
159+
return vcpu->arch.ctxt.spsr_irq;
160+
case KVM_SPSR_FIQ:
161+
return vcpu->arch.ctxt.spsr_fiq;
162+
}
163+
}
152164

153165
switch (spsr_idx) {
154166
case KVM_SPSR_SVC:
@@ -171,7 +183,24 @@ void vcpu_write_spsr32(struct kvm_vcpu *vcpu, unsigned long v)
171183
int spsr_idx = vcpu_spsr32_mode(vcpu);
172184

173185
if (!vcpu->arch.sysregs_loaded_on_cpu) {
174-
vcpu->arch.ctxt.spsr[spsr_idx] = v;
186+
switch (spsr_idx) {
187+
case KVM_SPSR_SVC:
188+
vcpu->arch.ctxt.spsr_el1 = v;
189+
break;
190+
case KVM_SPSR_ABT:
191+
vcpu->arch.ctxt.spsr_abt = v;
192+
break;
193+
case KVM_SPSR_UND:
194+
vcpu->arch.ctxt.spsr_und = v;
195+
break;
196+
case KVM_SPSR_IRQ:
197+
vcpu->arch.ctxt.spsr_irq = v;
198+
break;
199+
case KVM_SPSR_FIQ:
200+
vcpu->arch.ctxt.spsr_fiq = v;
201+
break;
202+
}
203+
175204
return;
176205
}
177206

0 commit comments

Comments
 (0)