----- Original Message ----- > > And complicating matters even further, your patch presumes that the > kernel has configured CONFIG_SPARSEMEM_EXTREME in conjunction with > CONFIG_SPARSEMEM. Would it be possible for an s390x to be configured > with just CONFIG_SPARSEMEM alone? If so, your patch breaks down. > > Or is there another way you can determine which MAX_PHYSMEM_BITS value > is in use? > > Dave > Using your scheme, this is the best I can come up with (untested): --- s390x.c 10 Nov 2011 14:37:15 -0000 1.57 +++ s390x.c 21 Dec 2011 17:07:20 -0000 @@ -282,6 +282,43 @@ } } +static int +set_s390x_max_physmem_bits(void) +{ + int array_len, dimension; + + if (!kernel_symbol_exists("mem_section")) + return TRUE; + + if (!(array_len = get_array_length("mem_section", &dimension, 0)) + return FALSE; + + /* + * If not CONFIG_SPARSEMEM_EXTREME, presume the older 42. + */ + if (dimension) { + machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_OLD; + return TRUE; + } + + /* + * The older s390x kernels uses _MAX_PHYSMEM_BITS as 42 and the + * newer kernels uses 46 bits. + */ + STRUCT_SIZE_INIT(mem_section, "mem_section"); + machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_OLD; + if ((array_len == (NR_MEM_SECTIONS() / _SECTIONS_PER_ROOT_EXTREME())) + || (array_len == (NR_MEM_SECTIONS() / _SECTIONS_PER_ROOT()))) + return TRUE; + + machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_NEW; + if ((array_len == (NR_MEM_SECTIONS() / _SECTIONS_PER_ROOT_EXTREME())) + || (array_len == (NR_MEM_SECTIONS() / _SECTIONS_PER_ROOT()))) + return TRUE; + + return FALSE; +} + /* * Do all necessary machine-specific setup here. This is called several * times during initialization. @@ -350,7 +387,8 @@ if (!machdep->hz) machdep->hz = HZ; machdep->section_size_bits = _SECTION_SIZE_BITS; - machdep->max_physmem_bits = _MAX_PHYSMEM_BITS; + if (!set_s390x_max_physmem_bits()) + error(FATAL, "cannot determine MAX_PHYSMEM_BITS"); s390x_offsets_init(); break; -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility