diff mbox

[RFC] spapr: by-pass SLOF when -kernel is provided

Message ID 1467729757-12441-1-git-send-email-lvivier@redhat.com
State New
Headers show

Commit Message

Laurent Vivier July 5, 2016, 2:42 p.m. UTC
As device-tree is now fully built by QEMU, we don't need SLOF
anymore if the kernel is provided on the command line.

In this case, don't load SLOF and boot directly into the
kernel.

This saves at least 5 seconds on the boot sequence.

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
---
 hw/ppc/spapr.c | 37 ++++++++++++++++++++-----------------
 1 file changed, 20 insertions(+), 17 deletions(-)

Comments

Cédric Le Goater July 5, 2016, 5:58 p.m. UTC | #1
On 07/05/2016 04:42 PM, Laurent Vivier wrote:
> As device-tree is now fully built by QEMU, we don't need SLOF
> anymore if the kernel is provided on the command line.
> 
> In this case, don't load SLOF and boot directly into the
> kernel.
> 
> This saves at least 5 seconds on the boot sequence.
> 
> Signed-off-by: Laurent Vivier <lvivier@redhat.com>

Looks good to me. 

It would also be good to have a trimmed version of slof for a kvm 
environment, with only virtio devices. I think Nikunj had started 
to work on a minimal version.

C.


> ---
>  hw/ppc/spapr.c | 37 ++++++++++++++++++++-----------------
>  1 file changed, 20 insertions(+), 17 deletions(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 7f33a1b..bbdb21d 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -1219,8 +1219,11 @@ static void ppc_spapr_reset(void)
>      first_ppc_cpu->env.gpr[3] = spapr->fdt_addr;
>      first_ppc_cpu->env.gpr[5] = 0;
>      first_cpu->halted = 0;
> -    first_ppc_cpu->env.nip = SPAPR_ENTRY_POINT;
> -
> +    if (machine->kernel_filename) {
> +        first_ppc_cpu->env.nip = KERNEL_LOAD_ADDR;
> +    } else {
> +        first_ppc_cpu->env.nip = SPAPR_ENTRY_POINT;
> +    }
>  }
>  
>  static void spapr_create_nvram(sPAPRMachineState *spapr)
> @@ -2023,23 +2026,23 @@ static void ppc_spapr_init(MachineState *machine)
>              initrd_base = 0;
>              initrd_size = 0;
>          }
> +    } else {
> +        if (bios_name == NULL) {
> +            bios_name = FW_FILE_NAME;
> +        }
> +        filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
> +        if (!filename) {
> +            error_report("Could not find LPAR firmware '%s'", bios_name);
> +            exit(1);
> +        }
> +        fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);
> +        if (fw_size <= 0) {
> +            error_report("Could not load LPAR firmware '%s'", filename);
> +            exit(1);
> +        }
> +        g_free(filename);
>      }
>  
> -    if (bios_name == NULL) {
> -        bios_name = FW_FILE_NAME;
> -    }
> -    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
> -    if (!filename) {
> -        error_report("Could not find LPAR firmware '%s'", bios_name);
> -        exit(1);
> -    }
> -    fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);
> -    if (fw_size <= 0) {
> -        error_report("Could not load LPAR firmware '%s'", filename);
> -        exit(1);
> -    }
> -    g_free(filename);
> -
>      /* FIXME: Should register things through the MachineState's qdev
>       * interface, this is a legacy from the sPAPREnvironment structure
>       * which predated MachineState but had a similar function */
>
Greg Kurz July 5, 2016, 6:44 p.m. UTC | #2
On Tue,  5 Jul 2016 16:42:37 +0200
Laurent Vivier <lvivier@redhat.com> wrote:

> As device-tree is now fully built by QEMU, we don't need SLOF
> anymore if the kernel is provided on the command line.
> 
> In this case, don't load SLOF and boot directly into the
> kernel.
> 
> This saves at least 5 seconds on the boot sequence.
> 

The concept looks great so I gave a try with a fedora24 guest.

I copied the kernel and initramfs to the host and passed the kernel arguments
taken from grub.

The kernel starts but the boot sequence stalls at:

