>Synopsis:      bug in powerpc pmap.c
>Category:      kernel
>Environment:
        System      : OpenBSD 6.3
        Details     : OpenBSD 6.3-current (GENERIC.MP) #10: Mon Jul  9 14:57:07 
CEST 2018
                         
p...@iota.centroid.eu:/usr/src/sys/arch/macppc/compile/GENERIC.MP

        Architecture: OpenBSD.macppc
        Machine     : macppc
>Description:
        Hi, in several spots (for the G5) in sys/arch/powerpc/powerpc/pmap.c 
there is a call to pteidx() shortly after that is construct such as:
--
        /* first just try fill of primary hash */
        ptp64 = pmap_ptable64 + (idx) * 8;
--

        I believe in the design this is wrong, follow me:

        If a system has 64 MB RAM, there is 16384 pages max.  This means that
        in pmap_bootstrap()  pmap_ptab_cnt = 8192 pages and pmap_ptab_mask is
        equal to 8191 pages, this multiplied with HTABMEMSZ_64 is the extent of 
        the paging table area.
        
        The result of the idx from pteidx() is in pages not any other number.
        it is also AND'ed on return with pmap_ptab_mask and thus cannot be
        larger than 8191 pages.

        ptp64 = pmap_ptable64 + (idx) * 8;
        
        should be rewritten as:

        ptp64 = pmap_ptable64;
        ptp64 += (idx * 8);

        Because pmap_ptable64 is an offset in physical RAM (a pointer).
        ptp64 is a struct pte_64 * which has size 16 bytes (2 64 bit ints).

        so when pteidx() returns maximum 8191 pages as idx, it's really
        16 bytes * 8191 pages * 8 in the formula which equals 1048448 bytes.
        which is exactly at the boundary of HTABMEMSZ_64 (8191 * 8 * 16).

        With "ptp64 = pmap_ptable64 + (idx) * 8" that is not achieved so
        some PTEG's never get reached.  What it does is it sees the (idx) * 8
        as an offset to address of pmap_ptable64.

        I have provided a test program that shows the hex locations of both
        methods to back this up.   It's in the how to repeat section.

        Maybe I'm just confused though, for that I apologize if I'm wrong here.

>How-To-Repeat:
#include <sys/types.h>
#include <stdio.h>

int
main(void)
{
        char *addresslocation;
        struct {
                u_int64_t a;
                u_int64_t b;
        } *mys;

        int pmap_ptab_cnt = 8192;
        int pmap_ptab_mask = 8191;
        
        addresslocation = malloc(64 * 1024 * 1024);
        if (addresslocation == NULL)
                exit(1);

        mys = addresslocation;

        printf("start: %llx\n", addresslocation);

        printf("mys before\n");
        printf("mys: %llx\n", mys);

        mys = addresslocation + (pmap_ptab_mask) * 8;

        printf("mys: %llx\n", mys);
        printf("mys after\n");
        
        mys = addresslocation;
        printf("mys: %llx\n", mys);

        mys += pmap_ptab_mask * 8;
        printf("mys: %llx\n", mys);
}
>Fix:
        I have made a patch and tested it once.  The machine is still alive.
Index: pmap.c
===================================================================
RCS file: /cvs/src/sys/arch/powerpc/powerpc/pmap.c,v
retrieving revision 1.167
diff -u -p -u -r1.167 pmap.c
--- pmap.c      16 May 2017 20:52:54 -0000      1.167
+++ pmap.c      9 Jul 2018 12:54:34 -0000
@@ -2334,7 +2334,9 @@ pte_insert64(struct pte_desc *pted)
         */
 
        /* first just try fill of primary hash */
-       ptp64 = pmap_ptable64 + (idx) * 8;
+       ptp64 = pmap_ptable64;
+       ptp64 += (idx) * 8;
+       
        for (i = 0; i < 8; i++) {
                if (ptp64[i].pte_hi & PTE_VALID_64)
                        continue;
@@ -2352,7 +2354,8 @@ pte_insert64(struct pte_desc *pted)
        }
 
        /* try fill of secondary hash */
-       ptp64 = pmap_ptable64 + (idx ^ pmap_ptab_mask) * 8;
+       ptp64 = pmap_ptable64;
+       ptp64 += (idx ^ pmap_ptab_mask) * 8;
        for (i = 0; i < 8; i++) {
                if (ptp64[i].pte_hi & PTE_VALID_64)
                        continue;
@@ -2378,7 +2381,8 @@ pte_insert64(struct pte_desc *pted)
 
        idx = (idx ^ (PTED_HID(pted) ? pmap_ptab_mask : 0));
 
-       ptp64 = pmap_ptable64 + (idx * 8);
+       ptp64 = pmap_ptable64;
+       ptp64 += (idx * 8);
        ptp64 += PTED_PTEGIDX(pted); /* increment by index into pteg */
 
        if (ptp64->pte_hi & PTE_VALID_64) {


dmesg:
OpenBSD 6.3-current (GENERIC.MP) #10: Mon Jul  9 14:57:07 CEST 2018
    p...@iota.centroid.eu:/usr/src/sys/arch/macppc/compile/GENERIC.MP
real mem = 4294963200 (4095MB)
avail mem = 2020466688 (1926MB)
mpath0 at root
scsibus0 at mpath0: 256 targets
mainbus0 at root: model PowerMac7,3
cpu0 at mainbus0: 970FX (Revision 0x300): 1800 MHz
cpu1 at mainbus0: 970FX (Revision 0x300): 1800 MHz
mem0 at mainbus0
spdmem0 at mem0: 1GB DDR SDRAM non-parity PC3200CL2.5
spdmem1 at mem0: 1GB DDR SDRAM non-parity PC3200CL2.5
spdmem2 at mem0: 1GB DDR SDRAM non-parity PC3200CL2.5
spdmem3 at mem0: 1GB DDR SDRAM non-parity PC3200CL2.5
memc0 at mainbus0: u3 rev 0xb3
kiic0 at memc0 offset 0xf8001000
iic0 at kiic0
lmtemp0 at iic0 addr 0x4a: ds1775
maxtmp0 at iic0 addr 0x4c: max6690
maxtmp1 at iic0 addr 0x4e: max6690
"cy28508" at iic0 addr 0x69 not configured
"cy2213" at iic0 addr 0x65 not configured
fcu0 at iic0 addr 0xaf
"pca9556" at iic0 addr 0x18 not configured
adc0 at iic0 addr 0x2c: ad7417
"24256" at iic0 addr 0x50 not configured
"pca9556" at iic0 addr 0x19 not configured
adc1 at iic0 addr 0x2d: ad7417
"24256" at iic0 addr 0x51 not configured
"dart" at memc0 offset 0xf8033000 not configured
"mpic" at memc0 offset 0xf8040000 not configured
mpcpcibr0 at mainbus0 pci: u3-agp
pci0 at mpcpcibr0 bus 0
pchb0 at pci0 dev 11 function 0 "Apple U3 AGP" rev 0x00
appleagp0 at pchb0
agp0 at appleagp0: aperture at 0x0, size 0x10000000
vgafb0 at pci0 dev 16 function 0 "NVIDIA GeForce FX 5200 Ultra" rev 0xa1
wsdisplay0 at vgafb0 mux 1: console (std, vt100 emulation)
wsdisplay0: screen 1-5 added (std, vt100 emulation)
ht0 at mainbus0: u3-ht, 6 devices
pci1 at ht0 bus 0
hpb0 at pci1 dev 1 function 0 "Apple U3" rev 0x00: 85 sources
pci2 at hpb0 bus 1
macobio0 at pci2 dev 7 function 0 "Apple K2 Macio" rev 0x60
openpic0 at macobio0 offset 0x40000: version 0x4614 feature 770302 LE
macgpio0 at macobio0 offset 0x50
"pmu-interrupt" at macgpio0 offset 0x9 not configured
"programmer-switch" at macgpio0 offset 0x11 not configured
"modem-reset" at macgpio0 offset 0x1d not configured
"modem-power" at macgpio0 offset 0x1e not configured
"fcu-interrupt" at macgpio0 offset 0x15 not configured
"fcu-hw-reset" at macgpio0 offset 0x3a not configured
"slewing-done" at macgpio0 offset 0x23 not configured
"codec-input-data-mux" at macgpio0 offset 0xb not configured
"line-input-detect" at macgpio0 offset 0xc not configured
"codec-error-irq" at macgpio0 offset 0xd not configured
"dig-hw-reset" at macgpio0 offset 0x14 not configured
"line-output-detect" at macgpio0 offset 0x16 not configured
"headphone-detect" at macgpio0 offset 0x17 not configured
"codec-irq" at macgpio0 offset 0x18 not configured
"headphone-mute" at macgpio0 offset 0x1f not configured
"amp-mute" at macgpio0 offset 0x20 not configured
"hw-reset" at macgpio0 offset 0x24 not configured
"line-output-mute" at macgpio0 offset 0x25 not configured
"codec-clock-mux" at macgpio0 offset 0x26 not configured
"escc-legacy" at macobio0 offset 0x12000 not configured
zs0 at macobio0 offset 0x13000: irq 22,23
zstty0 at zs0 channel 0
zstty1 at zs0 channel 1
kiic1 at macobio0 offset 0x18000
iic1 at kiic1
aoa0 at macobio0 offset 0x10000: irq 30,1,2
"timer" at macobio0 offset 0x15000 not configured
adb0 at macobio0 offset 0x16000
apm0 at adb0: battery flags 0x9, 0% charged
piic0 at adb0
iic2 at piic0
"fans" at macobio0 offset 0x4c not configured
audio0 at aoa0
ohci0 at pci2 dev 8 function 0 "Apple K2 USB" rev 0x00: irq 27, version 1.0, 
legacy support
ohci1 at pci2 dev 9 function 0 "Apple K2 USB" rev 0x00: irq 28, version 1.0, 
legacy support
usb0 at ohci0: USB revision 1.0
uhub0 at usb0 configuration 1 interface 0 "Apple OHCI root hub" rev 1.00/1.00 
addr 1
usb1 at ohci1: USB revision 1.0
uhub1 at usb1 configuration 1 interface 0 "Apple OHCI root hub" rev 1.00/1.00 
addr 1
ppb0 at pci1 dev 2 function 0 "Apple U3" rev 0x00
pci3 at ppb0 bus 5
bwi0 at pci3 dev 1 function 0 "Broadcom BCM4306" rev 0x03: irq 57, address 
00:11:24:9c:01:82
ohci2 at pci3 dev 11 function 0 "NEC USB" rev 0x43: irq 63, version 1.0
ohci3 at pci3 dev 11 function 1 "NEC USB" rev 0x43: irq 63, version 1.0
ehci0 at pci3 dev 11 function 2 "NEC USB" rev 0x04: irq 63
usb2 at ehci0: USB revision 2.0
uhub2 at usb2 configuration 1 interface 0 "NEC EHCI root hub" rev 2.00/1.00 
addr 1
usb3 at ohci2: USB revision 1.0
uhub3 at usb3 configuration 1 interface 0 "NEC OHCI root hub" rev 1.00/1.00 
addr 1
usb4 at ohci3: USB revision 1.0
uhub4 at usb4 configuration 1 interface 0 "NEC OHCI root hub" rev 1.00/1.00 
addr 1
ppb1 at pci1 dev 3 function 0 "Apple U3" rev 0x00
pci4 at ppb1 bus 2
kauaiata0 at pci4 dev 13 function 0 "Apple K2 ATA" rev 0x00
wdc0 at kauaiata0 irq 39: DMA
atapiscsi0 at wdc0 channel 0 drive 0
scsibus1 at atapiscsi0: 2 targets
cd0 at scsibus1 targ 0 lun 0: <SONY, DVD RW DW-U21A, AADB> ATAPI 5/cdrom 
removable
cd0(wdc0:0:0): using PIO mode 4, DMA mode 2, Ultra-DMA mode 4
"Apple K2 Firewire" rev 0x00 at pci4 dev 14 function 0 not configured
ppb2 at pci1 dev 4 function 0 "Apple U3" rev 0x00
pci5 at ppb2 bus 3
gem0 at pci5 dev 15 function 0 "Apple K2 GMAC" rev 0x00: irq 41, address 
00:0d:93:4e:ab:48
brgphy0 at gem0 phy 1: BCM54K2 10/100/1000baseT PHY, rev. 0
ppb3 at pci1 dev 5 function 0 "Apple U3" rev 0x00
pci6 at ppb3 bus 4
pciide0 at pci6 dev 12 function 0 "ServerWorks K2 SATA" rev 0x00: DMA
pciide0: using irq 0 for native-PCI interrupt
pciide0: port 0: 1.5Gb/s
wd0 at pciide0 channel 0 drive 0: <SAMSUNG HD321KJ>
wd0: 16-sector PIO, LBA48, 305245MB, 625142448 sectors
wd0(pciide0:0:0): using PIO mode 4, Ultra-DMA mode 6
pciide0: port 1: PHY offline
pciide0: port 2: PHY offline
pciide0: port 3: PHY offline
uhub5 at uhub3 port 1 configuration 1 interface 0 "Macally Macally iKey" rev 
1.10/0.01 addr 2
uhidev0 at uhub5 port 1 configuration 1 interface 0 "Macally Macally iKey" rev 
1.10/0.01 addr 3
uhidev0: iclass 3/1
ukbd0 at uhidev0: 8 variable keys, 6 key codes
wskbd0 at ukbd0: console keyboard, using wsdisplay0
uhidev1 at uhub4 port 2 configuration 1 interface 0 "Logitech USB Optical 
Mouse" rev 2.00/43.01 addr 2
uhidev1: iclass 3/1
ums0 at uhidev1: 3 buttons, Z dir
wsmouse0 at ums0 mux 0
uhidev2 at uhub0 port 1 configuration 1 interface 0 "Apple Computer HID-proxy" 
rev 1.10/12.41 addr 2
uhidev2: iclass 3/1
ukbd1 at uhidev2: 8 variable keys, 6 key codes
wskbd1 at ukbd1 mux 1
wskbd1: connecting to wsdisplay0
uhidev3 at uhub0 port 1 configuration 1 interface 1 "Apple Computer HID-proxy" 
rev 1.10/12.41 addr 2
uhidev3: iclass 3/1
ums1 at uhidev3: 5 buttons
wsmouse1 at ums1 mux 0
vscsi0 at root
scsibus2 at vscsi0: 256 targets
softraid0 at root
scsibus3 at softraid0: 256 targets
bootpath: /ht/pci@5/k2-sata-root/k2-sata@0/disk@0:/bsd
root on wd0a (ea996edcb5614d4d.a) swap on wd0b dump on wd0b

usbdevs:
Controller /dev/usb0:
addr 01: 106b:0000 Apple, OHCI root hub
         full speed, self powered, config 1, rev 1.00
addr 02: 05ac:1000 Apple Computer, HID-proxy
         full speed, self powered, config 1, rev 12.41
Controller /dev/usb1:
addr 01: 106b:0000 Apple, OHCI root hub
         full speed, self powered, config 1, rev 1.00
Controller /dev/usb2:
addr 01: 1033:0000 NEC, EHCI root hub
         high speed, self powered, config 1, rev 1.00
Controller /dev/usb3:
addr 01: 1033:0000 NEC, OHCI root hub
         full speed, self powered, config 1, rev 1.00
addr 02: 2222:0200 Macally, Macally iKey
         full speed, power 100 mA, config 1, rev 0.01
addr 03: 2222:0003 Macally, Macally iKey
         full speed, self powered, config 1, rev 0.01
Controller /dev/usb4:
addr 01: 1033:0000 NEC, OHCI root hub
         full speed, self powered, config 1, rev 1.00
addr 02: 046d:c018 Logitech, USB Optical Mouse
         low speed, power 100 mA, config 1, rev 43.01

Reply via email to