[kvm-unit-tests,v2,3/3] s390x: Load reset psw on diag308 reset
diff mbox series

Message ID 20191111153345.22505-4-frankja@linux.ibm.com
State New
Headers show
Series
  • s390x: Improve architectural compliance for diag308
Related show

Commit Message

Janosch Frank Nov. 11, 2019, 3:33 p.m. UTC
On a diag308 subcode 0 CRs will be reset, so we need a PSW mask
without DAT. Also we need to set the short psw indication to be
compliant with the architecture.

Let's therefore define a reset PSW mask with 64 bit addressing and
short PSW indication that is compliant with architecture and use it.

Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
---
 lib/s390x/asm-offsets.c  |  1 +
 lib/s390x/asm/arch_def.h |  3 ++-
 s390x/cstart64.S         | 24 +++++++++++++++++-------
 3 files changed, 20 insertions(+), 8 deletions(-)

Comments

Thomas Huth Nov. 12, 2019, 9:53 a.m. UTC | #1
On 11/11/2019 16.33, Janosch Frank wrote:
> On a diag308 subcode 0 CRs will be reset, so we need a PSW mask
> without DAT. Also we need to set the short psw indication to be
> compliant with the architecture.
> 
> Let's therefore define a reset PSW mask with 64 bit addressing and
> short PSW indication that is compliant with architecture and use it.
> 
> Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
> ---
>  lib/s390x/asm-offsets.c  |  1 +
>  lib/s390x/asm/arch_def.h |  3 ++-
>  s390x/cstart64.S         | 24 +++++++++++++++++-------
>  3 files changed, 20 insertions(+), 8 deletions(-)

Reviewed-by: Thomas Huth <thuth@redhat.com>
David Hildenbrand Nov. 12, 2019, 12:09 p.m. UTC | #2
On 11.11.19 16:33, Janosch Frank wrote:
> On a diag308 subcode 0 CRs will be reset, so we need a PSW mask
> without DAT. Also we need to set the short psw indication to be
> compliant with the architecture.
> 
> Let's therefore define a reset PSW mask with 64 bit addressing and
> short PSW indication that is compliant with architecture and use it.
> 
> Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
> ---
>  lib/s390x/asm-offsets.c  |  1 +
>  lib/s390x/asm/arch_def.h |  3 ++-
>  s390x/cstart64.S         | 24 +++++++++++++++++-------
>  3 files changed, 20 insertions(+), 8 deletions(-)
> 
> diff --git a/lib/s390x/asm-offsets.c b/lib/s390x/asm-offsets.c
> index 4b213f8..61d2658 100644
> --- a/lib/s390x/asm-offsets.c
> +++ b/lib/s390x/asm-offsets.c
> @@ -58,6 +58,7 @@ int main(void)
>  	OFFSET(GEN_LC_SW_INT_FPRS, lowcore, sw_int_fprs);
>  	OFFSET(GEN_LC_SW_INT_FPC, lowcore, sw_int_fpc);
>  	OFFSET(GEN_LC_SW_INT_CRS, lowcore, sw_int_crs);
> +	OFFSET(GEN_LC_SW_INT_PSW, lowcore, sw_int_psw);
>  	OFFSET(GEN_LC_MCCK_EXT_SA_ADDR, lowcore, mcck_ext_sa_addr);
>  	OFFSET(GEN_LC_FPRS_SA, lowcore, fprs_sa);
>  	OFFSET(GEN_LC_GRS_SA, lowcore, grs_sa);
> diff --git a/lib/s390x/asm/arch_def.h b/lib/s390x/asm/arch_def.h
> index 07d4e5e..7d25e4f 100644
> --- a/lib/s390x/asm/arch_def.h
> +++ b/lib/s390x/asm/arch_def.h
> @@ -79,7 +79,8 @@ struct lowcore {
>  	uint32_t	sw_int_fpc;			/* 0x0300 */
>  	uint8_t		pad_0x0304[0x0308 - 0x0304];	/* 0x0304 */
>  	uint64_t	sw_int_crs[16];			/* 0x0308 */
> -	uint8_t		pad_0x0310[0x11b0 - 0x0388];	/* 0x0388 */
> +	struct psw	sw_int_psw;			/* 0x0388 */
> +	uint8_t		pad_0x0310[0x11b0 - 0x0390];	/* 0x0390 */
>  	uint64_t	mcck_ext_sa_addr;		/* 0x11b0 */
>  	uint8_t		pad_0x11b8[0x1200 - 0x11b8];	/* 0x11b8 */
>  	uint64_t	fprs_sa[16];			/* 0x1200 */
> diff --git a/s390x/cstart64.S b/s390x/cstart64.S
> index 4be20fc..86dd4c4 100644
> --- a/s390x/cstart64.S
> +++ b/s390x/cstart64.S
> @@ -126,13 +126,18 @@ memsetxc:
>  .globl diag308_load_reset
>  diag308_load_reset:
>  	SAVE_REGS
> -	/* Save the first PSW word to the IPL PSW */
> +	/* Backup current PSW mask, as we have to restore it on success */
>  	epsw	%r0, %r1
> -	st	%r0, 0
> -	/* Store the address and the bit for 31 bit addressing */
> -	larl    %r0, 0f
> -	oilh    %r0, 0x8000
> -	st      %r0, 0x4
> +	st	%r0, GEN_LC_SW_INT_PSW
> +	st	%r1, GEN_LC_SW_INT_PSW + 4
> +	/* Load reset psw mask (short psw, 64 bit) */
> +	lg	%r0, reset_psw
> +	/* Load the success label address */
> +	larl    %r1, 0f
> +	/* Or it to the mask */
> +	ogr	%r0, %r1
> +	/* Store it at the reset PSW location (real 0x0) */
> +	stg	%r0, 0
>  	/* Do the reset */
>  	diag    %r0,%r2,0x308
>  	/* Failure path */
> @@ -144,7 +149,10 @@ diag308_load_reset:
>  	lctlg	%c0, %c0, 0(%r1)
>  	RESTORE_REGS
>  	lhi	%r2, 1
> -	br	%r14
> +	larl	%r0, 1f
> +	stg	%r0, GEN_LC_SW_INT_PSW + 8
> +	lpswe	GEN_LC_SW_INT_PSW
> +1:	br	%r14
>  
>  .globl smp_cpu_setup_state
>  smp_cpu_setup_state:
> @@ -184,6 +192,8 @@ svc_int:
>  	lpswe	GEN_LC_SVC_OLD_PSW
>  
>  	.align	8
> +reset_psw:
> +	.quad	0x0008000180000000
>  initial_psw:
>  	.quad	0x0000000180000000, clear_bss_start
>  pgm_int_psw:
> 

This patch breaks the smp test under TCG (no clue and no time to look
into the details :) ):

timeout -k 1s --foreground 90s
/home/dhildenb/git/qemu/s390x-softmmu/qemu-system-s390x -nodefaults
-nographic -machine s390-ccw-virtio,accel=tcg -chardev stdio,id=con0
-device sclpconsole,chardev=con0 -kernel s390x/smp.elf -smp 1 -smp 2 #
-initrd /tmp/tmp.EDi4y0tv58
SMP: Initializing, found 2 cpus
PASS: smp: start
PASS: smp: stop
FAIL: smp: stop store status: prefix
PASS: smp: stop store status: stack
PASS: smp: store status at address: running: incorrect state
PASS: smp: store status at address: running: status not written
PASS: smp: store status at address: stopped: status written
PASS: smp: ecall: ecall
PASS: smp: emcall: ecall
PASS: smp: cpu reset: cpu stopped
PASS: smp: reset initial: clear: psw
PASS: smp: reset initial: clear: prefix
PASS: smp: reset initial: clear: fpc
PASS: smp: reset initial: clear: cpu timer
PASS: smp: reset initial: clear: todpr
PASS: smp: reset initial: initialized: cr0 == 0xE0
PASS: smp: reset initial: initialized: cr14 == 0xC2000000
PASS: smp: reset initial: cpu stopped
SUMMARY: 18 tests, 1 unexpected failures
Janosch Frank Nov. 12, 2019, 1:42 p.m. UTC | #3
On 11/12/19 1:09 PM, David Hildenbrand wrote:
> On 11.11.19 16:33, Janosch Frank wrote:
>> On a diag308 subcode 0 CRs will be reset, so we need a PSW mask
>> without DAT. Also we need to set the short psw indication to be
>> compliant with the architecture.
>>
>> Let's therefore define a reset PSW mask with 64 bit addressing and
>> short PSW indication that is compliant with architecture and use it.
>>
>> Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
>> ---
>>  lib/s390x/asm-offsets.c  |  1 +
>>  lib/s390x/asm/arch_def.h |  3 ++-
>>  s390x/cstart64.S         | 24 +++++++++++++++++-------
>>  3 files changed, 20 insertions(+), 8 deletions(-)
>>
>> diff --git a/lib/s390x/asm-offsets.c b/lib/s390x/asm-offsets.c
>> index 4b213f8..61d2658 100644
>> --- a/lib/s390x/asm-offsets.c
>> +++ b/lib/s390x/asm-offsets.c
>> @@ -58,6 +58,7 @@ int main(void)
>>  	OFFSET(GEN_LC_SW_INT_FPRS, lowcore, sw_int_fprs);
>>  	OFFSET(GEN_LC_SW_INT_FPC, lowcore, sw_int_fpc);
>>  	OFFSET(GEN_LC_SW_INT_CRS, lowcore, sw_int_crs);
>> +	OFFSET(GEN_LC_SW_INT_PSW, lowcore, sw_int_psw);
>>  	OFFSET(GEN_LC_MCCK_EXT_SA_ADDR, lowcore, mcck_ext_sa_addr);
>>  	OFFSET(GEN_LC_FPRS_SA, lowcore, fprs_sa);
>>  	OFFSET(GEN_LC_GRS_SA, lowcore, grs_sa);
>> diff --git a/lib/s390x/asm/arch_def.h b/lib/s390x/asm/arch_def.h
>> index 07d4e5e..7d25e4f 100644
>> --- a/lib/s390x/asm/arch_def.h
>> +++ b/lib/s390x/asm/arch_def.h
>> @@ -79,7 +79,8 @@ struct lowcore {
>>  	uint32_t	sw_int_fpc;			/* 0x0300 */
>>  	uint8_t		pad_0x0304[0x0308 - 0x0304];	/* 0x0304 */
>>  	uint64_t	sw_int_crs[16];			/* 0x0308 */
>> -	uint8_t		pad_0x0310[0x11b0 - 0x0388];	/* 0x0388 */
>> +	struct psw	sw_int_psw;			/* 0x0388 */
>> +	uint8_t		pad_0x0310[0x11b0 - 0x0390];	/* 0x0390 */
>>  	uint64_t	mcck_ext_sa_addr;		/* 0x11b0 */
>>  	uint8_t		pad_0x11b8[0x1200 - 0x11b8];	/* 0x11b8 */
>>  	uint64_t	fprs_sa[16];			/* 0x1200 */
>> diff --git a/s390x/cstart64.S b/s390x/cstart64.S
>> index 4be20fc..86dd4c4 100644
>> --- a/s390x/cstart64.S
>> +++ b/s390x/cstart64.S
>> @@ -126,13 +126,18 @@ memsetxc:
>>  .globl diag308_load_reset
>>  diag308_load_reset:
>>  	SAVE_REGS
>> -	/* Save the first PSW word to the IPL PSW */
>> +	/* Backup current PSW mask, as we have to restore it on success */
>>  	epsw	%r0, %r1
>> -	st	%r0, 0
>> -	/* Store the address and the bit for 31 bit addressing */
>> -	larl    %r0, 0f
>> -	oilh    %r0, 0x8000
>> -	st      %r0, 0x4
>> +	st	%r0, GEN_LC_SW_INT_PSW
>> +	st	%r1, GEN_LC_SW_INT_PSW + 4
>> +	/* Load reset psw mask (short psw, 64 bit) */
>> +	lg	%r0, reset_psw
>> +	/* Load the success label address */
>> +	larl    %r1, 0f
>> +	/* Or it to the mask */
>> +	ogr	%r0, %r1
>> +	/* Store it at the reset PSW location (real 0x0) */
>> +	stg	%r0, 0
>>  	/* Do the reset */
>>  	diag    %r0,%r2,0x308
>>  	/* Failure path */
>> @@ -144,7 +149,10 @@ diag308_load_reset:
>>  	lctlg	%c0, %c0, 0(%r1)
>>  	RESTORE_REGS
>>  	lhi	%r2, 1
>> -	br	%r14
>> +	larl	%r0, 1f
>> +	stg	%r0, GEN_LC_SW_INT_PSW + 8
>> +	lpswe	GEN_LC_SW_INT_PSW
>> +1:	br	%r14
>>  
>>  .globl smp_cpu_setup_state
>>  smp_cpu_setup_state:
>> @@ -184,6 +192,8 @@ svc_int:
>>  	lpswe	GEN_LC_SVC_OLD_PSW
>>  
>>  	.align	8
>> +reset_psw:
>> +	.quad	0x0008000180000000
>>  initial_psw:
>>  	.quad	0x0000000180000000, clear_bss_start
>>  pgm_int_psw:
>>
> 
> This patch breaks the smp test under TCG (no clue and no time to look
> into the details :) ):

I forgot to fixup the offset calculation at the top of the patch once
again...

> 
> timeout -k 1s --foreground 90s
> /home/dhildenb/git/qemu/s390x-softmmu/qemu-system-s390x -nodefaults
> -nographic -machine s390-ccw-virtio,accel=tcg -chardev stdio,id=con0
> -device sclpconsole,chardev=con0 -kernel s390x/smp.elf -smp 1 -smp 2 #
> -initrd /tmp/tmp.EDi4y0tv58
> SMP: Initializing, found 2 cpus
> PASS: smp: start
> PASS: smp: stop
> FAIL: smp: stop store status: prefix
> PASS: smp: stop store status: stack
> PASS: smp: store status at address: running: incorrect state
> PASS: smp: store status at address: running: status not written
> PASS: smp: store status at address: stopped: status written
> PASS: smp: ecall: ecall
> PASS: smp: emcall: ecall
> PASS: smp: cpu reset: cpu stopped
> PASS: smp: reset initial: clear: psw
> PASS: smp: reset initial: clear: prefix
> PASS: smp: reset initial: clear: fpc
> PASS: smp: reset initial: clear: cpu timer
> PASS: smp: reset initial: clear: todpr
> PASS: smp: reset initial: initialized: cr0 == 0xE0
> PASS: smp: reset initial: initialized: cr14 == 0xC2000000
> PASS: smp: reset initial: cpu stopped
> SUMMARY: 18 tests, 1 unexpected failures
> 
>
Thomas Huth Nov. 12, 2019, 4:17 p.m. UTC | #4
On 12/11/2019 14.42, Janosch Frank wrote:
> On 11/12/19 1:09 PM, David Hildenbrand wrote:
>> On 11.11.19 16:33, Janosch Frank wrote:
>>> On a diag308 subcode 0 CRs will be reset, so we need a PSW mask
>>> without DAT. Also we need to set the short psw indication to be
>>> compliant with the architecture.
>>>
>>> Let's therefore define a reset PSW mask with 64 bit addressing and
>>> short PSW indication that is compliant with architecture and use it.
>>>
>>> Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
>>> ---
>>>  lib/s390x/asm-offsets.c  |  1 +
>>>  lib/s390x/asm/arch_def.h |  3 ++-
>>>  s390x/cstart64.S         | 24 +++++++++++++++++-------
>>>  3 files changed, 20 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/lib/s390x/asm-offsets.c b/lib/s390x/asm-offsets.c
>>> index 4b213f8..61d2658 100644
>>> --- a/lib/s390x/asm-offsets.c
>>> +++ b/lib/s390x/asm-offsets.c
>>> @@ -58,6 +58,7 @@ int main(void)
>>>  	OFFSET(GEN_LC_SW_INT_FPRS, lowcore, sw_int_fprs);
>>>  	OFFSET(GEN_LC_SW_INT_FPC, lowcore, sw_int_fpc);
>>>  	OFFSET(GEN_LC_SW_INT_CRS, lowcore, sw_int_crs);
>>> +	OFFSET(GEN_LC_SW_INT_PSW, lowcore, sw_int_psw);
>>>  	OFFSET(GEN_LC_MCCK_EXT_SA_ADDR, lowcore, mcck_ext_sa_addr);
>>>  	OFFSET(GEN_LC_FPRS_SA, lowcore, fprs_sa);
>>>  	OFFSET(GEN_LC_GRS_SA, lowcore, grs_sa);
>>> diff --git a/lib/s390x/asm/arch_def.h b/lib/s390x/asm/arch_def.h
>>> index 07d4e5e..7d25e4f 100644
>>> --- a/lib/s390x/asm/arch_def.h
>>> +++ b/lib/s390x/asm/arch_def.h
>>> @@ -79,7 +79,8 @@ struct lowcore {
>>>  	uint32_t	sw_int_fpc;			/* 0x0300 */
>>>  	uint8_t		pad_0x0304[0x0308 - 0x0304];	/* 0x0304 */
>>>  	uint64_t	sw_int_crs[16];			/* 0x0308 */
>>> -	uint8_t		pad_0x0310[0x11b0 - 0x0388];	/* 0x0388 */
>>> +	struct psw	sw_int_psw;			/* 0x0388 */
>>> +	uint8_t		pad_0x0310[0x11b0 - 0x0390];	/* 0x0390 */
>>>  	uint64_t	mcck_ext_sa_addr;		/* 0x11b0 */
>>>  	uint8_t		pad_0x11b8[0x1200 - 0x11b8];	/* 0x11b8 */
>>>  	uint64_t	fprs_sa[16];			/* 0x1200 */
[...]
>> This patch breaks the smp test under TCG (no clue and no time to look
>> into the details :) ):
> 
> I forgot to fixup the offset calculation at the top of the patch once
> again...

Maybe add a

_Static_assert(sizeof(struct lowcore) == xyz)

after the struct definitions, to avoid that this happens again?

 Thomas
Janosch Frank Nov. 13, 2019, 10:04 a.m. UTC | #5
On 11/12/19 5:17 PM, Thomas Huth wrote:
> On 12/11/2019 14.42, Janosch Frank wrote:
>> On 11/12/19 1:09 PM, David Hildenbrand wrote:
>>> On 11.11.19 16:33, Janosch Frank wrote:
>>>> On a diag308 subcode 0 CRs will be reset, so we need a PSW mask
>>>> without DAT. Also we need to set the short psw indication to be
>>>> compliant with the architecture.
>>>>
>>>> Let's therefore define a reset PSW mask with 64 bit addressing and
>>>> short PSW indication that is compliant with architecture and use it.
>>>>
>>>> Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
>>>> ---
>>>>  lib/s390x/asm-offsets.c  |  1 +
>>>>  lib/s390x/asm/arch_def.h |  3 ++-
>>>>  s390x/cstart64.S         | 24 +++++++++++++++++-------
>>>>  3 files changed, 20 insertions(+), 8 deletions(-)
>>>>
>>>> diff --git a/lib/s390x/asm-offsets.c b/lib/s390x/asm-offsets.c
>>>> index 4b213f8..61d2658 100644
>>>> --- a/lib/s390x/asm-offsets.c
>>>> +++ b/lib/s390x/asm-offsets.c
>>>> @@ -58,6 +58,7 @@ int main(void)
>>>>  	OFFSET(GEN_LC_SW_INT_FPRS, lowcore, sw_int_fprs);
>>>>  	OFFSET(GEN_LC_SW_INT_FPC, lowcore, sw_int_fpc);
>>>>  	OFFSET(GEN_LC_SW_INT_CRS, lowcore, sw_int_crs);
>>>> +	OFFSET(GEN_LC_SW_INT_PSW, lowcore, sw_int_psw);
>>>>  	OFFSET(GEN_LC_MCCK_EXT_SA_ADDR, lowcore, mcck_ext_sa_addr);
>>>>  	OFFSET(GEN_LC_FPRS_SA, lowcore, fprs_sa);
>>>>  	OFFSET(GEN_LC_GRS_SA, lowcore, grs_sa);
>>>> diff --git a/lib/s390x/asm/arch_def.h b/lib/s390x/asm/arch_def.h
>>>> index 07d4e5e..7d25e4f 100644
>>>> --- a/lib/s390x/asm/arch_def.h
>>>> +++ b/lib/s390x/asm/arch_def.h
>>>> @@ -79,7 +79,8 @@ struct lowcore {
>>>>  	uint32_t	sw_int_fpc;			/* 0x0300 */
>>>>  	uint8_t		pad_0x0304[0x0308 - 0x0304];	/* 0x0304 */
>>>>  	uint64_t	sw_int_crs[16];			/* 0x0308 */
>>>> -	uint8_t		pad_0x0310[0x11b0 - 0x0388];	/* 0x0388 */
>>>> +	struct psw	sw_int_psw;			/* 0x0388 */
>>>> +	uint8_t		pad_0x0310[0x11b0 - 0x0390];	/* 0x0390 */
>>>>  	uint64_t	mcck_ext_sa_addr;		/* 0x11b0 */
>>>>  	uint8_t		pad_0x11b8[0x1200 - 0x11b8];	/* 0x11b8 */
>>>>  	uint64_t	fprs_sa[16];			/* 0x1200 */
> [...]
>>> This patch breaks the smp test under TCG (no clue and no time to look
>>> into the details :) ):
>>
>> I forgot to fixup the offset calculation at the top of the patch once
>> again...
> 
> Maybe add a
> 
> _Static_assert(sizeof(struct lowcore) == xyz)
> 
> after the struct definitions, to avoid that this happens again?
> 
>  Thomas
> 

How about this?
Or do we want to extend the struct to 8K and test for that?

diff --git i/lib/s390x/asm/arch_def.h w/lib/s390x/asm/arch_def.h
index 5f034a7..cf6e1ca 100644
--- i/lib/s390x/asm/arch_def.h
+++ w/lib/s390x/asm/arch_def.h
@@ -99,6 +99,7 @@ struct lowcore {
        uint8_t         pad_0x1400[0x1800 - 0x1400];    /* 0x1400 */
        uint8_t         pgm_int_tdb[0x1900 - 0x1800];   /* 0x1800 */
 } __attribute__ ((__packed__));
+_Static_assert(sizeof(struct lowcore) == 0x1900, "Lowcore size");

 #define PGM_INT_CODE_OPERATION                 0x01
 #define PGM_INT_CODE_PRIVILEGED_OPERATION      0x02
Thomas Huth Nov. 13, 2019, 10:31 a.m. UTC | #6
On 13/11/2019 11.04, Janosch Frank wrote:
> On 11/12/19 5:17 PM, Thomas Huth wrote:
>> On 12/11/2019 14.42, Janosch Frank wrote:
>>> On 11/12/19 1:09 PM, David Hildenbrand wrote:
>>>> On 11.11.19 16:33, Janosch Frank wrote:
>>>>> On a diag308 subcode 0 CRs will be reset, so we need a PSW mask
>>>>> without DAT. Also we need to set the short psw indication to be
>>>>> compliant with the architecture.
>>>>>
>>>>> Let's therefore define a reset PSW mask with 64 bit addressing and
>>>>> short PSW indication that is compliant with architecture and use it.
>>>>>
>>>>> Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
>>>>> ---
>>>>>  lib/s390x/asm-offsets.c  |  1 +
>>>>>  lib/s390x/asm/arch_def.h |  3 ++-
>>>>>  s390x/cstart64.S         | 24 +++++++++++++++++-------
>>>>>  3 files changed, 20 insertions(+), 8 deletions(-)
>>>>>
>>>>> diff --git a/lib/s390x/asm-offsets.c b/lib/s390x/asm-offsets.c
>>>>> index 4b213f8..61d2658 100644
>>>>> --- a/lib/s390x/asm-offsets.c
>>>>> +++ b/lib/s390x/asm-offsets.c
>>>>> @@ -58,6 +58,7 @@ int main(void)
>>>>>  	OFFSET(GEN_LC_SW_INT_FPRS, lowcore, sw_int_fprs);
>>>>>  	OFFSET(GEN_LC_SW_INT_FPC, lowcore, sw_int_fpc);
>>>>>  	OFFSET(GEN_LC_SW_INT_CRS, lowcore, sw_int_crs);
>>>>> +	OFFSET(GEN_LC_SW_INT_PSW, lowcore, sw_int_psw);
>>>>>  	OFFSET(GEN_LC_MCCK_EXT_SA_ADDR, lowcore, mcck_ext_sa_addr);
>>>>>  	OFFSET(GEN_LC_FPRS_SA, lowcore, fprs_sa);
>>>>>  	OFFSET(GEN_LC_GRS_SA, lowcore, grs_sa);
>>>>> diff --git a/lib/s390x/asm/arch_def.h b/lib/s390x/asm/arch_def.h
>>>>> index 07d4e5e..7d25e4f 100644
>>>>> --- a/lib/s390x/asm/arch_def.h
>>>>> +++ b/lib/s390x/asm/arch_def.h
>>>>> @@ -79,7 +79,8 @@ struct lowcore {
>>>>>  	uint32_t	sw_int_fpc;			/* 0x0300 */
>>>>>  	uint8_t		pad_0x0304[0x0308 - 0x0304];	/* 0x0304 */
>>>>>  	uint64_t	sw_int_crs[16];			/* 0x0308 */
>>>>> -	uint8_t		pad_0x0310[0x11b0 - 0x0388];	/* 0x0388 */
>>>>> +	struct psw	sw_int_psw;			/* 0x0388 */
>>>>> +	uint8_t		pad_0x0310[0x11b0 - 0x0390];	/* 0x0390 */
>>>>>  	uint64_t	mcck_ext_sa_addr;		/* 0x11b0 */
>>>>>  	uint8_t		pad_0x11b8[0x1200 - 0x11b8];	/* 0x11b8 */
>>>>>  	uint64_t	fprs_sa[16];			/* 0x1200 */
>> [...]
>>>> This patch breaks the smp test under TCG (no clue and no time to look
>>>> into the details :) ):
>>>
>>> I forgot to fixup the offset calculation at the top of the patch once
>>> again...
>>
>> Maybe add a
>>
>> _Static_assert(sizeof(struct lowcore) == xyz)
>>
>> after the struct definitions, to avoid that this happens again?
>>
>>  Thomas
>>
> 
> How about this?
> Or do we want to extend the struct to 8K and test for that?
> 
> diff --git i/lib/s390x/asm/arch_def.h w/lib/s390x/asm/arch_def.h
> index 5f034a7..cf6e1ca 100644
> --- i/lib/s390x/asm/arch_def.h
> +++ w/lib/s390x/asm/arch_def.h
> @@ -99,6 +99,7 @@ struct lowcore {
>         uint8_t         pad_0x1400[0x1800 - 0x1400];    /* 0x1400 */
>         uint8_t         pgm_int_tdb[0x1900 - 0x1800];   /* 0x1800 */
>  } __attribute__ ((__packed__));
> +_Static_assert(sizeof(struct lowcore) == 0x1900, "Lowcore size");