[  OK  ] Reached target Basic System.
[  126.238400] dracut-initqueue[290]: Warning: dracut-initqueue timeout - starting timeout scripts

I also noticed this error:

[    0.127303] WARNING: nvram corruption detected: 0-length partition
[    0.127610] nvram: No room to create ibm,rtas-log partition, deleting any obsolete OS partitions...
[    0.128011] nvram: Failed to find or create ibm,rtas-log partition, err -28
[    0.128300] nvram: No room to create lnx,oops-log partition, deleting any obsolete OS partitions...
[    0.128701] nvram: Failed to find or create lnx,oops-log partition, err -28
Linux ppc6400] nvram: Failed to initialize oops partition!

Cc'ing Nikunj who has already worked on booting a guest without SLOF.


> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
> ---
>  hw/ppc/spapr.c | 37 ++++++++++++++++++++-----------------
>  1 file changed, 20 insertions(+), 17 deletions(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 7f33a1b..bbdb21d 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -1219,8 +1219,11 @@ static void ppc_spapr_reset(void)
>      first_ppc_cpu->env.gpr[3] = spapr->fdt_addr;
>      first_ppc_cpu->env.gpr[5] = 0;
>      first_cpu->halted = 0;
> -    first_ppc_cpu->env.nip = SPAPR_ENTRY_POINT;
> -
> +    if (machine->kernel_filename) {
> +        first_ppc_cpu->env.nip = KERNEL_LOAD_ADDR;
> +    } else {
> +        first_ppc_cpu->env.nip = SPAPR_ENTRY_POINT;
> +    }
>  }
>  
>  static void spapr_create_nvram(sPAPRMachineState *spapr)
> @@ -2023,23 +2026,23 @@ static void ppc_spapr_init(MachineState *machine)
>              initrd_base = 0;
>              initrd_size = 0;
>          }
> +    } else {
> +        if (bios_name == NULL) {
> +            bios_name = FW_FILE_NAME;
> +        }
> +        filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
> +        if (!filename) {
> +            error_report("Could not find LPAR firmware '%s'", bios_name);
> +            exit(1);
> +        }
> +        fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);
> +        if (fw_size <= 0) {
> +            error_report("Could not load LPAR firmware '%s'", filename);
> +            exit(1);
> +        }
> +        g_free(filename);
>      }
>  
> -    if (bios_name == NULL) {
> -        bios_name = FW_FILE_NAME;
> -    }
> -    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
> -    if (!filename) {
> -        error_report("Could not find LPAR firmware '%s'", bios_name);
> -        exit(1);
> -    }
> -    fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);
> -    if (fw_size <= 0) {
> -        error_report("Could not load LPAR firmware '%s'", filename);
> -        exit(1);
> -    }
> -    g_free(filename);
> -
>      /* FIXME: Should register things through the MachineState's qdev
>       * interface, this is a legacy from the sPAPREnvironment structure
>       * which predated MachineState but had a similar function */
Laurent Vivier July 5, 2016, 6:51 p.m. UTC | #3
On 05/07/2016 20:44, Greg Kurz wrote:
> On Tue,  5 Jul 2016 16:42:37 +0200
> Laurent Vivier <lvivier@redhat.com> wrote:
> 
>> As device-tree is now fully built by QEMU, we don't need SLOF
>> anymore if the kernel is provided on the command line.
>>
>> In this case, don't load SLOF and boot directly into the
>> kernel.
>>
>> This saves at least 5 seconds on the boot sequence.
>>
> 
> The concept looks great so I gave a try with a fedora24 guest.

I did the same test with a rhel7 vmlinuz adn intramfs and it works fine.

> 
> I copied the kernel and initramfs to the host and passed the kernel arguments
> taken from grub.
> 
> The kernel starts but the boot sequence stalls at:
> 
> [  OK  ] Reached target Basic System.
> [  126.238400] dracut-initqueue[290]: Warning: dracut-initqueue timeout - starting timeout scripts

It happens when the initramfs didn't have the disk driver: do you use
the same disk controller with the "-kernel" than the one which was used
when the initramfs has been created?

