Re: Calxeda Midway crashes on boot with KVM on 3.14-rc

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

 



On Thu, 20 Feb 2014 10:54:53 +0000
Marc Zyngier <marc.zyngier@xxxxxxx> wrote:

> On 20/02/14 10:14, Marc Zyngier wrote:
> > Hi Lorenzo,
> > 
> > On 20/02/14 09:47, Lorenzo Pieralisi wrote:
> >> On Wed, Feb 19, 2014 at 09:34:21PM +0000, Rob Herring wrote:
> >>> On Wed, Feb 19, 2014 at 9:41 AM, Lorenzo Pieralisi
> >>
> >> [...]
> >>
> >>>> diff --git a/drivers/cpuidle/cpuidle-calxeda.c
> >>>> b/drivers/cpuidle/cpuidle-calxeda.c index 6e51114..5034f7a 100644
> >>>> --- a/drivers/cpuidle/cpuidle-calxeda.c
> >>>> +++ b/drivers/cpuidle/cpuidle-calxeda.c
> >>>> @@ -41,9 +41,12 @@ static int calxeda_pwrdown_idle(struct
> >>>> cpuidle_device *dev, struct cpuidle_driver *drv,
> >>>>                                 int index)
> >>>>  {
> >>>> +       int ret;
> >>>> +
> >>>>         cpu_pm_enter();
> >>>> -       cpu_suspend(0, calxeda_idle_finish);
> >>>> -       cpu_pm_exit();
> >>>> +       ret = cpu_suspend(0, calxeda_idle_finish);
> >>>> +       if (!ret)
> >>>> +               cpu_pm_exit();
> >>>
> >>> It seems a little strange that the enter does not have to be
> >>> balanced with an exit call. Couldn't the enter tear down things
> >>> that need to be re-enabled?
> >>
> >> That's why I mentioned it is not a proper fix, just wanted to
> >> check my assumptions. There are multiple solutions to this
> >> problem, but the only one which is proper IMHO is for KVM to
> >> either "reset registers" on cpu_pm_enter (CPU_PM_ENTER in
> >> hyp_init_cpu_pm_notifier), or to avoid executing the hyp init code
> >> if a proper registers settings is detected when the cpu_pm_exit is
> >> triggered (CPU_PM_EXIT).
> >>
> >> Is there a way for KVM to simply detect it has nothing to do (ie,
> >> detect hyp mode is already initialized and it has nothing to do) ?
> >>
> >> There is no way in the kernel to guarantee the processor has been
> >> reset, I could infer that from return paths (ie cpu_suspend
> >> returning 0) but that's still not correct.
> > 
> > We really need to distinguish two cases:
> > - CPU is coming back with its registers intact: nothing to do.
> > - CPU is coming back after having being reset and is coming back
> > from the secondary boot path: we need to reinstall the KVM vectors
> > and stack.
> > 
> >>From EL1, there is absolutely no chance we can guess what is the
> >>state
> > of EL2. So I guess there is only two solutions:
> > - Get an indication that the CPU was reset or not: can we actually
> > get that information? I have the idea of a per-cpu variable
> > indicating if we're coming from reset of not, but that feels
> > tricky. A hypercall indicating the state of the HYP mode (free:
> > re-init, engaged: do nothing) feels slightly better.
> > - Always deactivate KVM on PM_ENTER: bloody expensive (requires
> > switching EL2 to some form of idmap, deactivate the MMU, reinstall
> > the original vectors), specially if we already know that this is
> > useless.
> > 
> > So I'd favour the first solution. Thoughts?
> 
> A quick and dirty, fully untested patch:
> 
> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> index 1d8248e..bd18bb8 100644
> --- a/arch/arm/kvm/arm.c
> +++ b/arch/arm/kvm/arm.c
> @@ -878,7 +878,8 @@ static int hyp_init_cpu_pm_notifier(struct
> notifier_block *self, unsigned long cmd,
>  				    void *v)
>  {
> -	if (cmd == CPU_PM_EXIT) {
> +	if (cmd == CPU_PM_EXIT &&
> +	    __hyp_get_vectors() == hyp_default_vectors) {
>  		cpu_init_hyp_mode(NULL);
>  		return NOTIFY_OK;
>  	}
> diff --git a/arch/arm/kvm/interrupts.S b/arch/arm/kvm/interrupts.S
> index ddc1553..25e8a47 100644
> --- a/arch/arm/kvm/interrupts.S
> +++ b/arch/arm/kvm/interrupts.S
> @@ -363,6 +363,10 @@ hyp_hvc:
>  host_switch_to_hyp:
>  	pop	{r0, r1, r2}
>  
> +	cmp	r0, #-1
> +	mrceq	p15, 4, r0, c12, c0, 0	@ get HVBAR
> +	beq	eret_host
> +
>  	push	{lr}
>  	mrs	lr, SPSR
>  	push	{lr}
> @@ -378,6 +382,7 @@ THUMB(	orr	lr, #1)
>  	pop	{lr}
>  	msr	SPSR_csxf, lr
>  	pop	{lr}
> +eret_host:
>  	eret
>  
>  guest_trap:
> 
> 
> 
> Andre, can you please back out Lorenzo's patch and test
> this one instead?

Marc, Lorenzo:

So both patches work. I had to disable my debug messages, though - they
are so many that they are blocking progress. So I cannot really say
what's going on now, but definitely still many suspends/resumes, but
the system looks fine and KVM seems to work.

I looked into the PSCI firmware code, indeed it does not do anything
except a wfi and returning -3 if only this core should be suspended.
There is code to power-down the whole cluster (all 4 cores) through the
management processor (including cache disabling and stuff), but there
is no real power-gating or even state/cache changes if just a single
core should be handled. In fact I wonder if this is wrong in the
firmware since it returns to lr instead to the address in r2 (even for
state type 1).

Rob, can you confirm this?

Regards,
Andre.
_______________________________________________
kvmarm mailing list
kvmarm@xxxxxxxxxxxxxxxxxxxxx
https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm




[Index of Archives]     [Linux KVM]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux