----- Original Message ----- > Hello Dave and Mahesh, > > We also tried to solve the problem and came up with an alternative > solution. > > The function s390x_max_physmem_bits() solves the following equation: > > array_len == NR_MEM_SECTIONS / SECTIONS_PER_ROOT > > 2^(MAX_PYSMEM_BITS - SECTION_SIZE_BITS) > --------------------------------------- > == PAGE_SIZE > ------------------------- > sizeof(struct mem_section) > > This leads to the following: > > MAX_PYSMEM_BITS == SECTION_SIZE_BITS + log2(array_len) + > log2(PAGE_SIZE) > - log2(sizeof(struct mem_section)); > > I tested the patch with 42 and 46 bits and for both it seems to work. > I will leave now for vacation and will return January the 9th 2012. > > I leave it to you which solution to take. No -- I leave to you guys to decide. I appreciate the simplicity of your solution, but Mahesh's patch is easier to understand. So please decide before you go home -- I was hoping to get a release out today! > Merry Christmas! > > Michael > > PS: I think this patch also fixes a bug in verify_ptn()... > BTOP vs. PTOB :-) Hey, you're right! Dave > --- > kernel.c | 2 +- > memory.c | 2 +- > s390x.c | 17 ++++++++++++++++- > 3 files changed, 18 insertions(+), 3 deletions(-) > > --- a/kernel.c > +++ b/kernel.c > @@ -275,7 +275,7 @@ kernel_init() > MEMBER_OFFSET_INIT(prio_array_nr_active, "prio_array", > "nr_active"); > STRUCT_SIZE_INIT(runqueue, rqstruct); > STRUCT_SIZE_INIT(prio_array, "prio_array"); > - > + STRUCT_SIZE_INIT(mem_section, "mem_section"); > MEMBER_OFFSET_INIT(rq_cfs, "rq", "cfs"); > > /* > --- a/memory.c > +++ b/memory.c > @@ -13601,7 +13601,7 @@ verify_pfn(ulong pfn) > for (i = machdep->max_physmem_bits; i < machdep->bits; i++) > mask |= ((physaddr_t)1 << i); > > - if (mask & BTOP(pfn)) > + if (mask & PTOB(pfn)) > return FALSE; > > return TRUE; > --- a/s390x.c > +++ b/s390x.c > @@ -17,6 +17,7 @@ > */ > #ifdef S390X > #include <elf.h> > +#include <math.h> > #include "defs.h" > #include "netdump.h" > > @@ -283,6 +284,19 @@ static void s390x_process_elf_notes(void > } > > /* > + * The older s390x kernels use _MAX_PHYSMEM_BITS as 42 and the > + * newer kernels use 46 bits. This function calculates the bits > + * via a generic function. > + */ > +static int s390x_max_physmem_bits(void) > +{ > + unsigned long array_len = get_array_length("mem_section", NULL, 0); > + > + return _SECTION_SIZE_BITS + log2(array_len) + 12 /* log2(PAGE_SIZE) > */ > + - log2(SIZE(mem_section)); > +} > + > +/* > * Do all necessary machine-specific setup here. This is called > several > * times during initialization. > */ > @@ -350,13 +364,14 @@ s390x_init(int when) > if (!machdep->hz) > machdep->hz = HZ; > machdep->section_size_bits = _SECTION_SIZE_BITS; > - machdep->max_physmem_bits = _MAX_PHYSMEM_BITS; > + machdep->max_physmem_bits = s390x_max_physmem_bits(); > s390x_offsets_init(); > break; > > case POST_INIT: > break; > } > + fprintf(stderr, "XXX %d\n", machdep->max_physmem_bits); > } > > /* > >