> 
> I also noticed this error:
> 
> [    0.127303] WARNING: nvram corruption detected: 0-length partition
> [    0.127610] nvram: No room to create ibm,rtas-log partition, deleting any obsolete OS partitions...
> [    0.128011] nvram: Failed to find or create ibm,rtas-log partition, err -28
> [    0.128300] nvram: No room to create lnx,oops-log partition, deleting any obsolete OS partitions...
> [    0.128701] nvram: Failed to find or create lnx,oops-log partition, err -28
> Linux ppc6400] nvram: Failed to initialize oops partition!

I've also that: perhaps SLOF is initializing the NVRAM when it is empty,
and qemu doesn't?

I will check.

Thanks,
Laurent

> 
> Cc'ing Nikunj who has already worked on booting a guest without SLOF.
> 
> 
>> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
>> ---
>>  hw/ppc/spapr.c | 37 ++++++++++++++++++++-----------------
>>  1 file changed, 20 insertions(+), 17 deletions(-)
>>
>> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
>> index 7f33a1b..bbdb21d 100644
>> --- a/hw/ppc/spapr.c
>> +++ b/hw/ppc/spapr.c
>> @@ -1219,8 +1219,11 @@ static void ppc_spapr_reset(void)
>>      first_ppc_cpu->env.gpr[3] = spapr->fdt_addr;
>>      first_ppc_cpu->env.gpr[5] = 0;
>>      first_cpu->halted = 0;
>> -    first_ppc_cpu->env.nip = SPAPR_ENTRY_POINT;
>> -
>> +    if (machine->kernel_filename) {
>> +        first_ppc_cpu->env.nip = KERNEL_LOAD_ADDR;
>> +    } else {
>> +        first_ppc_cpu->env.nip = SPAPR_ENTRY_POINT;
>> +    }
>>  }
>>  
>>  static void spapr_create_nvram(sPAPRMachineState *spapr)
>> @@ -2023,23 +2026,23 @@ static void ppc_spapr_init(MachineState *machine)
>>              initrd_base = 0;
>>              initrd_size = 0;
>>          }
>> +    } else {
>> +        if (bios_name == NULL) {
>> +            bios_name = FW_FILE_NAME;
>> +        }
>> +        filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
>> +        if (!filename) {
>> +            error_report("Could not find LPAR firmware '%s'", bios_name);
>> +            exit(1);
>> +        }
>> +        fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);
>> +        if (fw_size <= 0) {
>> +            error_report("Could not load LPAR firmware '%s'", filename);
>> +            exit(1);
>> +        }
>> +        g_free(filename);
>>      }
>>  
>> -    if (bios_name == NULL) {
>> -        bios_name = FW_FILE_NAME;
>> -    }
>> -    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
>> -    if (!filename) {
>> -        error_report("Could not find LPAR firmware '%s'", bios_name);
>> -        exit(1);
>> -    }
>> -    fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);
>> -    if (fw_size <= 0) {
>> -        error_report("Could not load LPAR firmware '%s'", filename);
>> -        exit(1);
>> -    }
>> -    g_free(filename);
>> -
>>      /* FIXME: Should register things through the MachineState's qdev
>>       * interface, this is a legacy from the sPAPREnvironment structure
>>       * which predated MachineState but had a similar function */
>
David Gibson July 6, 2016, 1:35 a.m. UTC | #4
On Tue, Jul 05, 2016 at 04:42:37PM +0200, Laurent Vivier wrote:
> As device-tree is now fully built by QEMU, we don't need SLOF
> anymore if the kernel is provided on the command line.
> 
> In this case, don't load SLOF and boot directly into the
> kernel.
> 
> This saves at least 5 seconds on the boot sequence.
> 
> Signed-off-by: Laurent Vivier <lvivier@redhat.com>

I'm not comfortable applying this.  We actually used to do this ages
ago, but changed to always running through SLOF, and there were
reasons for doing so.

I don't remember exactly what they were, but I think it boiled down to
slight differences in state between booting from SLOF and booting
without SLOF leading to confusing errors from the guest kernel.

