tech-kern archive

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

Two possible bugs in rbus_ppb.c



While refactoring the relevant code I think I have found two possible
bugs there.

a) Off-by-one of iobustags / membustags storage (possible stack
   corruption?)

b) PCI-to-PCI bridge configuration register settings

(I have not tested these.)

Masao

#
#
# patch "sys/dev/cardbus/rbus_ppb.c"
#  from [891aa91742cd04246904d8268d9566b7d9f44195]
#    to [7c693cc01ec41729e47831672c9d8117d3233845]
# 
# patch "sys/dev/pci/ppbreg.h"
#  from [43f864a682729c2799b83a1513223231beedc4ed]
#    to [6c68ef9987b2fc57aec3decb8ad8f81ec5504d8a]
#
============================================================
--- sys/dev/cardbus/rbus_ppb.c  891aa91742cd04246904d8268d9566b7d9f44195
+++ sys/dev/cardbus/rbus_ppb.c  7c693cc01ec41729e47831672c9d8117d3233845
@@ -260,8 +260,8 @@ rbus_pci_addr_fixup(struct ppb_cardbus_s
        size = sizeof(bus_size_t)*(maxbus+1);
        rct.bussize_ioreqs  = alloca(size);
        rct.bussize_memreqs = alloca(size);
-       rct.iobustags = alloca(maxbus * sizeof(rbus_tag_t));
-       rct.membustags = alloca(maxbus * sizeof(rbus_tag_t));
+       rct.iobustags = alloca((maxbus + 1) * sizeof(rbus_tag_t));
+       rct.membustags = alloca((maxbus + 1) * sizeof(rbus_tag_t));
 
        bzero(rct.bussize_ioreqs, size);
        bzero(rct.bussize_memreqs, size);
@@ -404,10 +404,10 @@ rbus_pci_addr_fixup(struct ppb_cardbus_s
 
            /* now init the limit register for I/O */
            pci_conf_write(pc, pci_bus_tag[busnum], PPB_REG_IOSTATUS,
-                          (((start & 0xf000) >> 8) << PPB_IOBASE_SHIFT) |
+                          (((start & PPB_IO_MASK) >> PPB_IO_SHIFT) << 
PPB_IOBASE_SHIFT) |
                           ((((start +
                               rct.bussize_ioreqs[busnum] +
-                              4095) & 0xf000) >> 8) << PPB_IOLIMIT_SHIFT));
+                              PPB_IO_MIN - 1) & PPB_IO_MASK) >> PPB_IO_SHIFT) 
<< PPB_IOLIMIT_SHIFT));
          }
 
          if(rct.bussize_memreqs[busnum]) {
@@ -444,8 +444,8 @@ rbus_pci_addr_fixup(struct ppb_cardbus_s
                            >> PPB_MEM_SHIFT) << PPB_MEMBASE_SHIFT |
                           (((start +
                             rct.bussize_memreqs[busnum] +
-                             PPB_MEM_MIN-1) >> PPB_MEM_SHIFT)
-                           << PPB_MEMLIMIT_SHIFT));
+                             PPB_MEM_MIN-1) & PPB_MEM_MASK) >> PPB_MEM_SHIFT)
+                           << PPB_MEMLIMIT_SHIFT);
 
            /* and set the prefetchable limits as well */
            pci_conf_write(pc, pci_bus_tag[busnum], PPB_REG_PREFMEM,
@@ -453,8 +453,8 @@ rbus_pci_addr_fixup(struct ppb_cardbus_s
                            >> PPB_MEM_SHIFT) << PPB_MEMBASE_SHIFT |
                           (((start +
                             rct.bussize_memreqs[busnum] +
-                             PPB_MEM_MIN-1) >> PPB_MEM_SHIFT)
-                           << PPB_MEMLIMIT_SHIFT));
+                             PPB_MEM_MIN-1) & PPB_MEM_MASK) >> PPB_MEM_SHIFT)
+                           << PPB_MEMLIMIT_SHIFT);
 
            /* pci_conf_print(pc, pci_bus_tag[busnum], NULL); */
          }
============================================================
--- sys/dev/pci/ppbreg.h        43f864a682729c2799b83a1513223231beedc4ed
+++ sys/dev/pci/ppbreg.h        6c68ef9987b2fc57aec3decb8ad8f81ec5504d8a
@@ -77,7 +77,8 @@
 #define PPB_IOBASE_SHIFT   0
 #define PPB_IOLIMIT_SHIFT  8
 #define PPB_IO_MASK   0xf000
-#define PPB_IO_MIN    4096
+#define PPB_IO_SHIFT  12
+#define PPB_IO_MIN    (1 << PPB_IO_SHIFT)
 
 /*
  * secondary bus memory base and limits
@@ -85,8 +86,8 @@
 #define PPB_MEMBASE_SHIFT  0
 #define PPB_MEMLIMIT_SHIFT 16
 #define PPB_MEM_MASK   0xfff00000
-#define PPB_MEM_SHIFT  16
-#define PPB_MEM_MIN    0x00100000
+#define PPB_MEM_SHIFT  20
+#define PPB_MEM_MIN    (1 << PPB_MEM_SHIFT)
 
 /*
  * bridge control register (see table 3.9 of ppb rev. 1.1)


Home | Main Index | Thread Index | Old Index