Re: [kvm-unit-tests PATCH v1 1/1] lib/s390x: fix SMP setup bug

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, 19 Aug 2022 10:52:40 +0200
Janosch Frank <frankja@xxxxxxxxxxxxx> wrote:

> On 8/18/22 17:21, Claudio Imbrenda wrote:
> > The lowcore pointer pointing to the current CPU (THIS_CPU) was not
> > initialized for the boot CPU. The pointer is needed for correct
> > interrupt handling, which is needed in the setup process before the
> > struct cpu array is allocated.
> > 
> > The bug went unnoticed because some environments (like qemu/KVM) clear
> > all memory and don't write anything in the lowcore area before starting
> > the payload. The pointer thus pointed to 0, an area of memory also not
> > used. Other environments will write to memory before starting the
> > payload, causing the unit tests to crash at the first interrupt.
> > 
> > Fix by assigning a temporary struct cpu before the rest of the setup
> > process, and assigning the pointer to the correct allocated struct
> > during smp initialization.
> > 
> > Fixes: 4e5dd758 ("lib: s390x: better smp interrupt checks")
> > Signed-off-by: Claudio Imbrenda <imbrenda@xxxxxxxxxxxxx>  
> 
> I've considered letting the IPL cpu have a static struct cpu and setting 
> it up in cstart64.S. But that would mean that we would need extra 
> handling when using smp functions and that'll look even worse.
> 
> Reported-by: Janosch Frank <frankja@xxxxxxxxxxxxx>
> 
> > ---
> >   lib/s390x/io.c  | 9 +++++++++
> >   lib/s390x/smp.c | 1 +
> >   2 files changed, 10 insertions(+)
> > 
> > diff --git a/lib/s390x/io.c b/lib/s390x/io.c
> > index a4f1b113..fb7b7dda 100644
> > --- a/lib/s390x/io.c
> > +++ b/lib/s390x/io.c
> > @@ -33,6 +33,15 @@ void puts(const char *s)
> >   
> >   void setup(void)
> >   {
> > +	struct cpu this_cpu_tmp = { 0 };  
> 
> We can setup these struct members here and memcpy in smp_setup()
> .addr = stap();
> .stack = stackptr;

stackptr is accessible in io.c (I would need to add an extern
declaration)

> .lowcore = (void *)0;
> .active = true;

this temporary struct is then not accessible from smp_setup, so it
can't be memcpy-ed.

if you really want something meaningful in the temporary struct, it has
to be initialized in smp.c and called in io.c (something like
smp_boot_cpu_tmp_setup(&this_cpu_tmp) ), but then still no memcpy.

in the end the struct cpu is needed only to allow interrupts to happen
without crashes, I don't think we strictly need initialization

> 
> 
> > +
> > +	/*
> > +	 * Set a temporary empty struct cpu for the boot CPU, needed for
> > +	 * correct interrupt handling in the setup process.
> > +	 * smp_setup will allocate and set the permanent one.
> > +	 */
> > +	THIS_CPU = &this_cpu_tmp;
> > +
> >   	setup_args_progname(ipl_args);
> >   	setup_facilities();
> >   	sclp_read_info();
> > diff --git a/lib/s390x/smp.c b/lib/s390x/smp.c
> > index 0d98c17d..03d6d2a4 100644
> > --- a/lib/s390x/smp.c
> > +++ b/lib/s390x/smp.c
> > @@ -353,6 +353,7 @@ void smp_setup(void)
> >   			cpus[0].stack = stackptr;
> >   			cpus[0].lowcore = (void *)0;
> >   			cpus[0].active = true;
> > +			THIS_CPU = &cpus[0];  
> 
> /* Override temporary struct cpu address with permanent one */

will be done

> 
> >   		}
> >   	}
> >   	spin_unlock(&lock);  
> 




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux