> Date: Wed, 22 May 2019 00:40:24 -0700
> From: Mike Larkin <[email protected]>
> 
> On Tue, May 21, 2019 at 12:33:24AM +0200, Mark Kettenis wrote:
> > > Date: Sat, 18 May 2019 05:58:39 +0200 (CEST)
> > > From: Mark Kettenis <[email protected]>
> > > 
> > > > Date: Fri, 17 May 2019 17:56:52 -0400
> > > > From: Patrick Wildt <[email protected]>
> > > > 
> > > > Hi,
> > > > 
> > > > claudio@ has a Kaby Lake that exceeds the 128 kB limit, being as big as
> > > > 190 kB.  So, for him the ucode isn't being loaded.
> > > > 
> > > > On EFI systems we can simply ask EFI to allocate some memory for us.
> > > > I'm not sure why this file is duplicated 4 times, but it looks like
> > > > for efiboot this one is currently the file to patch.
> > > > 
> > > > This diff works for claudio@'s EFI booted system.  Since I don't know
> > > > how much space is available on legacy systems I will not attempt to
> > > > fix this for the legacy bootloader.  Someone that knows more than me
> > > > about x86 can attempt that.
> > > > 
> > > > Feedback? ok?
> > > 
> > > In principle, ye, that is the right approach.
> > > 
> > > However, until Mike gets us to the point where we no longer care at
> > > which physical address the kernel was loaded, efiboot will move the
> > > kernel to a specific physical address after loading it and potentially
> > > thrash all memory allocated through the EFI interfaces.  So there is a
> > > change that we will overwrite the microcode at that point.
> > > 
> > > So it might actually be safer to just change the limit to 256k if
> > > there is a good chance the the memory at the 1MB mark is unlikely to
> > > be used by anything else.
> > 
> > Actually, since we always move the kernel to 16MB, we can use
> > AllocateMaxAddress to allocate a large enough block of memory below
> > that.  So the diff below should work (and does on my Skylake system
> > that uses a 100k firmware).
> > 
> > ok?
> > 
> 
> While I am frightened about gigantisch microcodes and EFI trying to
> fit things into lowmem below the ISA hole, I suppose it knows what
> it's doing.

If EFI needs the lowmem, it won't give it to us.  When the EFI memory
map gets converted to an old-style BIOS memory map, this block of
memory will be marked free, so the lowmem gobbled up here will remain
available to our kernel.  The kernel copies the ucode to a safe place
early on.  I'm not convinced that happens early enough though, but
that's not a new problem...

> ok mlarkin, not sure how you want to integrate this into the MDS
> stuff that is being worked on though. I'll take care of merging this
> into efi32/efi64 when I'm ready.

Should we also fix biosboot?  The machines that are affected are all
fairly recent and should boot using UEFI by default...

I have no clue if/how this should be handled as an errata/syspatch.


> > Index: arch/amd64/stand/efiboot/exec_i386.c
> > ===================================================================
> > RCS file: /cvs/src/sys/arch/amd64/stand/efiboot/exec_i386.c,v
> > retrieving revision 1.1
> > diff -u -p -r1.1 exec_i386.c
> > --- arch/amd64/stand/efiboot/exec_i386.c    10 May 2019 21:20:42 -0000      
> > 1.1
> > +++ arch/amd64/stand/efiboot/exec_i386.c    20 May 2019 22:25:38 -0000
> > @@ -46,8 +46,13 @@
> >  #include "softraid_amd64.h"
> >  #endif
> >  
> > +#include <efi.h>
> > +#include <efiapi.h>
> > +#include "eficall.h"
> >  #include "efiboot.h"
> >  
> > +extern EFI_BOOT_SERVICES   *BS;
> > +
> >  typedef void (*startfuncp)(int, int, int, int, int, int, int, int)
> >      __attribute__ ((noreturn));
> >  
> > @@ -165,6 +170,7 @@ run_loadfile(uint64_t *marks, int howto)
> >  void
> >  ucode_load(void)
> >  {
> > +   EFI_PHYSICAL_ADDRESS addr;
> >     uint32_t model, family, stepping;
> >     uint32_t dummy, signature;
> >     uint32_t vendor[4];
> > @@ -200,12 +206,13 @@ ucode_load(void)
> >             return;
> >  
> >     buflen = sb.st_size;
> > -   if (buflen > 128*1024) {
> > -           printf("ucode too large\n");
> > +   addr = 16 * 1024 * 1024;
> > +   if (EFI_CALL(BS->AllocatePages, AllocateMaxAddress, EfiLoaderData,
> > +       EFI_SIZE_TO_PAGES(buflen), &addr) != EFI_SUCCESS) {
> > +           printf("cannot allocate memory for ucode\n");
> >             return;
> >     }
> > -
> > -   buf = (char *)(1*1024*1024);
> > +   buf = (char *)((paddr_t)addr);
> >  
> >     if (read(fd, buf, buflen) != buflen) {
> >             close(fd);
> > 
> > 
> 

Reply via email to