Fine for me either way (either checking for 0x1900 or extending the
struct to 8192).
Hmm, maybe we should go with 0x1900 for now, and extend the struct to
8192 bytes later if there is a reason to do it.

 Thomas

Patch
diff mbox series

diff --git a/lib/s390x/asm-offsets.c b/lib/s390x/asm-offsets.c
index 4b213f8..61d2658 100644
--- a/lib/s390x/asm-offsets.c
+++ b/lib/s390x/asm-offsets.c
@@ -58,6 +58,7 @@  int main(void)
 	OFFSET(GEN_LC_SW_INT_FPRS, lowcore, sw_int_fprs);
 	OFFSET(GEN_LC_SW_INT_FPC, lowcore, sw_int_fpc);
 	OFFSET(GEN_LC_SW_INT_CRS, lowcore, sw_int_crs);
+	OFFSET(GEN_LC_SW_INT_PSW, lowcore, sw_int_psw);
 	OFFSET(GEN_LC_MCCK_EXT_SA_ADDR, lowcore, mcck_ext_sa_addr);
 	OFFSET(GEN_LC_FPRS_SA, lowcore, fprs_sa);
 	OFFSET(GEN_LC_GRS_SA, lowcore, grs_sa);
diff --git a/lib/s390x/asm/arch_def.h b/lib/s390x/asm/arch_def.h
index 07d4e5e..7d25e4f 100644
--- a/lib/s390x/asm/arch_def.h
+++ b/lib/s390x/asm/arch_def.h
@@ -79,7 +79,8 @@  struct lowcore {
 	uint32_t	sw_int_fpc;			/* 0x0300 */
 	uint8_t		pad_0x0304[0x0308 - 0x0304];	/* 0x0304 */
 	uint64_t	sw_int_crs[16];			/* 0x0308 */
-	uint8_t		pad_0x0310[0x11b0 - 0x0388];	/* 0x0388 */
+	struct psw	sw_int_psw;			/* 0x0388 */
+	uint8_t		pad_0x0310[0x11b0 - 0x0390];	/* 0x0390 */
 	uint64_t	mcck_ext_sa_addr;		/* 0x11b0 */
 	uint8_t		pad_0x11b8[0x1200 - 0x11b8];	/* 0x11b8 */
 	uint64_t	fprs_sa[16];			/* 0x1200 */
diff --git a/s390x/cstart64.S b/s390x/cstart64.S
index 4be20fc..86dd4c4 100644
--- a/s390x/cstart64.S
+++ b/s390x/cstart64.S
@@ -126,13 +126,18 @@  memsetxc:
 .globl diag308_load_reset
 diag308_load_reset:
 	SAVE_REGS
-	/* Save the first PSW word to the IPL PSW */
+	/* Backup current PSW mask, as we have to restore it on success */
 	epsw	%r0, %r1
-	st	%r0, 0
-	/* Store the address and the bit for 31 bit addressing */
-	larl    %r0, 0f
-	oilh    %r0, 0x8000
-	st      %r0, 0x4
+	st	%r0, GEN_LC_SW_INT_PSW
+	st	%r1, GEN_LC_SW_INT_PSW + 4
+	/* Load reset psw mask (short psw, 64 bit) */
+	lg	%r0, reset_psw
+	/* Load the success label address */
+	larl    %r1, 0f
+	/* Or it to the mask */
+	ogr	%r0, %r1
+	/* Store it at the reset PSW location (real 0x0) */
+	stg	%r0, 0
 	/* Do the reset */
 	diag    %r0,%r2,0x308
 	/* Failure path */
@@ -144,7 +149,10 @@  diag308_load_reset:
 	lctlg	%c0, %c0, 0(%r1)
 	RESTORE_REGS
 	lhi	%r2, 1
-	br	%r14
+	larl	%r0, 1f
+	stg	%r0, GEN_LC_SW_INT_PSW + 8
+	lpswe	GEN_LC_SW_INT_PSW
+1:	br	%r14
 
 .globl smp_cpu_setup_state
 smp_cpu_setup_state:
@@ -184,6 +192,8 @@  svc_int:
 	lpswe	GEN_LC_SVC_OLD_PSW
 
 	.align	8
+reset_psw:
+	.quad	0x0008000180000000
 initial_psw:
 	.quad	0x0000000180000000, clear_bss_start
 pgm_int_psw: