1. 24 Oct, 2023 28 commits
  2. 19 Oct, 2023 4 commits
  3. 18 Oct, 2023 7 commits
    • Thomas Gleixner's avatar
      x86/microcode/32: Move early loading after paging enable · 0b62f6cb
      Thomas Gleixner authored
      32-bit loads microcode before paging is enabled. The commit which
      introduced that has zero justification in the changelog. The cover
      letter has slightly more content, but it does not give any technical
      justification either:
      
        "The problem in current microcode loading method is that we load a
         microcode way, way too late; ideally we should load it before turning
         paging on.  This may only be practical on 32 bits since we can't get
         to 64-bit mode without paging on, but we should still do it as early
         as at all possible."
      
      Handwaving word salad with zero technical content.
      
      Someone claimed in an offlist conversation that this is required for
      curing the ATOM erratum AAE44/AAF40/AAG38/AAH41. That erratum requires
      an microcode update in order to make the usage of PSE safe. But during
      early boot, PSE is completely irrelevant and it is evaluated way later.
      
      Neither is it relevant for the AP on single core HT enabled CPUs as the
      microcode loading on the AP is not doing anything.
      
      On dual core CPUs there is a theoretical problem if a split of an
      executable large page between enabling paging including PSE and loading
      the microcode happens. But that's only theoretical, it's practically
      irrelevant because the affected dual core CPUs are 64bit enabled and
      therefore have paging and PSE enabled before loading the microcode on
      the second core. So why would it work on 64-bit but not on 32-bit?
      
      The erratum:
      
        "AAG38 Code Fetch May Occur to Incorrect Address After a Large Page is
         Split Into 4-Kbyte Pages
      
         Problem: If software clears the PS (page size) bit in a present PDE
         (page directory entry), that will cause linear addresses mapped through
         this PDE to use 4-KByte pages instead of using a large page after old
         TLB entries are invalidated. Due to this erratum, if a code fetch uses
         this PDE before the TLB entry for the large page is invalidated then it
         may fetch from a different physical address than specified by either the
         old large page translation or the new 4-KByte page translation. This
         erratum may also cause speculative code fetches from incorrect addresses."
      
      The practical relevance for this is exactly zero because there is no
      splitting of large text pages during early boot-time, i.e. between paging
      enable and microcode loading, and neither during CPU hotplug.
      
      IOW, this load microcode before paging enable is yet another voodoo
      programming solution in search of a problem. What's worse is that it causes
      at least two serious problems:
      
       1) When stackprotector is enabled, the microcode loader code has the
          stackprotector mechanics enabled. The read from the per CPU variable
          __stack_chk_guard is always accessing the virtual address either
          directly on UP or via %fs on SMP. In physical address mode this
          results in an access to memory above 3GB. So this works by chance as
          the hardware returns the same value when there is no RAM at this
          physical address. When there is RAM populated above 3G then the read
          is by chance the same as nothing changes that memory during the very
          early boot stage. That's not necessarily true during runtime CPU
          hotplug.
      
       2) When function tracing is enabled, the relevant microcode loader
          functions and the functions invoked from there will call into the
          tracing code and evaluate global and per CPU variables in physical
          address mode. What could potentially go wrong?
      
      Cure this and move the microcode loading after the early paging enable, use
      the new temporary initrd mapping and remove the gunk in the microcode
      loader which is required to handle physical address mode.
      Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
      Signed-off-by: default avatarBorislav Petkov (AMD) <bp@alien8.de>
      Link: https://lore.kernel.org/r/20231017211722.348298216@linutronix.de
      0b62f6cb
    • Thomas Gleixner's avatar
      x86/boot/32: Temporarily map initrd for microcode loading · 4c585af7
      Thomas Gleixner authored
      Early microcode loading on 32-bit runs in physical address mode because
      the initrd is not covered by the initial page tables. That results in
      a horrible mess all over the microcode loader code.
      
      Provide a temporary mapping for the initrd in the initial page tables by
      appending it to the actual initial mapping starting with a new PGD or
      PMD depending on the configured page table levels ([non-]PAE).
      
      The page table entries are located after _brk_end so they are not
      permanently using memory space. The mapping is invalidated right away in
      i386_start_kernel() after the early microcode loader has run.
      
      This prepares for removing the physical address mode oddities from all
      over the microcode loader code, which in turn allows further cleanups.
      
      Provide the map and unmap code and document the place where the
      microcode loader needs to be invoked with a comment.
      Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
      Signed-off-by: default avatarBorislav Petkov (AMD) <bp@alien8.de>
      Link: https://lore.kernel.org/r/20231017211722.292291436@linutronix.de
      4c585af7
    • Thomas Gleixner's avatar
      x86/microcode: Provide CONFIG_MICROCODE_INITRD32 · fdbd4381
      Thomas Gleixner authored
      Create an aggregate config switch which covers X86_32, MICROCODE and
      BLK_DEV_INITRD to avoid lengthy #ifdeffery in upcoming code.
      Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
      Signed-off-by: default avatarBorislav Petkov (AMD) <bp@alien8.de>
      Link: https://lore.kernel.org/r/20231017211722.236208250@linutronix.de
      fdbd4381
    • Thomas Gleixner's avatar
      x86/boot/32: Restructure mk_early_pgtbl_32() · 69ba866d
      Thomas Gleixner authored
      Prepare it for adding a temporary initrd mapping by splitting out the
      actual map loop.
      
      No functional change.
      Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
      Signed-off-by: default avatarBorislav Petkov (AMD) <bp@alien8.de>
      Link: https://lore.kernel.org/r/20231017211722.175910753@linutronix.de
      69ba866d
    • Thomas Gleixner's avatar
      x86/boot/32: De-uglify the 2/3 level paging difference in mk_early_pgtbl_32() · a62f4ca1
      Thomas Gleixner authored
      Move the ifdeffery out of the function and use proper typedefs to make it
      work for both 2 and 3 level paging.
      
      No functional change.
      
        [ bp: Move mk_early_pgtbl_32() declaration into a header. ]
      Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
      Signed-off-by: default avatarBorislav Petkov (AMD) <bp@alien8.de>
      Link: https://lore.kernel.org/r/20231017211722.111059491@linutronix.de
      a62f4ca1
    • Thomas Gleixner's avatar
      x86/boot: Use __pa_nodebug() in mk_early_pgtbl_32() · 1e2dd572
      Thomas Gleixner authored
      Use the existing macro instead of undefining and redefining __pa().
      
      No functional change.
      Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
      Signed-off-by: default avatarBorislav Petkov (AMD) <bp@alien8.de>
      Link: https://lore.kernel.org/r/20231017211722.051625827@linutronix.de
      1e2dd572
    • Thomas Gleixner's avatar
      x86/boot/32: Disable stackprotector and tracing for mk_early_pgtbl_32() · 242db758
      Thomas Gleixner authored
      Stackprotector cannot work before paging is enabled. The read from the per
      CPU variable __stack_chk_guard is always accessing the virtual address
      either directly on UP or via FS on SMP. In physical address mode this
      results in an access to memory above 3GB.
      
      So this works by chance as the hardware returns the same value when there
      is no RAM at this physical address. When there is RAM populated above 3G
      then the read is by chance the same as nothing changes that memory during
      the very early boot stage.
      
      Stop relying on pure luck and disable the stack protector for the only C
      function which is called during early boot before paging is enabled.
      
      Remove function tracing from the whole source file as there is no way to
      trace this at all, but in case of CONFIG_DYNAMIC_FTRACE=n
      mk_early_pgtbl_32() would access global function tracer variables in
      physical address mode which again might work by chance.
      Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
      Signed-off-by: default avatarBorislav Petkov (AMD) <bp@alien8.de>
      Link: https://lore.kernel.org/r/20231002115902.156063939@linutronix.de
      242db758
  4. 17 Oct, 2023 1 commit