> ---
>  hw/ppc/spapr.c | 37 ++++++++++++++++++++-----------------
>  1 file changed, 20 insertions(+), 17 deletions(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 7f33a1b..bbdb21d 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -1219,8 +1219,11 @@ static void ppc_spapr_reset(void)
>      first_ppc_cpu->env.gpr[3] = spapr->fdt_addr;
>      first_ppc_cpu->env.gpr[5] = 0;
>      first_cpu->halted = 0;
> -    first_ppc_cpu->env.nip = SPAPR_ENTRY_POINT;
> -
> +    if (machine->kernel_filename) {
> +        first_ppc_cpu->env.nip = KERNEL_LOAD_ADDR;
> +    } else {
> +        first_ppc_cpu->env.nip = SPAPR_ENTRY_POINT;
> +    }
>  }
>  
>  static void spapr_create_nvram(sPAPRMachineState *spapr)
> @@ -2023,23 +2026,23 @@ static void ppc_spapr_init(MachineState *machine)
>              initrd_base = 0;
>              initrd_size = 0;
>          }
> +    } else {
> +        if (bios_name == NULL) {
> +            bios_name = FW_FILE_NAME;
> +        }
> +        filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
> +        if (!filename) {
> +            error_report("Could not find LPAR firmware '%s'", bios_name);
> +            exit(1);
> +        }
> +        fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);
> +        if (fw_size <= 0) {
> +            error_report("Could not load LPAR firmware '%s'", filename);
> +            exit(1);
> +        }
> +        g_free(filename);
>      }
>  
> -    if (bios_name == NULL) {
> -        bios_name = FW_FILE_NAME;
> -    }
> -    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
> -    if (!filename) {
> -        error_report("Could not find LPAR firmware '%s'", bios_name);
> -        exit(1);
> -    }
> -    fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);
> -    if (fw_size <= 0) {
> -        error_report("Could not load LPAR firmware '%s'", filename);
> -        exit(1);
> -    }
> -    g_free(filename);
> -
>      /* FIXME: Should register things through the MachineState's qdev
>       * interface, this is a legacy from the sPAPREnvironment structure
>       * which predated MachineState but had a similar function */
Alexey Kardashevskiy July 6, 2016, 3:33 a.m. UTC | #5
On 06/07/16 11:35, David Gibson wrote:
> On Tue, Jul 05, 2016 at 04:42:37PM +0200, Laurent Vivier wrote:
>> As device-tree is now fully built by QEMU, we don't need SLOF
>> anymore if the kernel is provided on the command line.
>>
>> In this case, don't load SLOF and boot directly into the
>> kernel.
>>
>> This saves at least 5 seconds on the boot sequence.
>>
>> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
> 
> I'm not comfortable applying this.  We actually used to do this ages
> ago, but changed to always running through SLOF, and there were
> reasons for doing so.
> 
> I don't remember exactly what they were, but I think it boiled down to
> slight differences in state between booting from SLOF and booting
> without SLOF leading to confusing errors from the guest kernel.
> 

PCI resource allocation is still done by SLOF (however having them not set
will trigger allocation in the guest but this is rather unexpected
workaround than a feature); "client-architecture-support" won't work
without SLOF either (i.e. compatibile PowerISA 2.0x CPUs).
Greg Kurz July 6, 2016, 7:03 a.m. UTC | #6
On Tue, 5 Jul 2016 20:51:41 +0200
Laurent Vivier <lvivier@redhat.com> wrote:

> On 05/07/2016 20:44, Greg Kurz wrote:
> > On Tue,  5 Jul 2016 16:42:37 +0200
> > Laurent Vivier <lvivier@redhat.com> wrote:
> >   
> >> As device-tree is now fully built by QEMU, we don't need SLOF
> >> anymore if the kernel is provided on the command line.
> >>
> >> In this case, don't load SLOF and boot directly into the
> >> kernel.
> >>
> >> This saves at least 5 seconds on the boot sequence.
> >>  
> > 
> > The concept looks great so I gave a try with a fedora24 guest.  
> 
> I did the same test with a rhel7 vmlinuz adn intramfs and it works fine.
> 
> > 
> > I copied the kernel and initramfs to the host and passed the kernel arguments
> > taken from grub.
> > 
> > The kernel starts but the boot sequence stalls at:
> > 
> > [  OK  ] Reached target Basic System.
> > [  126.238400] dracut-initqueue[290]: Warning: dracut-initqueue timeout - starting timeout scripts  
> 
> It happens when the initramfs didn't have the disk driver: do you use
> the same disk controller with the "-kernel" than the one which was used
> when the initramfs has been created?
> 

Yes. The very same QEMU command line (except -kernel/-initrd/-append) works with
SLOF and fails without SLOF.

> > 
> > I also noticed this error:
> > 
> > [    0.127303] WARNING: nvram corruption detected: 0-length partition
> > [    0.127610] nvram: No room to create ibm,rtas-log partition, deleting any obsolete OS partitions...
> > [    0.128011] nvram: Failed to find or create ibm,rtas-log partition, err -28
> > [    0.128300] nvram: No room to create lnx,oops-log partition, deleting any obsolete OS partitions...
> > [    0.128701] nvram: Failed to find or create lnx,oops-log partition, err -28
> > Linux ppc6400] nvram: Failed to initialize oops partition!  
> 
> I've also that: perhaps SLOF is initializing the NVRAM when it is empty,
> and qemu doesn't?
> 
> I will check.
> 
> Thanks,
> Laurent
> 
> > 
> > Cc'ing Nikunj who has already worked on booting a guest without SLOF.
> > 
> >   
> >> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
> >> ---
> >>  hw/ppc/spapr.c | 37 ++++++++++++++++++++-----------------
> >>  1 file changed, 20 insertions(+), 17 deletions(-)
> >>
> >> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> >> index 7f33a1b..bbdb21d 100644
> >> --- a/hw/ppc/spapr.c
> >> +++ b/hw/ppc/spapr.c
> >> @@ -1219,8 +1219,11 @@ static void ppc_spapr_reset(void)
> >>      first_ppc_cpu->env.gpr[3] = spapr->fdt_addr;
> >>      first_ppc_cpu->env.gpr[5] = 0;
> >>      first_cpu->halted = 0;
> >> -    first_ppc_cpu->env.nip = SPAPR_ENTRY_POINT;
> >> -
> >> +    if (machine->kernel_filename) {
> >> +        first_ppc_cpu->env.nip = KERNEL_LOAD_ADDR;
> >> +    } else {
> >> +        first_ppc_cpu->env.nip = SPAPR_ENTRY_POINT;
> >> +    }
> >>  }
> >>  
> >>  static void spapr_create_nvram(sPAPRMachineState *spapr)
> >> @@ -2023,23 +2026,23 @@ static void ppc_spapr_init(MachineState *machine)
> >>              initrd_base = 0;
> >>              initrd_size = 0;
> >>          }
> >> +    } else {
> >> +        if (bios_name == NULL) {
> >> +            bios_name = FW_FILE_NAME;
> >> +        }
> >> +        filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
> >> +        if (!filename) {
> >> +            error_report("Could not find LPAR firmware '%s'", bios_name);
> >> +            exit(1);
> >> +        }
> >> +        fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);
> >> +        if (fw_size <= 0) {
> >> +            error_report("Could not load LPAR firmware '%s'", filename);
> >> +            exit(1);
> >> +        }
> >> +        g_free(filename);
> >>      }
> >>  
> >> -    if (bios_name == NULL) {
> >> -        bios_name = FW_FILE_NAME;
> >> -    }
> >> -    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
> >> -    if (!filename) {
> >> -        error_report("Could not find LPAR firmware '%s'", bios_name);
> >> -        exit(1);
> >> -    }
> >> -    fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);
> >> -    if (fw_size <= 0) {
> >> -        error_report("Could not load LPAR firmware '%s'", filename);
> >> -        exit(1);
> >> -    }
> >> -    g_free(filename);
> >> -
> >>      /* FIXME: Should register things through the MachineState's qdev
> >>       * interface, this is a legacy from the sPAPREnvironment structure
> >>       * which predated MachineState but had a similar function */  
> >   
>
Greg Kurz July 6, 2016, 7:04 a.m. UTC | #7
On Wed, 6 Jul 2016 13:33:49 +1000
Alexey Kardashevskiy <aik@ozlabs.ru> wrote:

