Skip to content

Commit 6b33e68

Browse files
Nico Boehrfrankjaa
authored andcommitted
s390/entry: sort out physical vs virtual pointers usage in sie64a
Fix virtual vs physical address confusion (which currently are the same). sie_block is accessed in entry.S and passed it to hardware, which is why both its physical and virtual address are needed. To avoid every caller having to do the virtual-physical conversion, add a new function sie64a() which converts the virtual address to physical. Signed-off-by: Nico Boehr <[email protected]> Reviewed-by: Alexander Gordeev <[email protected]> Reviewed-by: Claudio Imbrenda <[email protected]> Link: https://lore.kernel.org/r/[email protected] Message-Id: <[email protected]> Signed-off-by: Janosch Frank <[email protected]>
1 parent 079f0c2 commit 6b33e68

File tree

4 files changed

+24
-12
lines changed

4 files changed

+24
-12
lines changed

arch/s390/include/asm/kvm_host.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1017,7 +1017,13 @@ void kvm_arch_crypto_clear_masks(struct kvm *kvm);
10171017
void kvm_arch_crypto_set_masks(struct kvm *kvm, unsigned long *apm,
10181018
unsigned long *aqm, unsigned long *adm);
10191019

1020-
extern int sie64a(struct kvm_s390_sie_block *, u64 *);
1020+
int __sie64a(phys_addr_t sie_block_phys, struct kvm_s390_sie_block *sie_block, u64 *rsa);
1021+
1022+
static inline int sie64a(struct kvm_s390_sie_block *sie_block, u64 *rsa)
1023+
{
1024+
return __sie64a(virt_to_phys(sie_block), sie_block, rsa);
1025+
}
1026+
10211027
extern char sie_exit;
10221028

10231029
extern int kvm_s390_gisc_register(struct kvm *kvm, u32 gisc);

arch/s390/include/asm/stacktrace.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ struct stack_frame {
4646
unsigned long sie_savearea;
4747
unsigned long sie_reason;
4848
unsigned long sie_flags;
49+
unsigned long sie_control_block_phys;
4950
};
5051
};
5152
unsigned long gprs[10];

arch/s390/kernel/asm-offsets.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ int main(void)
6262
OFFSET(__SF_SIE_SAVEAREA, stack_frame, sie_savearea);
6363
OFFSET(__SF_SIE_REASON, stack_frame, sie_reason);
6464
OFFSET(__SF_SIE_FLAGS, stack_frame, sie_flags);
65+
OFFSET(__SF_SIE_CONTROL_PHYS, stack_frame, sie_control_block_phys);
6566
DEFINE(STACK_FRAME_OVERHEAD, sizeof(struct stack_frame));
6667
BLANK();
6768
/* idle data offsets */

arch/s390/kernel/entry.S

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -225,18 +225,20 @@ ENDPROC(__switch_to)
225225

226226
#if IS_ENABLED(CONFIG_KVM)
227227
/*
228-
* sie64a calling convention:
229-
* %r2 pointer to sie control block
230-
* %r3 guest register save area
228+
* __sie64a calling convention:
229+
* %r2 pointer to sie control block phys
230+
* %r3 pointer to sie control block virt
231+
* %r4 guest register save area
231232
*/
232-
ENTRY(sie64a)
233+
ENTRY(__sie64a)
233234
stmg %r6,%r14,__SF_GPRS(%r15) # save kernel registers
234235
lg %r12,__LC_CURRENT
235-
stg %r2,__SF_SIE_CONTROL(%r15) # save control block pointer
236-
stg %r3,__SF_SIE_SAVEAREA(%r15) # save guest register save area
236+
stg %r2,__SF_SIE_CONTROL_PHYS(%r15) # save sie block physical..
237+
stg %r3,__SF_SIE_CONTROL(%r15) # ...and virtual addresses
238+
stg %r4,__SF_SIE_SAVEAREA(%r15) # save guest register save area
237239
xc __SF_SIE_REASON(8,%r15),__SF_SIE_REASON(%r15) # reason code = 0
238240
mvc __SF_SIE_FLAGS(8,%r15),__TI_flags(%r12) # copy thread flags
239-
lmg %r0,%r13,0(%r3) # load guest gprs 0-13
241+
lmg %r0,%r13,0(%r4) # load guest gprs 0-13
240242
lg %r14,__LC_GMAP # get gmap pointer
241243
ltgr %r14,%r14
242244
jz .Lsie_gmap
@@ -248,6 +250,7 @@ ENTRY(sie64a)
248250
jnz .Lsie_skip
249251
TSTMSK __LC_CPU_FLAGS,_CIF_FPU
250252
jo .Lsie_skip # exit if fp/vx regs changed
253+
lg %r14,__SF_SIE_CONTROL_PHYS(%r15) # get sie block phys addr
251254
BPEXIT __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
252255
.Lsie_entry:
253256
sie 0(%r14)
@@ -258,13 +261,14 @@ ENTRY(sie64a)
258261
BPOFF
259262
BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
260263
.Lsie_skip:
264+
lg %r14,__SF_SIE_CONTROL(%r15) # get control block pointer
261265
ni __SIE_PROG0C+3(%r14),0xfe # no longer in SIE
262266
lctlg %c1,%c1,__LC_KERNEL_ASCE # load primary asce
263267
.Lsie_done:
264268
# some program checks are suppressing. C code (e.g. do_protection_exception)
265269
# will rewind the PSW by the ILC, which is often 4 bytes in case of SIE. There
266270
# are some corner cases (e.g. runtime instrumentation) where ILC is unpredictable.
267-
# Other instructions between sie64a and .Lsie_done should not cause program
271+
# Other instructions between __sie64a and .Lsie_done should not cause program
268272
# interrupts. So lets use 3 nops as a landing pad for all possible rewinds.
269273
.Lrewind_pad6:
270274
nopr 7
@@ -293,8 +297,8 @@ sie_exit:
293297
EX_TABLE(.Lrewind_pad4,.Lsie_fault)
294298
EX_TABLE(.Lrewind_pad2,.Lsie_fault)
295299
EX_TABLE(sie_exit,.Lsie_fault)
296-
ENDPROC(sie64a)
297-
EXPORT_SYMBOL(sie64a)
300+
ENDPROC(__sie64a)
301+
EXPORT_SYMBOL(__sie64a)
298302
EXPORT_SYMBOL(sie_exit)
299303
#endif
300304

@@ -373,7 +377,7 @@ ENTRY(pgm_check_handler)
373377
j 3f # -> fault in user space
374378
.Lpgm_skip_asce:
375379
#if IS_ENABLED(CONFIG_KVM)
376-
# cleanup critical section for program checks in sie64a
380+
# cleanup critical section for program checks in __sie64a
377381
OUTSIDE %r9,.Lsie_gmap,.Lsie_done,1f
378382
SIEEXIT
379383
lghi %r10,_PIF_GUEST_FAULT

0 commit comments

Comments
 (0)