Message ID | 1524647323-6449-3-git-send-email-thuth@redhat.com |
---|---|
State | New |
Headers | show |
Series | [v3,1/3] pc-bios/s390-ccw/net: Split up net_load() into init, load and uninit parts | expand |
On 04/25/2018 11:08 AM, Thomas Huth wrote: > --- a/pc-bios/s390-ccw/netmain.c > +++ b/pc-bios/s390-ccw/netmain.c > @@ -283,6 +283,15 @@ void panic(const char *string) > } > } > > +void write_subsystem_identification(void) > +{ > + uint32_t *schid = (uint32_t *) 184; > + uint32_t *zeroes = (uint32_t *) 188; > + > + *schid = 0; /* We must not set this for virtio-net */ > + *zeroes = 0; > +} > + I think we actually want to have the CCW devno of that network device stored. It has some value to know which CCW device we bootet from, no?
On 25.04.2018 14:18, Christian Borntraeger wrote: > > On 04/25/2018 11:08 AM, Thomas Huth wrote: > >> --- a/pc-bios/s390-ccw/netmain.c >> +++ b/pc-bios/s390-ccw/netmain.c >> @@ -283,6 +283,15 @@ void panic(const char *string) >> } >> } >> >> +void write_subsystem_identification(void) >> +{ >> + uint32_t *schid = (uint32_t *) 184; >> + uint32_t *zeroes = (uint32_t *) 188; >> + >> + *schid = 0; /* We must not set this for virtio-net */ >> + *zeroes = 0; >> +} >> + > > I think we actually want to have the CCW devno of that network device > stored. It has some value to know which CCW device we bootet from, no? Actually, I tried that first (and it took quite some time to debug it), but the Linux kernel then bails out quite early, without any error message. The trace looks like this: 0x0000000007801802: diag %r1,%r1,776 0x0000000007801780: larl %r2,0x7831004 0x0000000007801786: llgf %r1,8 0x000000000780178c: mvc 0(12,%r0),0(%r2) 0x0000000007801792: br %r1 0x0000000000000418: bas %r14,512 0x0000000000000200: mvi 163,1 0x0000000000000204: slr %r0,%r0 0x0000000000000206: lhi %r1,2 0x000000000000020a: sigp %r1,%r0,18 0x000000000000020e: bras %r13,0x252 0x0000000000000252: lmh %r0,%r15,0(%r13) 0x0000000000000258: sam31 0x000000000000025a: br %r14 0x000000000000041c: lh %r1,184 0x0000000000000420: bct %r1,1322 0x0000000000000424: l %r1,184 0x0000000000000428: la %r2,1840 0x000000000000042c: bas %r14,640 0x0000000000000280: la %r4,0(%r14) 0x0000000000000284: la %r3,792 0x0000000000000288: la %r5,804 0x000000000000028c: la %r6,888 0x0000000000000290: la %r7,20 0x0000000000000294: st %r2,4(%r6) 0x0000000000000298: la %r2,80(%r2) 0x000000000000029c: la %r6,8(%r6) 0x00000000000002a0: bct %r7,660 0x00000000000002a4: lctl %c6,%c6,868 0x00000000000002a8: slr %r2,%r2 0x00000000000002aa: ssch 0(%r3) 0x00000000000002ae: bne 786 0x0000000000000312: lpsw 880 Guest crashed on cpu 0: disabled-wait PSW: 0x000a000000000000 0x0000000000000000 That's the Lloader function in arch/s390/kernel/head.S which is failing here, so seems like Linux tries to load from a block device in case there is a value in 184. Thus I assume that 184 has to contain 0 in this case. Thomas
You load from address 0. On 04/25/2018 02:34 PM, Thomas Huth wrote: > On 25.04.2018 14:18, Christian Borntraeger wrote: >> >> On 04/25/2018 11:08 AM, Thomas Huth wrote: >> >>> --- a/pc-bios/s390-ccw/netmain.c >>> +++ b/pc-bios/s390-ccw/netmain.c >>> @@ -283,6 +283,15 @@ void panic(const char *string) >>> } >>> } >>> >>> +void write_subsystem_identification(void) >>> +{ >>> + uint32_t *schid = (uint32_t *) 184; >>> + uint32_t *zeroes = (uint32_t *) 188; >>> + >>> + *schid = 0; /* We must not set this for virtio-net */ >>> + *zeroes = 0; >>> +} >>> + >> >> I think we actually want to have the CCW devno of that network device >> stored. It has some value to know which CCW device we bootet from, no? > > Actually, I tried that first (and it took quite some time to debug it), > but the Linux kernel then bails out quite early, without any error > message. The trace looks like this: > > 0x0000000007801802: diag %r1,%r1,776 > 0x0000000007801780: larl %r2,0x7831004 > 0x0000000007801786: llgf %r1,8 > 0x000000000780178c: mvc 0(12,%r0),0(%r2) > 0x0000000007801792: br %r1 > 0x0000000000000418: bas %r14,512 > 0x0000000000000200: mvi 163,1 > 0x0000000000000204: slr %r0,%r0 > 0x0000000000000206: lhi %r1,2 > 0x000000000000020a: sigp %r1,%r0,18 > 0x000000000000020e: bras %r13,0x252 > 0x0000000000000252: lmh %r0,%r15,0(%r13) > 0x0000000000000258: sam31 > 0x000000000000025a: br %r14 > 0x000000000000041c: lh %r1,184 > 0x0000000000000420: bct %r1,1322 > 0x0000000000000424: l %r1,184 > 0x0000000000000428: la %r2,1840 > 0x000000000000042c: bas %r14,640 > 0x0000000000000280: la %r4,0(%r14) > 0x0000000000000284: la %r3,792 > 0x0000000000000288: la %r5,804 > 0x000000000000028c: la %r6,888 > 0x0000000000000290: la %r7,20 > 0x0000000000000294: st %r2,4(%r6) > 0x0000000000000298: la %r2,80(%r2) > 0x000000000000029c: la %r6,8(%r6) > 0x00000000000002a0: bct %r7,660 > 0x00000000000002a4: lctl %c6,%c6,868 > 0x00000000000002a8: slr %r2,%r2 > 0x00000000000002aa: ssch 0(%r3) > 0x00000000000002ae: bne 786 > 0x0000000000000312: lpsw 880 > Guest crashed on cpu 0: disabled-wait > PSW: 0x000a000000000000 0x0000000000000000 > > That's the Lloader function in arch/s390/kernel/head.S which is failing > here, so seems like Linux tries to load from a block device in case > there is a value in 184. Thus I assume that 184 has to contain 0 in this > case. Hmm, I think this is because we jump to 418 for your kernel (which is the loader that tries to bootstrap the ccw ipl). When you look at ipl.c we override that and jump to 0x10000 instead for linux (which is also hackish) for image files. So I guess if we would do a psw restart instead (like you do) on a kernel image the normal ipl would also fail....
On 04/25/2018 02:41 PM, Christian Borntraeger wrote: > You load from address 0. > > On 04/25/2018 02:34 PM, Thomas Huth wrote: >> On 25.04.2018 14:18, Christian Borntraeger wrote: >>> >>> On 04/25/2018 11:08 AM, Thomas Huth wrote: >>> >>>> --- a/pc-bios/s390-ccw/netmain.c >>>> +++ b/pc-bios/s390-ccw/netmain.c >>>> @@ -283,6 +283,15 @@ void panic(const char *string) >>>> } >>>> } >>>> >>>> +void write_subsystem_identification(void) >>>> +{ >>>> + uint32_t *schid = (uint32_t *) 184; >>>> + uint32_t *zeroes = (uint32_t *) 188; >>>> + >>>> + *schid = 0; /* We must not set this for virtio-net */ >>>> + *zeroes = 0; >>>> +} >>>> + >>> >>> I think we actually want to have the CCW devno of that network device >>> stored. It has some value to know which CCW device we bootet from, no? >> >> Actually, I tried that first (and it took quite some time to debug it), >> but the Linux kernel then bails out quite early, without any error >> message. The trace looks like this: >> >> 0x0000000007801802: diag %r1,%r1,776 >> 0x0000000007801780: larl %r2,0x7831004 >> 0x0000000007801786: llgf %r1,8 >> 0x000000000780178c: mvc 0(12,%r0),0(%r2) >> 0x0000000007801792: br %r1 >> 0x0000000000000418: bas %r14,512 >> 0x0000000000000200: mvi 163,1 >> 0x0000000000000204: slr %r0,%r0 >> 0x0000000000000206: lhi %r1,2 >> 0x000000000000020a: sigp %r1,%r0,18 >> 0x000000000000020e: bras %r13,0x252 >> 0x0000000000000252: lmh %r0,%r15,0(%r13) >> 0x0000000000000258: sam31 >> 0x000000000000025a: br %r14 >> 0x000000000000041c: lh %r1,184 >> 0x0000000000000420: bct %r1,1322 >> 0x0000000000000424: l %r1,184 >> 0x0000000000000428: la %r2,1840 >> 0x000000000000042c: bas %r14,640 >> 0x0000000000000280: la %r4,0(%r14) >> 0x0000000000000284: la %r3,792 >> 0x0000000000000288: la %r5,804 >> 0x000000000000028c: la %r6,888 >> 0x0000000000000290: la %r7,20 >> 0x0000000000000294: st %r2,4(%r6) >> 0x0000000000000298: la %r2,80(%r2) >> 0x000000000000029c: la %r6,8(%r6) >> 0x00000000000002a0: bct %r7,660 >> 0x00000000000002a4: lctl %c6,%c6,868 >> 0x00000000000002a8: slr %r2,%r2 >> 0x00000000000002aa: ssch 0(%r3) >> 0x00000000000002ae: bne 786 >> 0x0000000000000312: lpsw 880 >> Guest crashed on cpu 0: disabled-wait >> PSW: 0x000a000000000000 0x0000000000000000 >> >> That's the Lloader function in arch/s390/kernel/head.S which is failing >> here, so seems like Linux tries to load from a block device in case >> there is a value in 184. Thus I assume that 184 has to contain 0 in this >> case. > > Hmm, I think this is because we jump to 418 for your kernel (which is the loader > that tries to bootstrap the ccw ipl). When you look at ipl.c we override that > and jump to 0x10000 instead for linux (which is also hackish) for image files. > So I guess if we would do a psw restart instead (like you do) on a kernel image > the normal ipl would also fail.... > FWIW, zipl also loads linux kernels from 0x10000 $ git grep 0x10000 boot/head.S:.Lstack: .long 0x10000-160 boot/stage2dump.c: if (prefix < 0x10000) /* if < linux-start addr */ boot/tape0.S:KERNEL_OFF = 0x10000 # kernel start code offset boot/tape0.S:KERNEL_ADDR = 0x10000 # default kernel load addr include/zipl.h:#define DEFAULT_IMAGE_ADDRESS 0x10000LL include/zipl.h:#define MINIMUM_ADDRESS 0x10000LL src/bootmap.c: size += DIV_ROUND_UP(st.st_size - 0x10000, src/job.c: &ipl->image_addr, 0, 0x10000, src/job.c: &ipl->ramdisk_addr, 0, 0, 0x10000); src/job.c: &dump->image_addr, 0, 0x10000, src/job.c: 0, 0, 0x10000); src/job.c: &ipl_tape->image_addr, 0, 0x10000, src/job.c: 0, 0, 0x10000);
On 25.04.2018 14:44, Christian Borntraeger wrote: > > > On 04/25/2018 02:41 PM, Christian Borntraeger wrote: >> You load from address 0. >> >> On 04/25/2018 02:34 PM, Thomas Huth wrote: >>> On 25.04.2018 14:18, Christian Borntraeger wrote: >>>> >>>> On 04/25/2018 11:08 AM, Thomas Huth wrote: >>>> >>>>> --- a/pc-bios/s390-ccw/netmain.c >>>>> +++ b/pc-bios/s390-ccw/netmain.c >>>>> @@ -283,6 +283,15 @@ void panic(const char *string) >>>>> } >>>>> } >>>>> >>>>> +void write_subsystem_identification(void) >>>>> +{ >>>>> + uint32_t *schid = (uint32_t *) 184; >>>>> + uint32_t *zeroes = (uint32_t *) 188; >>>>> + >>>>> + *schid = 0; /* We must not set this for virtio-net */ >>>>> + *zeroes = 0; >>>>> +} >>>>> + >>>> >>>> I think we actually want to have the CCW devno of that network device >>>> stored. It has some value to know which CCW device we bootet from, no? >>> >>> Actually, I tried that first (and it took quite some time to debug it), >>> but the Linux kernel then bails out quite early, without any error >>> message. The trace looks like this: >>> >>> 0x0000000007801802: diag %r1,%r1,776 >>> 0x0000000007801780: larl %r2,0x7831004 >>> 0x0000000007801786: llgf %r1,8 >>> 0x000000000780178c: mvc 0(12,%r0),0(%r2) >>> 0x0000000007801792: br %r1 >>> 0x0000000000000418: bas %r14,512 >>> 0x0000000000000200: mvi 163,1 >>> 0x0000000000000204: slr %r0,%r0 >>> 0x0000000000000206: lhi %r1,2 >>> 0x000000000000020a: sigp %r1,%r0,18 >>> 0x000000000000020e: bras %r13,0x252 >>> 0x0000000000000252: lmh %r0,%r15,0(%r13) >>> 0x0000000000000258: sam31 >>> 0x000000000000025a: br %r14 >>> 0x000000000000041c: lh %r1,184 >>> 0x0000000000000420: bct %r1,1322 >>> 0x0000000000000424: l %r1,184 >>> 0x0000000000000428: la %r2,1840 >>> 0x000000000000042c: bas %r14,640 >>> 0x0000000000000280: la %r4,0(%r14) >>> 0x0000000000000284: la %r3,792 >>> 0x0000000000000288: la %r5,804 >>> 0x000000000000028c: la %r6,888 >>> 0x0000000000000290: la %r7,20 >>> 0x0000000000000294: st %r2,4(%r6) >>> 0x0000000000000298: la %r2,80(%r2) >>> 0x000000000000029c: la %r6,8(%r6) >>> 0x00000000000002a0: bct %r7,660 >>> 0x00000000000002a4: lctl %c6,%c6,868 >>> 0x00000000000002a8: slr %r2,%r2 >>> 0x00000000000002aa: ssch 0(%r3) >>> 0x00000000000002ae: bne 786 >>> 0x0000000000000312: lpsw 880 >>> Guest crashed on cpu 0: disabled-wait >>> PSW: 0x000a000000000000 0x0000000000000000 >>> >>> That's the Lloader function in arch/s390/kernel/head.S which is failing >>> here, so seems like Linux tries to load from a block device in case >>> there is a value in 184. Thus I assume that 184 has to contain 0 in this >>> case. >> >> Hmm, I think this is because we jump to 418 for your kernel (which is the loader >> that tries to bootstrap the ccw ipl). When you look at ipl.c we override that >> and jump to 0x10000 instead for linux (which is also hackish) for image files. >> So I guess if we would do a psw restart instead (like you do) on a kernel image >> the normal ipl would also fail.... > > FWIW, zipl also loads linux kernels from 0x10000 OK, I just checked, and indeed, if I change to code to jump to 0x10000, it also works when setting a value into 184. So I'll change this patch here accordingly. Thomas
On 04/25/2018 05:36 PM, Thomas Huth wrote: > On 25.04.2018 14:44, Christian Borntraeger wrote: >> >> >> On 04/25/2018 02:41 PM, Christian Borntraeger wrote: >>> You load from address 0. >>> >>> On 04/25/2018 02:34 PM, Thomas Huth wrote: >>>> On 25.04.2018 14:18, Christian Borntraeger wrote: >>>>> >>>>> On 04/25/2018 11:08 AM, Thomas Huth wrote: >>>>> >>>>>> --- a/pc-bios/s390-ccw/netmain.c >>>>>> +++ b/pc-bios/s390-ccw/netmain.c >>>>>> @@ -283,6 +283,15 @@ void panic(const char *string) >>>>>> } >>>>>> } >>>>>> >>>>>> +void write_subsystem_identification(void) >>>>>> +{ >>>>>> + uint32_t *schid = (uint32_t *) 184; >>>>>> + uint32_t *zeroes = (uint32_t *) 188; >>>>>> + >>>>>> + *schid = 0; /* We must not set this for virtio-net */ >>>>>> + *zeroes = 0; >>>>>> +} >>>>>> + >>>>> >>>>> I think we actually want to have the CCW devno of that network device >>>>> stored. It has some value to know which CCW device we bootet from, no? >>>> >>>> Actually, I tried that first (and it took quite some time to debug it), >>>> but the Linux kernel then bails out quite early, without any error >>>> message. The trace looks like this: >>>> >>>> 0x0000000007801802: diag %r1,%r1,776 >>>> 0x0000000007801780: larl %r2,0x7831004 >>>> 0x0000000007801786: llgf %r1,8 >>>> 0x000000000780178c: mvc 0(12,%r0),0(%r2) >>>> 0x0000000007801792: br %r1 >>>> 0x0000000000000418: bas %r14,512 >>>> 0x0000000000000200: mvi 163,1 >>>> 0x0000000000000204: slr %r0,%r0 >>>> 0x0000000000000206: lhi %r1,2 >>>> 0x000000000000020a: sigp %r1,%r0,18 >>>> 0x000000000000020e: bras %r13,0x252 >>>> 0x0000000000000252: lmh %r0,%r15,0(%r13) >>>> 0x0000000000000258: sam31 >>>> 0x000000000000025a: br %r14 >>>> 0x000000000000041c: lh %r1,184 >>>> 0x0000000000000420: bct %r1,1322 >>>> 0x0000000000000424: l %r1,184 >>>> 0x0000000000000428: la %r2,1840 >>>> 0x000000000000042c: bas %r14,640 >>>> 0x0000000000000280: la %r4,0(%r14) >>>> 0x0000000000000284: la %r3,792 >>>> 0x0000000000000288: la %r5,804 >>>> 0x000000000000028c: la %r6,888 >>>> 0x0000000000000290: la %r7,20 >>>> 0x0000000000000294: st %r2,4(%r6) >>>> 0x0000000000000298: la %r2,80(%r2) >>>> 0x000000000000029c: la %r6,8(%r6) >>>> 0x00000000000002a0: bct %r7,660 >>>> 0x00000000000002a4: lctl %c6,%c6,868 >>>> 0x00000000000002a8: slr %r2,%r2 >>>> 0x00000000000002aa: ssch 0(%r3) >>>> 0x00000000000002ae: bne 786 >>>> 0x0000000000000312: lpsw 880 >>>> Guest crashed on cpu 0: disabled-wait >>>> PSW: 0x000a000000000000 0x0000000000000000 >>>> >>>> That's the Lloader function in arch/s390/kernel/head.S which is failing >>>> here, so seems like Linux tries to load from a block device in case >>>> there is a value in 184. Thus I assume that 184 has to contain 0 in this >>>> case. >>> >>> Hmm, I think this is because we jump to 418 for your kernel (which is the loader >>> that tries to bootstrap the ccw ipl). When you look at ipl.c we override that >>> and jump to 0x10000 instead for linux (which is also hackish) for image files. >>> So I guess if we would do a psw restart instead (like you do) on a kernel image >>> the normal ipl would also fail.... >> >> FWIW, zipl also loads linux kernels from 0x10000 > > OK, I just checked, and indeed, if I change to code to jump to 0x10000, > it also works when setting a value into 184. So I'll change this patch > here accordingly. At the same time it might make sense to change this code in head.S in the kernel to continue the normal startup (at 10000) if the device is a virtio device (similar to what it does when the value at 184 is 0)
On 04/25/2018 05:36 PM, Thomas Huth wrote: > On 25.04.2018 14:44, Christian Borntraeger wrote: >> >> >> On 04/25/2018 02:41 PM, Christian Borntraeger wrote: >>> You load from address 0. >>> >>> On 04/25/2018 02:34 PM, Thomas Huth wrote: >>>> On 25.04.2018 14:18, Christian Borntraeger wrote: >>>>> >>>>> On 04/25/2018 11:08 AM, Thomas Huth wrote: >>>>> >>>>>> --- a/pc-bios/s390-ccw/netmain.c >>>>>> +++ b/pc-bios/s390-ccw/netmain.c >>>>>> @@ -283,6 +283,15 @@ void panic(const char *string) >>>>>> } >>>>>> } >>>>>> >>>>>> +void write_subsystem_identification(void) >>>>>> +{ >>>>>> + uint32_t *schid = (uint32_t *) 184; >>>>>> + uint32_t *zeroes = (uint32_t *) 188; >>>>>> + >>>>>> + *schid = 0; /* We must not set this for virtio-net */ >>>>>> + *zeroes = 0; >>>>>> +} >>>>>> + >>>>> >>>>> I think we actually want to have the CCW devno of that network device >>>>> stored. It has some value to know which CCW device we bootet from, no? >>>> >>>> Actually, I tried that first (and it took quite some time to debug it), >>>> but the Linux kernel then bails out quite early, without any error >>>> message. The trace looks like this: >>>> >>>> 0x0000000007801802: diag %r1,%r1,776 >>>> 0x0000000007801780: larl %r2,0x7831004 >>>> 0x0000000007801786: llgf %r1,8 >>>> 0x000000000780178c: mvc 0(12,%r0),0(%r2) >>>> 0x0000000007801792: br %r1 >>>> 0x0000000000000418: bas %r14,512 >>>> 0x0000000000000200: mvi 163,1 >>>> 0x0000000000000204: slr %r0,%r0 >>>> 0x0000000000000206: lhi %r1,2 >>>> 0x000000000000020a: sigp %r1,%r0,18 >>>> 0x000000000000020e: bras %r13,0x252 >>>> 0x0000000000000252: lmh %r0,%r15,0(%r13) >>>> 0x0000000000000258: sam31 >>>> 0x000000000000025a: br %r14 >>>> 0x000000000000041c: lh %r1,184 >>>> 0x0000000000000420: bct %r1,1322 >>>> 0x0000000000000424: l %r1,184 >>>> 0x0000000000000428: la %r2,1840 >>>> 0x000000000000042c: bas %r14,640 >>>> 0x0000000000000280: la %r4,0(%r14) >>>> 0x0000000000000284: la %r3,792 >>>> 0x0000000000000288: la %r5,804 >>>> 0x000000000000028c: la %r6,888 >>>> 0x0000000000000290: la %r7,20 >>>> 0x0000000000000294: st %r2,4(%r6) >>>> 0x0000000000000298: la %r2,80(%r2) >>>> 0x000000000000029c: la %r6,8(%r6) >>>> 0x00000000000002a0: bct %r7,660 >>>> 0x00000000000002a4: lctl %c6,%c6,868 >>>> 0x00000000000002a8: slr %r2,%r2 >>>> 0x00000000000002aa: ssch 0(%r3) >>>> 0x00000000000002ae: bne 786 >>>> 0x0000000000000312: lpsw 880 >>>> Guest crashed on cpu 0: disabled-wait >>>> PSW: 0x000a000000000000 0x0000000000000000 >>>> >>>> That's the Lloader function in arch/s390/kernel/head.S which is failing >>>> here, so seems like Linux tries to load from a block device in case >>>> there is a value in 184. Thus I assume that 184 has to contain 0 in this >>>> case. >>> >>> Hmm, I think this is because we jump to 418 for your kernel (which is the loader >>> that tries to bootstrap the ccw ipl). When you look at ipl.c we override that >>> and jump to 0x10000 instead for linux (which is also hackish) for image files. >>> So I guess if we would do a psw restart instead (like you do) on a kernel image >>> the normal ipl would also fail.... >> >> FWIW, zipl also loads linux kernels from 0x10000 > > OK, I just checked, and indeed, if I change to code to jump to 0x10000, > it also works when setting a value into 184. So I'll change this patch > here accordingly. This will of course break loading non-Linux binaries. Could we maybe check 0x10008 for S390EP (see head.S) which indicates Linux since 3.2 or so and only in that case change the address to 0x10000?
On 25.04.2018 18:03, Christian Borntraeger wrote: > > > On 04/25/2018 05:36 PM, Thomas Huth wrote: >> On 25.04.2018 14:44, Christian Borntraeger wrote: >>> >>> >>> On 04/25/2018 02:41 PM, Christian Borntraeger wrote: >>>> You load from address 0. >>>> >>>> On 04/25/2018 02:34 PM, Thomas Huth wrote: >>>>> On 25.04.2018 14:18, Christian Borntraeger wrote: >>>>>> >>>>>> On 04/25/2018 11:08 AM, Thomas Huth wrote: >>>>>> >>>>>>> --- a/pc-bios/s390-ccw/netmain.c >>>>>>> +++ b/pc-bios/s390-ccw/netmain.c >>>>>>> @@ -283,6 +283,15 @@ void panic(const char *string) >>>>>>> } >>>>>>> } >>>>>>> >>>>>>> +void write_subsystem_identification(void) >>>>>>> +{ >>>>>>> + uint32_t *schid = (uint32_t *) 184; >>>>>>> + uint32_t *zeroes = (uint32_t *) 188; >>>>>>> + >>>>>>> + *schid = 0; /* We must not set this for virtio-net */ >>>>>>> + *zeroes = 0; >>>>>>> +} >>>>>>> + >>>>>> >>>>>> I think we actually want to have the CCW devno of that network device >>>>>> stored. It has some value to know which CCW device we bootet from, no? >>>>> >>>>> Actually, I tried that first (and it took quite some time to debug it), >>>>> but the Linux kernel then bails out quite early, without any error >>>>> message. The trace looks like this: >>>>> >>>>> 0x0000000007801802: diag %r1,%r1,776 >>>>> 0x0000000007801780: larl %r2,0x7831004 >>>>> 0x0000000007801786: llgf %r1,8 >>>>> 0x000000000780178c: mvc 0(12,%r0),0(%r2) >>>>> 0x0000000007801792: br %r1 >>>>> 0x0000000000000418: bas %r14,512 >>>>> 0x0000000000000200: mvi 163,1 >>>>> 0x0000000000000204: slr %r0,%r0 >>>>> 0x0000000000000206: lhi %r1,2 >>>>> 0x000000000000020a: sigp %r1,%r0,18 >>>>> 0x000000000000020e: bras %r13,0x252 >>>>> 0x0000000000000252: lmh %r0,%r15,0(%r13) >>>>> 0x0000000000000258: sam31 >>>>> 0x000000000000025a: br %r14 >>>>> 0x000000000000041c: lh %r1,184 >>>>> 0x0000000000000420: bct %r1,1322 >>>>> 0x0000000000000424: l %r1,184 >>>>> 0x0000000000000428: la %r2,1840 >>>>> 0x000000000000042c: bas %r14,640 >>>>> 0x0000000000000280: la %r4,0(%r14) >>>>> 0x0000000000000284: la %r3,792 >>>>> 0x0000000000000288: la %r5,804 >>>>> 0x000000000000028c: la %r6,888 >>>>> 0x0000000000000290: la %r7,20 >>>>> 0x0000000000000294: st %r2,4(%r6) >>>>> 0x0000000000000298: la %r2,80(%r2) >>>>> 0x000000000000029c: la %r6,8(%r6) >>>>> 0x00000000000002a0: bct %r7,660 >>>>> 0x00000000000002a4: lctl %c6,%c6,868 >>>>> 0x00000000000002a8: slr %r2,%r2 >>>>> 0x00000000000002aa: ssch 0(%r3) >>>>> 0x00000000000002ae: bne 786 >>>>> 0x0000000000000312: lpsw 880 >>>>> Guest crashed on cpu 0: disabled-wait >>>>> PSW: 0x000a000000000000 0x0000000000000000 >>>>> >>>>> That's the Lloader function in arch/s390/kernel/head.S which is failing >>>>> here, so seems like Linux tries to load from a block device in case >>>>> there is a value in 184. Thus I assume that 184 has to contain 0 in this >>>>> case. >>>> >>>> Hmm, I think this is because we jump to 418 for your kernel (which is the loader >>>> that tries to bootstrap the ccw ipl). When you look at ipl.c we override that >>>> and jump to 0x10000 instead for linux (which is also hackish) for image files. >>>> So I guess if we would do a psw restart instead (like you do) on a kernel image >>>> the normal ipl would also fail.... >>> >>> FWIW, zipl also loads linux kernels from 0x10000 >> >> OK, I just checked, and indeed, if I change to code to jump to 0x10000, >> it also works when setting a value into 184. So I'll change this patch >> here accordingly. > > This will of course break loading non-Linux binaries. > Could we maybe check 0x10008 for S390EP (see head.S) which indicates Linux since 3.2 or so > and only in that case change the address to 0x10000? Sounds like a good idea! I assume load_iso_bc_entry() in bootmap.c should use that mechanism, too? And what about hw/s390/ipl.c, should we change the code there, too? Thomas
On 04/26/2018 05:43 AM, Thomas Huth wrote: > On 25.04.2018 18:03, Christian Borntraeger wrote: >> >> >> On 04/25/2018 05:36 PM, Thomas Huth wrote: >>> On 25.04.2018 14:44, Christian Borntraeger wrote: >>>> >>>> >>>> On 04/25/2018 02:41 PM, Christian Borntraeger wrote: >>>>> You load from address 0. >>>>> >>>>> On 04/25/2018 02:34 PM, Thomas Huth wrote: >>>>>> On 25.04.2018 14:18, Christian Borntraeger wrote: >>>>>>> >>>>>>> On 04/25/2018 11:08 AM, Thomas Huth wrote: >>>>>>> >>>>>>>> --- a/pc-bios/s390-ccw/netmain.c >>>>>>>> +++ b/pc-bios/s390-ccw/netmain.c >>>>>>>> @@ -283,6 +283,15 @@ void panic(const char *string) >>>>>>>> } >>>>>>>> } >>>>>>>> >>>>>>>> +void write_subsystem_identification(void) >>>>>>>> +{ >>>>>>>> + uint32_t *schid = (uint32_t *) 184; >>>>>>>> + uint32_t *zeroes = (uint32_t *) 188; >>>>>>>> + >>>>>>>> + *schid = 0; /* We must not set this for virtio-net */ >>>>>>>> + *zeroes = 0; >>>>>>>> +} >>>>>>>> + >>>>>>> >>>>>>> I think we actually want to have the CCW devno of that network device >>>>>>> stored. It has some value to know which CCW device we bootet from, no? >>>>>> >>>>>> Actually, I tried that first (and it took quite some time to debug it), >>>>>> but the Linux kernel then bails out quite early, without any error >>>>>> message. The trace looks like this: >>>>>> >>>>>> 0x0000000007801802: diag %r1,%r1,776 >>>>>> 0x0000000007801780: larl %r2,0x7831004 >>>>>> 0x0000000007801786: llgf %r1,8 >>>>>> 0x000000000780178c: mvc 0(12,%r0),0(%r2) >>>>>> 0x0000000007801792: br %r1 >>>>>> 0x0000000000000418: bas %r14,512 >>>>>> 0x0000000000000200: mvi 163,1 >>>>>> 0x0000000000000204: slr %r0,%r0 >>>>>> 0x0000000000000206: lhi %r1,2 >>>>>> 0x000000000000020a: sigp %r1,%r0,18 >>>>>> 0x000000000000020e: bras %r13,0x252 >>>>>> 0x0000000000000252: lmh %r0,%r15,0(%r13) >>>>>> 0x0000000000000258: sam31 >>>>>> 0x000000000000025a: br %r14 >>>>>> 0x000000000000041c: lh %r1,184 >>>>>> 0x0000000000000420: bct %r1,1322 >>>>>> 0x0000000000000424: l %r1,184 >>>>>> 0x0000000000000428: la %r2,1840 >>>>>> 0x000000000000042c: bas %r14,640 >>>>>> 0x0000000000000280: la %r4,0(%r14) >>>>>> 0x0000000000000284: la %r3,792 >>>>>> 0x0000000000000288: la %r5,804 >>>>>> 0x000000000000028c: la %r6,888 >>>>>> 0x0000000000000290: la %r7,20 >>>>>> 0x0000000000000294: st %r2,4(%r6) >>>>>> 0x0000000000000298: la %r2,80(%r2) >>>>>> 0x000000000000029c: la %r6,8(%r6) >>>>>> 0x00000000000002a0: bct %r7,660 >>>>>> 0x00000000000002a4: lctl %c6,%c6,868 >>>>>> 0x00000000000002a8: slr %r2,%r2 >>>>>> 0x00000000000002aa: ssch 0(%r3) >>>>>> 0x00000000000002ae: bne 786 >>>>>> 0x0000000000000312: lpsw 880 >>>>>> Guest crashed on cpu 0: disabled-wait >>>>>> PSW: 0x000a000000000000 0x0000000000000000 >>>>>> >>>>>> That's the Lloader function in arch/s390/kernel/head.S which is failing >>>>>> here, so seems like Linux tries to load from a block device in case >>>>>> there is a value in 184. Thus I assume that 184 has to contain 0 in this >>>>>> case. >>>>> >>>>> Hmm, I think this is because we jump to 418 for your kernel (which is the loader >>>>> that tries to bootstrap the ccw ipl). When you look at ipl.c we override that >>>>> and jump to 0x10000 instead for linux (which is also hackish) for image files. >>>>> So I guess if we would do a psw restart instead (like you do) on a kernel image >>>>> the normal ipl would also fail.... >>>> >>>> FWIW, zipl also loads linux kernels from 0x10000 >>> >>> OK, I just checked, and indeed, if I change to code to jump to 0x10000, >>> it also works when setting a value into 184. So I'll change this patch >>> here accordingly. >> >> This will of course break loading non-Linux binaries. >> Could we maybe check 0x10008 for S390EP (see head.S) which indicates Linux since 3.2 or so >> and only in that case change the address to 0x10000? > > Sounds like a good idea! I assume load_iso_bc_entry() in bootmap.c > should use that mechanism, too? And what about hw/s390/ipl.c, should we > change the code there, too? Yes, we should fix them all.
diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile index 1712c2d..439e3cc 100644 --- a/pc-bios/s390-ccw/Makefile +++ b/pc-bios/s390-ccw/Makefile @@ -9,7 +9,9 @@ $(call set-vpath, $(SRC_PATH)/pc-bios/s390-ccw) .PHONY : all clean build-all -OBJECTS = start.o main.o bootmap.o sclp.o virtio.o virtio-scsi.o virtio-blkdev.o libc.o menu.o +OBJECTS = start.o main.o bootmap.o jump2ipl.o sclp.o menu.o \ + virtio.o virtio-scsi.o virtio-blkdev.o libc.o + QEMU_CFLAGS := $(filter -W%, $(QEMU_CFLAGS)) QEMU_CFLAGS += -ffreestanding -fno-delete-null-pointer-checks -msoft-float QEMU_CFLAGS += -march=z900 -fPIE -fno-strict-aliasing diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c index 9287b7a..7e63e6b 100644 --- a/pc-bios/s390-ccw/bootmap.c +++ b/pc-bios/s390-ccw/bootmap.c @@ -29,14 +29,6 @@ /* Scratch space */ static uint8_t sec[MAX_SECTOR_SIZE*4] __attribute__((__aligned__(PAGE_SIZE))); -typedef struct ResetInfo { - uint32_t ipl_mask; - uint32_t ipl_addr; - uint32_t ipl_continue; -} ResetInfo; - -static ResetInfo save; - const uint8_t el_torito_magic[] = "EL TORITO SPECIFICATION" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; @@ -57,53 +49,6 @@ static inline bool is_iso_vd_valid(IsoVolDesc *vd) vd->type <= VOL_DESC_TYPE_PARTITION; } -static void jump_to_IPL_2(void) -{ - ResetInfo *current = 0; - - void (*ipl)(void) = (void *) (uint64_t) current->ipl_continue; - *current = save; - ipl(); /* should not return */ -} - -static void jump_to_IPL_code(uint64_t address) -{ - /* store the subsystem information _after_ the bootmap was loaded */ - write_subsystem_identification(); - - /* prevent unknown IPL types in the guest */ - if (iplb.pbt == S390_IPL_TYPE_QEMU_SCSI) { - iplb.pbt = S390_IPL_TYPE_CCW; - set_iplb(&iplb); - } - - /* - * The IPL PSW is at address 0. We also must not overwrite the - * content of non-BIOS memory after we loaded the guest, so we - * save the original content and restore it in jump_to_IPL_2. - */ - ResetInfo *current = 0; - - save = *current; - current->ipl_addr = (uint32_t) (uint64_t) &jump_to_IPL_2; - current->ipl_continue = address & 0x7fffffff; - - debug_print_int("set IPL addr to", current->ipl_continue); - - /* Ensure the guest output starts fresh */ - sclp_print("\n"); - - /* - * HACK ALERT. - * We use the load normal reset to keep r15 unchanged. jump_to_IPL_2 - * can then use r15 as its stack pointer. - */ - asm volatile("lghi 1,1\n\t" - "diag 1,1,0x308\n\t" - : : : "1", "memory"); - panic("\n! IPL returns !\n"); -} - /*********************************************************************** * IPL an ECKD DASD (CDL or LDL/CMS format) */ @@ -727,13 +672,7 @@ static void load_iso_bc_entry(IsoBcSection *load) (void *)((uint64_t)bswap16(s.load_segment)), blks_to_load); - /* Trying to get PSW at zero address */ - if (*((uint64_t *)0) & IPL_PSW_MASK) { - jump_to_IPL_code((*((uint64_t *)0)) & 0x7fffffff); - } - - /* Try default linux start address */ - jump_to_IPL_code(KERN_IMAGE_START); + jump_to_low_kernel(); } static uint32_t find_iso_bc(void) diff --git a/pc-bios/s390-ccw/bootmap.h b/pc-bios/s390-ccw/bootmap.h index 07eb600..bef81ff 100644 --- a/pc-bios/s390-ccw/bootmap.h +++ b/pc-bios/s390-ccw/bootmap.h @@ -355,10 +355,6 @@ static inline uint32_t iso_733_to_u32(uint64_t x) #define ISO_SECTOR_SIZE 2048 /* El Torito specifies boot image size in 512 byte blocks */ #define ET_SECTOR_SHIFT 2 -#define KERN_IMAGE_START 0x010000UL -#define PSW_MASK_64 0x0000000100000000ULL -#define PSW_MASK_32 0x0000000080000000ULL -#define IPL_PSW_MASK (PSW_MASK_32 | PSW_MASK_64) #define ISO_PRIMARY_VD_SECTOR 16 diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c new file mode 100644 index 0000000..21b25d8 --- /dev/null +++ b/pc-bios/s390-ccw/jump2ipl.c @@ -0,0 +1,81 @@ +/* + * QEMU s390-ccw firmware - jump to IPL code + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at + * your option) any later version. See the COPYING file in the top-level + * directory. + */ + +#include "libc.h" +#include "s390-ccw.h" + +#define KERN_IMAGE_START 0x010000UL +#define PSW_MASK_64 0x0000000100000000ULL +#define PSW_MASK_32 0x0000000080000000ULL +#define IPL_PSW_MASK (PSW_MASK_32 | PSW_MASK_64) + +typedef struct ResetInfo { + uint32_t ipl_mask; + uint32_t ipl_addr; + uint32_t ipl_continue; +} ResetInfo; + +static ResetInfo save; + +static void jump_to_IPL_2(void) +{ + ResetInfo *current = 0; + + void (*ipl)(void) = (void *) (uint64_t) current->ipl_continue; + *current = save; + ipl(); /* should not return */ +} + +void jump_to_IPL_code(uint64_t address) +{ + /* store the subsystem information _after_ the bootmap was loaded */ + write_subsystem_identification(); + + /* prevent unknown IPL types in the guest */ + if (iplb.pbt == S390_IPL_TYPE_QEMU_SCSI) { + iplb.pbt = S390_IPL_TYPE_CCW; + set_iplb(&iplb); + } + + /* + * The IPL PSW is at address 0. We also must not overwrite the + * content of non-BIOS memory after we loaded the guest, so we + * save the original content and restore it in jump_to_IPL_2. + */ + ResetInfo *current = 0; + + save = *current; + current->ipl_addr = (uint32_t) (uint64_t) &jump_to_IPL_2; + current->ipl_continue = address & 0x7fffffff; + + debug_print_int("set IPL addr to", current->ipl_continue); + + /* Ensure the guest output starts fresh */ + sclp_print("\n"); + + /* + * HACK ALERT. + * We use the load normal reset to keep r15 unchanged. jump_to_IPL_2 + * can then use r15 as its stack pointer. + */ + asm volatile("lghi 1,1\n\t" + "diag 1,1,0x308\n\t" + : : : "1", "memory"); + panic("\n! IPL returns !\n"); +} + +void jump_to_low_kernel(void) +{ + /* Trying to get PSW at zero address */ + if (*((uint64_t *)0) & IPL_PSW_MASK) { + jump_to_IPL_code((*((uint64_t *)0)) & 0x7fffffff); + } + + /* Try default linux start address */ + jump_to_IPL_code(KERN_IMAGE_START); +} diff --git a/pc-bios/s390-ccw/netboot.mak b/pc-bios/s390-ccw/netboot.mak index a25d238..4f64128 100644 --- a/pc-bios/s390-ccw/netboot.mak +++ b/pc-bios/s390-ccw/netboot.mak @@ -1,7 +1,8 @@ SLOF_DIR := $(SRC_PATH)/roms/SLOF -NETOBJS := start.o sclp.o virtio.o virtio-net.o netmain.o libnet.a libc.a +NETOBJS := start.o sclp.o virtio.o virtio-net.o jump2ipl.o netmain.o \ + libnet.a libc.a LIBC_INC := -nostdinc -I$(SLOF_DIR)/lib/libc/include LIBNET_INC := -I$(SLOF_DIR)/lib/libnet diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c index 8fa9e6c..5f28ea0 100644 --- a/pc-bios/s390-ccw/netmain.c +++ b/pc-bios/s390-ccw/netmain.c @@ -283,6 +283,15 @@ void panic(const char *string) } } +void write_subsystem_identification(void) +{ + uint32_t *schid = (uint32_t *) 184; + uint32_t *zeroes = (uint32_t *) 188; + + *schid = 0; /* We must not set this for virtio-net */ + *zeroes = 0; +} + static bool find_net_dev(Schib *schib, int dev_no) { int i, r; @@ -365,7 +374,7 @@ void main(void) if (rc > 0) { sclp_print("Network loading done, starting kernel...\n"); - asm volatile (" lpsw 0(%0) " : : "r"(0) : "memory"); + jump_to_low_kernel(); } panic("Failed to load OS from network\n"); diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h index fd18da2..d88e637 100644 --- a/pc-bios/s390-ccw/s390-ccw.h +++ b/pc-bios/s390-ccw/s390-ccw.h @@ -87,6 +87,10 @@ ulong get_second(void); /* bootmap.c */ void zipl_load(void); +/* jump2ipl.c */ +void jump_to_IPL_code(uint64_t address); +void jump_to_low_kernel(void); + /* menu.c */ void menu_set_parms(uint8_t boot_menu_flag, uint32_t boot_menu_timeout); int menu_get_zipl_boot_index(const char *menu_data);
The netboot firmware so far simply jumped directly into the OS kernel after the download has been completed. This, however, bears the risk that the virtio-net device still might be active in the background and incoming packets are still placed into the buffers - which could destroy memory of the now-running Linux kernel in case it did not take over the device fast enough. Also the SCLP console is not put into a well-defined state here. We should hand over the system in a clean state when jumping into the kernel, so let's use the same mechanism as it's done in the main s390-ccw firmware and reset the machine with diag308 into a clean state before jumping into the OS kernel code. To be able to share the code with the main s390-ccw firmware, the related functions are now extracted from bootmap.c into a new file called jump2ipl.c. Signed-off-by: Thomas Huth <thuth@redhat.com> --- pc-bios/s390-ccw/Makefile | 4 ++- pc-bios/s390-ccw/bootmap.c | 63 +--------------------------------- pc-bios/s390-ccw/bootmap.h | 4 --- pc-bios/s390-ccw/jump2ipl.c | 81 ++++++++++++++++++++++++++++++++++++++++++++ pc-bios/s390-ccw/netboot.mak | 3 +- pc-bios/s390-ccw/netmain.c | 11 +++++- pc-bios/s390-ccw/s390-ccw.h | 4 +++ 7 files changed, 101 insertions(+), 69 deletions(-) create mode 100644 pc-bios/s390-ccw/jump2ipl.c