> On 06/07/16 11:35, David Gibson wrote:
> > On Tue, Jul 05, 2016 at 04:42:37PM +0200, Laurent Vivier wrote:  
> >> As device-tree is now fully built by QEMU, we don't need SLOF
> >> anymore if the kernel is provided on the command line.
> >>
> >> In this case, don't load SLOF and boot directly into the
> >> kernel.
> >>
> >> This saves at least 5 seconds on the boot sequence.
> >>
> >> Signed-off-by: Laurent Vivier <lvivier@redhat.com>  
> > 
> > I'm not comfortable applying this.  We actually used to do this ages
> > ago, but changed to always running through SLOF, and there were
> > reasons for doing so.
> > 
> > I don't remember exactly what they were, but I think it boiled down to
> > slight differences in state between booting from SLOF and booting
> > without SLOF leading to confusing errors from the guest kernel.
> >   
> 
> PCI resource allocation is still done by SLOF (however having them not set
> will trigger allocation in the guest but this is rather unexpected
> workaround than a feature); "client-architecture-support" won't work
> without SLOF either (i.e. compatibile PowerISA 2.0x CPUs).
> 

Not even sure the workaround actually works:

I retried with a ppc64le guest and this time I get:

[    1.055922] virtio-pci 0000:00:01.0: virtio_pci: leaving for legacy driver
[    1.056048] virtio-pci: probe of 0000:00:01.0 failed with error -12
[    1.056263] virtio-pci 0000:00:00.0: virtio_pci: leaving for legacy driver
[    1.056373] virtio-pci: probe of 0000:00:00.0 failed with error -12

i.e. virtio_reset() isn't called during probing :-\

--
Greg
Nikunj A Dadhania July 6, 2016, 8:02 a.m. UTC | #8
Alexey Kardashevskiy <aik@ozlabs.ru> writes:

> [ Unknown signature status ]
> On 06/07/16 11:35, David Gibson wrote:
>> On Tue, Jul 05, 2016 at 04:42:37PM +0200, Laurent Vivier wrote:
>>> As device-tree is now fully built by QEMU, we don't need SLOF
>>> anymore if the kernel is provided on the command line.
>>>
>>> In this case, don't load SLOF and boot directly into the
>>> kernel.
>>>
>>> This saves at least 5 seconds on the boot sequence.
>>>
>>> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
>> 
>> I'm not comfortable applying this.  We actually used to do this ages
>> ago, but changed to always running through SLOF, and there were
>> reasons for doing so.
>> 
>> I don't remember exactly what they were, but I think it boiled down to
>> slight differences in state between booting from SLOF and booting
>> without SLOF leading to confusing errors from the guest kernel.
>> 
>
> PCI resource allocation is still done by SLOF (however having them not set
> will trigger allocation in the guest but this is rather unexpected
> workaround than a feature);

I am not sure that works well, i had a work around in qemu for this to get
triggered in guest kernel.

> "client-architecture-support" won't work
> without SLOF either (i.e. compatibile PowerISA 2.0x CPUs).

Right.

Regards
Nikunj
Alexey Kardashevskiy July 6, 2016, 8:04 a.m. UTC | #9
On 06/07/16 18:02, Nikunj A Dadhania wrote:
> Alexey Kardashevskiy <aik@ozlabs.ru> writes:
> 
>> [ Unknown signature status ]
>> On 06/07/16 11:35, David Gibson wrote:
>>> On Tue, Jul 05, 2016 at 04:42:37PM +0200, Laurent Vivier wrote:
>>>> As device-tree is now fully built by QEMU, we don't need SLOF
>>>> anymore if the kernel is provided on the command line.
>>>>
>>>> In this case, don't load SLOF and boot directly into the
>>>> kernel.
>>>>
>>>> This saves at least 5 seconds on the boot sequence.
>>>>
>>>> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
>>>
>>> I'm not comfortable applying this.  We actually used to do this ages
>>> ago, but changed to always running through SLOF, and there were
>>> reasons for doing so.
>>>
>>> I don't remember exactly what they were, but I think it boiled down to
>>> slight differences in state between booting from SLOF and booting
>>> without SLOF leading to confusing errors from the guest kernel.
>>>
>>
>> PCI resource allocation is still done by SLOF (however having them not set
>> will trigger allocation in the guest but this is rather unexpected
>> workaround than a feature);
> 
> I am not sure that works well, i had a work around in qemu for this to get
> triggered in guest kernel.
> 

Creating resource properties (i.e. BARs) with FFFFFFFF in QEMU did the
trick if I remember correctly. Either way, this is a hack.


>> "client-architecture-support" won't work
>> without SLOF either (i.e. compatibile PowerISA 2.0x CPUs).
> 
> Right.
> 
> Regards
> Nikunj
>
Laurent Vivier July 6, 2016, 8:37 a.m. UTC | #10
On 06/07/2016 09:03, Greg Kurz wrote:
> On Tue, 5 Jul 2016 20:51:41 +0200
> Laurent Vivier <lvivier@redhat.com> wrote:
> 
>> On 05/07/2016 20:44, Greg Kurz wrote:
>>> On Tue,  5 Jul 2016 16:42:37 +0200
>>> Laurent Vivier <lvivier@redhat.com> wrote:
>>>   
>>>> As device-tree is now fully built by QEMU, we don't need SLOF
>>>> anymore if the kernel is provided on the command line.
>>>>
>>>> In this case, don't load SLOF and boot directly into the
>>>> kernel.
>>>>
>>>> This saves at least 5 seconds on the boot sequence.
>>>>  
>>>
>>> The concept looks great so I gave a try with a fedora24 guest.  
>>
>> I did the same test with a rhel7 vmlinuz adn intramfs and it works fine.
>>
>>>
>>> I copied the kernel and initramfs to the host and passed the kernel arguments
>>> taken from grub.
>>>
>>> The kernel starts but the boot sequence stalls at:
>>>
>>> [  OK  ] Reached target Basic System.
>>> [  126.238400] dracut-initqueue[290]: Warning: dracut-initqueue timeout - starting timeout scripts  
>>
>> It happens when the initramfs didn't have the disk driver: do you use
>> the same disk controller with the "-kernel" than the one which was used
>> when the initramfs has been created?
>>
> 
> Yes. The very same QEMU command line (except -kernel/-initrd/-append) works with
> SLOF and fails without SLOF.

I think it works for me because I use spapr-vscsi  and spapr-vlan.

Laurent
diff mbox

Patch

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 7f33a1b..bbdb21d 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1219,8 +1219,11 @@  static void ppc_spapr_reset(void)
     first_ppc_cpu->env.gpr[3] = spapr->fdt_addr;
     first_ppc_cpu->env.gpr[5] = 0;
     first_cpu->halted = 0;
-    first_ppc_cpu->env.nip = SPAPR_ENTRY_POINT;
-
+    if (machine->kernel_filename) {
+        first_ppc_cpu->env.nip = KERNEL_LOAD_ADDR;
+    } else {
+        first_ppc_cpu->env.nip = SPAPR_ENTRY_POINT;
+    }
 }
 
 static void spapr_create_nvram(sPAPRMachineState *spapr)
@@ -2023,23 +2026,23 @@  static void ppc_spapr_init(MachineState *machine)
             initrd_base = 0;
             initrd_size = 0;
         }
+    } else {
+        if (bios_name == NULL) {
+            bios_name = FW_FILE_NAME;
+        }
+        filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+        if (!filename) {
+            error_report("Could not find LPAR firmware '%s'", bios_name);
+            exit(1);
+        }
+        fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);
+        if (fw_size <= 0) {
+            error_report("Could not load LPAR firmware '%s'", filename);
+            exit(1);
+        }
+        g_free(filename);
     }
 
-    if (bios_name == NULL) {
-        bios_name = FW_FILE_NAME;
-    }
-    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
-    if (!filename) {
-        error_report("Could not find LPAR firmware '%s'", bios_name);
-        exit(1);
-    }
-    fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);
-    if (fw_size <= 0) {
-        error_report("Could not load LPAR firmware '%s'", filename);
-        exit(1);
-    }
-    g_free(filename);
-
     /* FIXME: Should register things through the MachineState's qdev
      * interface, this is a legacy from the sPAPREnvironment structure
      * which predated MachineState but had a similar function */