Author: arichardson
Date: Mon Jun  8 08:52:02 2020
New Revision: 361905
URL: https://svnweb.freebsd.org/changeset/base/361905

Log:
  RISC-V: Check that the DTB doesn't overlap with kernel
  
  This can happen with very large kernels (e.g. ones embedding a root
  filesystem). The DTB written by OpenSBI/BBL is quite small so this is
  unlikely to hit important data, but if it does this can result in very
  confusing and hard-to-debug crashes. Add a KASSERT() and a verbose print
  to catch this problem with debug kernels.
  
  While this will not print any output by default if it fails (that would
  depend on EARLY_PRINTF), at least the kernel now halts reliably instead
  of randomly crashing.
  
  Reviewed By:  mhorne
  Differential Revision: https://reviews.freebsd.org/D25153

Modified:
  head/sys/riscv/include/machdep.h
  head/sys/riscv/riscv/genassym.c
  head/sys/riscv/riscv/locore.S
  head/sys/riscv/riscv/machdep.c

Modified: head/sys/riscv/include/machdep.h
==============================================================================
--- head/sys/riscv/include/machdep.h    Mon Jun  8 08:51:57 2020        
(r361904)
+++ head/sys/riscv/include/machdep.h    Mon Jun  8 08:52:02 2020        
(r361905)
@@ -42,6 +42,7 @@ struct riscv_bootparams {
        vm_offset_t     kern_phys;      /* Kernel base (physical) addr */
        vm_offset_t     kern_stack;
        vm_offset_t     dtbp_virt;      /* Device tree blob virtual addr */
+       vm_offset_t     dtbp_phys;      /* Device tree blob physical addr */
 };
 
 extern vm_paddr_t physmap[PHYS_AVAIL_ENTRIES];

Modified: head/sys/riscv/riscv/genassym.c
==============================================================================
--- head/sys/riscv/riscv/genassym.c     Mon Jun  8 08:51:57 2020        
(r361904)
+++ head/sys/riscv/riscv/genassym.c     Mon Jun  8 08:52:02 2020        
(r361905)
@@ -106,3 +106,4 @@ ASSYM(RISCV_BOOTPARAMS_KERN_PHYS, offsetof(struct risc
 ASSYM(RISCV_BOOTPARAMS_KERN_STACK, offsetof(struct riscv_bootparams,
     kern_stack));
 ASSYM(RISCV_BOOTPARAMS_DTBP_VIRT, offsetof(struct riscv_bootparams, 
dtbp_virt));
+ASSYM(RISCV_BOOTPARAMS_DTBP_PHYS, offsetof(struct riscv_bootparams, 
dtbp_phys));

Modified: head/sys/riscv/riscv/locore.S
==============================================================================
--- head/sys/riscv/riscv/locore.S       Mon Jun  8 08:51:57 2020        
(r361904)
+++ head/sys/riscv/riscv/locore.S       Mon Jun  8 08:52:02 2020        
(r361905)
@@ -221,6 +221,7 @@ va:
        and     t1, a1, t1
        add     t0, t0, t1
        sd      t0, RISCV_BOOTPARAMS_DTBP_VIRT(sp)
+       sd      a1, RISCV_BOOTPARAMS_DTBP_PHYS(sp)
 
        mv      a0, sp
        call    _C_LABEL(initriscv)     /* Off we go */

Modified: head/sys/riscv/riscv/machdep.c
==============================================================================
--- head/sys/riscv/riscv/machdep.c      Mon Jun  8 08:51:57 2020        
(r361904)
+++ head/sys/riscv/riscv/machdep.c      Mon Jun  8 08:52:02 2020        
(r361905)
@@ -776,8 +776,19 @@ fake_preload_metadata(struct riscv_bootparams *rvbp)
        PRELOAD_PUSH_VALUE(uint32_t, 0);
        preload_metadata = (caddr_t)fake_preload;
 
+       /* Check if bootloader clobbered part of the kernel with the DTB. */
+       KASSERT(rvbp->dtbp_phys + dtb_size <= rvbp->kern_phys ||
+               rvbp->dtbp_phys >= rvbp->kern_phys + (lastaddr - KERNBASE),
+           ("FDT (%lx-%lx) and kernel (%lx-%lx) overlap", rvbp->dtbp_phys,
+               rvbp->dtbp_phys + dtb_size, rvbp->kern_phys,
+               rvbp->kern_phys + (lastaddr - KERNBASE)));
        KASSERT(fake_size < sizeof(fake_preload),
            ("Too many fake_preload items"));
+
+       if (boothowto & RB_VERBOSE)
+               printf("FDT phys (%lx-%lx), kernel phys (%lx-%lx)\n",
+                   rvbp->dtbp_phys, rvbp->dtbp_phys + dtb_size,
+                   rvbp->kern_phys, rvbp->kern_phys + (lastaddr - KERNBASE));
 
        return (lastaddr);
 }
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to