mirror of
https://github.com/torvalds/linux.git
synced 2026-05-23 06:31:58 +02:00
s390/entry: Remove __GMAP_ASCE and use _PIF_GUEST_FAULT again
Now that the guest ASCE is passed as a parameter to __sie64a(), _PIF_GUEST_FAULT can be used again to determine whether the fault was a guest or host fault. Since the guest ASCE will not be taken from the gmap pointer in lowcore anymore, __GMAP_ASCE can be removed. For the same reason the guest ASCE needs now to be saved into the cr1 save area unconditionally. Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com> Acked-by: Janosch Frank <frankja@linux.ibm.com> Reviewed-by: Heiko Carstens <hca@linux.ibm.com> Link: https://lore.kernel.org/r/20241022120601.167009-2-imbrenda@linux.ibm.com Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
This commit is contained in:
parent
f4d5e64c5c
commit
f96cb0d61d
|
|
@ -14,11 +14,13 @@
|
|||
#define PIF_SYSCALL 0 /* inside a system call */
|
||||
#define PIF_EXECVE_PGSTE_RESTART 1 /* restart execve for PGSTE binaries */
|
||||
#define PIF_SYSCALL_RET_SET 2 /* return value was set via ptrace */
|
||||
#define PIF_GUEST_FAULT 3 /* indicates program check in sie64a */
|
||||
#define PIF_FTRACE_FULL_REGS 4 /* all register contents valid (ftrace) */
|
||||
|
||||
#define _PIF_SYSCALL BIT(PIF_SYSCALL)
|
||||
#define _PIF_EXECVE_PGSTE_RESTART BIT(PIF_EXECVE_PGSTE_RESTART)
|
||||
#define _PIF_SYSCALL_RET_SET BIT(PIF_SYSCALL_RET_SET)
|
||||
#define _PIF_GUEST_FAULT BIT(PIF_GUEST_FAULT)
|
||||
#define _PIF_FTRACE_FULL_REGS BIT(PIF_FTRACE_FULL_REGS)
|
||||
|
||||
#define PSW32_MASK_PER _AC(0x40000000, UL)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
#include <linux/purgatory.h>
|
||||
#include <linux/pgtable.h>
|
||||
#include <linux/ftrace.h>
|
||||
#include <asm/gmap.h>
|
||||
#include <asm/stacktrace.h>
|
||||
|
||||
int main(void)
|
||||
|
|
@ -161,7 +160,6 @@ int main(void)
|
|||
OFFSET(__LC_PGM_TDB, lowcore, pgm_tdb);
|
||||
BLANK();
|
||||
/* gmap/sie offsets */
|
||||
OFFSET(__GMAP_ASCE, gmap, asce);
|
||||
OFFSET(__SIE_PROG0C, kvm_s390_sie_block, prog0c);
|
||||
OFFSET(__SIE_PROG20, kvm_s390_sie_block, prog20);
|
||||
/* kexec_sha_region */
|
||||
|
|
|
|||
|
|
@ -327,13 +327,23 @@ SYM_CODE_START(pgm_check_handler)
|
|||
GET_LC %r13
|
||||
stpt __LC_SYS_ENTER_TIMER(%r13)
|
||||
BPOFF
|
||||
lgr %r10,%r15
|
||||
lmg %r8,%r9,__LC_PGM_OLD_PSW(%r13)
|
||||
xgr %r10,%r10
|
||||
xgr %r12,%r12
|
||||
tmhh %r8,0x0001 # coming from user space?
|
||||
jno .Lpgm_skip_asce
|
||||
lctlg %c1,%c1,__LC_KERNEL_ASCE(%r13)
|
||||
j 3f # -> fault in user space
|
||||
.Lpgm_skip_asce:
|
||||
#if IS_ENABLED(CONFIG_KVM)
|
||||
lg %r11,__LC_CURRENT(%r13)
|
||||
tm __TI_sie(%r11),0xff
|
||||
jz 1f
|
||||
BPENTER __SF_SIE_FLAGS(%r15),_TIF_ISOLATE_BP_GUEST
|
||||
SIEEXIT __SF_SIE_CONTROL(%r15),%r13
|
||||
lg %r12,__SF_SIE_GUEST_ASCE(%r15)
|
||||
lghi %r10,_PIF_GUEST_FAULT
|
||||
#endif
|
||||
1: tmhh %r8,0x4000 # PER bit set in old PSW ?
|
||||
jnz 2f # -> enabled, can't be a double fault
|
||||
tm __LC_PGM_ILC+3(%r13),0x80 # check for per exception
|
||||
|
|
@ -344,21 +354,13 @@ SYM_CODE_START(pgm_check_handler)
|
|||
CHECK_VMAP_STACK __LC_SAVE_AREA,%r13,4f
|
||||
3: lg %r15,__LC_KERNEL_STACK(%r13)
|
||||
4: la %r11,STACK_FRAME_OVERHEAD(%r15)
|
||||
xc __PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
|
||||
stg %r10,__PT_FLAGS(%r11)
|
||||
stg %r12,__PT_CR1(%r11)
|
||||
xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
|
||||
stmg %r0,%r7,__PT_R0(%r11)
|
||||
mvc __PT_R8(64,%r11),__LC_SAVE_AREA(%r13)
|
||||
mvc __PT_LAST_BREAK(8,%r11),__LC_PGM_LAST_BREAK(%r13)
|
||||
stctg %c1,%c1,__PT_CR1(%r11)
|
||||
#if IS_ENABLED(CONFIG_KVM)
|
||||
ltg %r12,__LC_GMAP(%r13)
|
||||
jz 5f
|
||||
clc __GMAP_ASCE(8,%r12), __PT_CR1(%r11)
|
||||
jne 5f
|
||||
BPENTER __SF_SIE_FLAGS(%r10),_TIF_ISOLATE_BP_GUEST
|
||||
SIEEXIT __SF_SIE_CONTROL(%r10),%r13
|
||||
#endif
|
||||
5: stmg %r8,%r9,__PT_PSW(%r11)
|
||||
stmg %r8,%r9,__PT_PSW(%r11)
|
||||
# clear user controlled registers to prevent speculative use
|
||||
xgr %r0,%r0
|
||||
xgr %r1,%r1
|
||||
|
|
|
|||
|
|
@ -68,15 +68,13 @@ early_initcall(fault_init);
|
|||
static enum fault_type get_fault_type(struct pt_regs *regs)
|
||||
{
|
||||
union teid teid = { .val = regs->int_parm_long };
|
||||
struct gmap *gmap;
|
||||
|
||||
if (likely(teid.as == PSW_BITS_AS_PRIMARY)) {
|
||||
if (user_mode(regs))
|
||||
return USER_FAULT;
|
||||
if (!IS_ENABLED(CONFIG_PGSTE))
|
||||
return KERNEL_FAULT;
|
||||
gmap = (struct gmap *)get_lowcore()->gmap;
|
||||
if (gmap && gmap->asce == regs->cr1)
|
||||
if (test_pt_regs_flag(regs, PIF_GUEST_FAULT))
|
||||
return GMAP_FAULT;
|
||||
return KERNEL_FAULT;
|
||||
}
|
||||
|
|
@ -187,7 +185,7 @@ static void dump_fault_info(struct pt_regs *regs)
|
|||
pr_cont("user ");
|
||||
break;
|
||||
case GMAP_FAULT:
|
||||
asce = ((struct gmap *)get_lowcore()->gmap)->asce;
|
||||
asce = regs->cr1;
|
||||
pr_cont("gmap ");
|
||||
break;
|
||||
case KERNEL_FAULT:
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user