diff options
Diffstat (limited to 'arch/s390/kernel')
| -rw-r--r-- | arch/s390/kernel/asm-offsets.c | 1 | ||||
| -rw-r--r-- | arch/s390/kernel/entry.S | 26 | ||||
| -rw-r--r-- | arch/s390/kernel/setup.c | 1 | ||||
| -rw-r--r-- | arch/s390/kernel/uv.c | 7 | 
4 files changed, 24 insertions, 11 deletions
| diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index d8ce965c0a97..3f8e760298c2 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c @@ -62,6 +62,7 @@ int main(void)  	OFFSET(__SF_SIE_SAVEAREA, stack_frame, sie_savearea);  	OFFSET(__SF_SIE_REASON, stack_frame, sie_reason);  	OFFSET(__SF_SIE_FLAGS, stack_frame, sie_flags); +	OFFSET(__SF_SIE_CONTROL_PHYS, stack_frame, sie_control_block_phys);  	DEFINE(STACK_FRAME_OVERHEAD, sizeof(struct stack_frame));  	BLANK();  	/* idle data offsets */ diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index e0d11f3adfcc..0f423e9df095 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -207,18 +207,20 @@ ENDPROC(__switch_to)  #if IS_ENABLED(CONFIG_KVM)  /* - * sie64a calling convention: - * %r2 pointer to sie control block - * %r3 guest register save area + * __sie64a calling convention: + * %r2 pointer to sie control block phys + * %r3 pointer to sie control block virt + * %r4 guest register save area   */ -ENTRY(sie64a) +ENTRY(__sie64a)  	stmg	%r6,%r14,__SF_GPRS(%r15)	# save kernel registers  	lg	%r12,__LC_CURRENT -	stg	%r2,__SF_SIE_CONTROL(%r15)	# save control block pointer -	stg	%r3,__SF_SIE_SAVEAREA(%r15)	# save guest register save area +	stg	%r2,__SF_SIE_CONTROL_PHYS(%r15)	# save sie block physical.. +	stg	%r3,__SF_SIE_CONTROL(%r15)	# ...and virtual addresses +	stg	%r4,__SF_SIE_SAVEAREA(%r15)	# save guest register save area  	xc	__SF_SIE_REASON(8,%r15),__SF_SIE_REASON(%r15) # reason code = 0  	mvc	__SF_SIE_FLAGS(8,%r15),__TI_flags(%r12) # copy thread flags -	lmg	%r0,%r13,0(%r3)			# load guest gprs 0-13 +	lmg	%r0,%r13,0(%r4)			# load guest gprs 0-13  	lg	%r14,__LC_GMAP			# get gmap pointer  	ltgr	%r14,%r14  	jz	.Lsie_gmap @@ -230,6 +232,7 @@ ENTRY(sie64a)  	jnz	.Lsie_skip  	TSTMSK	__LC_CPU_FLAGS,_CIF_FPU  	jo	.Lsie_skip			# exit if fp/vx regs changed +	lg	%r14,__SF_SIE_CONTROL_PHYS(%r15)	# get sie block phys addr  	BPEXIT	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)  .Lsie_entry:  	sie	0(%r14) @@ -240,13 +243,14 @@ ENTRY(sie64a)  	BPOFF  	BPENTER	__SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)  .Lsie_skip: +	lg	%r14,__SF_SIE_CONTROL(%r15)	# get control block pointer  	ni	__SIE_PROG0C+3(%r14),0xfe	# no longer in SIE  	lctlg	%c1,%c1,__LC_KERNEL_ASCE	# load primary asce  .Lsie_done:  # some program checks are suppressing. C code (e.g. do_protection_exception)  # will rewind the PSW by the ILC, which is often 4 bytes in case of SIE. There  # are some corner cases (e.g. runtime instrumentation) where ILC is unpredictable. -# Other instructions between sie64a and .Lsie_done should not cause program +# Other instructions between __sie64a and .Lsie_done should not cause program  # interrupts. So lets use 3 nops as a landing pad for all possible rewinds.  .Lrewind_pad6:  	nopr	7 @@ -275,8 +279,8 @@ sie_exit:  	EX_TABLE(.Lrewind_pad4,.Lsie_fault)  	EX_TABLE(.Lrewind_pad2,.Lsie_fault)  	EX_TABLE(sie_exit,.Lsie_fault) -ENDPROC(sie64a) -EXPORT_SYMBOL(sie64a) +ENDPROC(__sie64a) +EXPORT_SYMBOL(__sie64a)  EXPORT_SYMBOL(sie_exit)  #endif @@ -355,7 +359,7 @@ ENTRY(pgm_check_handler)  	j	3f			# -> fault in user space  .Lpgm_skip_asce:  #if IS_ENABLED(CONFIG_KVM) -	# cleanup critical section for program checks in sie64a +	# cleanup critical section for program checks in __sie64a  	OUTSIDE	%r9,.Lsie_gmap,.Lsie_done,1f  	SIEEXIT  	lghi	%r10,_PIF_GUEST_FAULT diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 2094f575c532..2b6091349daa 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -52,6 +52,7 @@  #include <linux/hugetlb.h>  #include <linux/kmemleak.h> +#include <asm/archrandom.h>  #include <asm/boot_data.h>  #include <asm/ipl.h>  #include <asm/facility.h> diff --git a/arch/s390/kernel/uv.c b/arch/s390/kernel/uv.c index f9810d2a267c..9f18a4af9c13 100644 --- a/arch/s390/kernel/uv.c +++ b/arch/s390/kernel/uv.c @@ -255,6 +255,13 @@ static int make_secure_pte(pte_t *ptep, unsigned long addr,   */  static bool should_export_before_import(struct uv_cb_header *uvcb, struct mm_struct *mm)  { +	/* +	 * The misc feature indicates, among other things, that importing a +	 * shared page from a different protected VM will automatically also +	 * transfer its ownership. +	 */ +	if (test_bit_inv(BIT_UV_FEAT_MISC, &uv_info.uv_feature_indications)) +		return false;  	if (uvcb->cmd == UVC_CMD_UNPIN_PAGE_SHARED)  		return false;  	return atomic_read(&mm->context.protected_count) > 1; |