Message ID | 20191111153345.22505-4-frankja@linux.ibm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | s390x: Improve architectural compliance for diag308 | expand |
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>
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
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 > >
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
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
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
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:
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(-)