On Thu, Jul 05, 2018 at 11:20:51AM +0200, Mark Kettenis wrote:
> > So sorry, it was erroneous... second attempt.  The first attempt wasn't 
> > safe 
> > for replies from OFW that were of size 0.  Also on my box the dmesg starts 
> > like so on this:
> 
> Sorry, but this isn't quite right.  What the code should really do is
> count all memory below the 4G boundary.  Since part if the phyical
> address space is reserved for devices that will be less < 4GB.
> 
> Yes that means that dmesg will not report the full amount of memory in
> the machine.  But you can't use that memory anyway on a 32-bit OpenBSD
> system.  And if the physmem variable includes a lot of memory that
> isn't actually usable, the kernel will make bad choices in sizing
> various things.
> 
> Cheers,
> 
> Mark

Hi Mark,

That makes perfect sense.  I adjusted my patch and wonder if you like it?
The patch takes a "pagelimit" which is UINT_MAX >> PAGE_SHIFT and doesn't
allow page counts over that.  This way is guaranteed that there is never
an overflow.  It perhaps isn't the classiest patch out there.

Here is what the dmesg reports from real memory from the last patch and below
it the real memory from this patch.

iota# dmesg | grep ^real\ mem
real mem = 4294950912 (4095MB)
real mem = 4294963200 (4095MB)

Regards,
-peter


Index: ofw_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/macppc/macppc/ofw_machdep.c,v
retrieving revision 1.56
diff -u -p -u -r1.56 ofw_machdep.c
--- ofw_machdep.c       22 Jul 2017 18:33:38 -0000      1.56
+++ ofw_machdep.c       5 Jul 2018 11:51:35 -0000
@@ -131,9 +131,10 @@ ppc_mem_regions(struct mem_region **memp
 void
 ofw_read_mem_regions(int phandle, int address_cells, int size_cells)
 {
+       const uint pagelimit = (UINT_MAX >> PAGE_SHIFT);
        int nreg, navail;
        int i, j;
-       uint physpages;
+       uint physpages, tmp;
 
        switch (address_cells) {
        default:
@@ -171,16 +172,26 @@ ofw_read_mem_regions(int phandle, int ad
        case 2:
                physpages = 0;
                for (i = 0, j = 0; i < nreg; i++) {
-                       if (OFmem64[i].size == 0)
+                       if ((tmp = OFmem64[i].size) == 0)
                                continue;
-                       physpages += atop(OFmem64[i].size);
+
+                       /*
+                        * restrict overflows to constant pagelimit,
+                        * even if > 4 GB of memory exist in the machine
+                        */
+
+                       if (physpages + atop(tmp) > pagelimit)
+                               physpages = pagelimit;
+                       else
+                               physpages += atop(tmp);
+
                        if (OFmem64[i].start >= 1ULL << 32)
                                continue;
                        OFmem[j].start = OFmem64[i].start;
-                       if (OFmem64[i].start + OFmem64[i].size >= 1ULL << 32)
+                       if (OFmem64[i].start + tmp >= 1ULL << 32)
                                OFmem[j].size = (1ULL << 32) - OFmem64[i].start;
                        else
-                               OFmem[j].size = OFmem64[i].size;
+                               OFmem[j].size = tmp;
                        j++;
                }
                physmem = physpages;

Reply via email to