Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
s390/mem_detect: query max possible memory address via diag260 (0xc)
Let's also query the maximum possible memory address via diag260 (0xc).
This will be relevant for QEMU with memory device support (e.g.,
virtio-mem). The value returned via SCLP will not include the reserved
physical address space for memory devices, we have to query it using
diag260.

The doc states for diag260 (0xc):
  "Return the highest addressable byte of virtual storage in the
   host-primary address space, including named saved
   systems and saved segments."

  "Ry: Equal to the highest addressable byte of virtual storage in the
   host-primary address space, including named saved systems and saved
   segments. For example, for a guest with DEFINE STORAGE CONFIG 0.1G 8G.1G
   in effect, Rx would be X'000000003FFFFFFF' and Ry would be
   X'000000023FFFFFFF'."

Usually, "virtual storage in the host" directly corresponds to guest
physical memory. IIRC, there is one exception, when the SIE is called with
"mso" set, so that the guest physical storage starts at an offset inside
host virtual storage. Not used for KVM at least.

Commit d918fe2 ("[S390] Remove diag 0x260 call from memory
detection.") indicates that there were detection issues under z/VM
a decade ago - maybe because of "mso". The values were not safe to
detect initial memory.

We cannot specialise on KVM that early during boot. Therefore, use the
maximum of both values (just in case there are still weird z/VM diag260
implementations) and only query in case diag260 (0x10) succeeded.

Use the same exception handling mechanism as tprot().

Signed-off-by: David Hildenbrand <david@redhat.com>
  • Loading branch information
davidhildenbrand committed Jul 10, 2020
1 parent cb1eff1 commit a235f9f
Showing 1 changed file with 41 additions and 4 deletions.
45 changes: 41 additions & 4 deletions arch/s390/boot/mem_detect.c
Expand Up @@ -63,7 +63,7 @@ void add_mem_detect_block(u64 start, u64 end)
mem_detect.count++;
}

static int __diag260(unsigned long rx1, unsigned long rx2)
static int __diag260_0x10(unsigned long rx1, unsigned long rx2)
{
register unsigned long _rx1 asm("2") = rx1;
register unsigned long _rx2 asm("3") = rx2;
Expand Down Expand Up @@ -91,8 +91,34 @@ static int __diag260(unsigned long rx1, unsigned long rx2)
return rc == 0 ? _ry : -1;
}

static int diag260(void)
static int __diag260_0xc(unsigned long *rx, unsigned long *ry)
{
psw_t old = S390_lowcore.program_new_psw;
unsigned long pgm_addr, _rx, _ry = 0xc;

S390_lowcore.program_new_psw.mask = __extract_psw();
asm volatile(
" larl %[pgm_addr],1f\n"
" stg %[pgm_addr],%[psw_pgm_addr]\n"
" diag %[rx],%[ry],0x260\n"
"1:\n"
: [pgm_addr] "=&d"(pgm_addr),
[psw_pgm_addr] "=Q"(S390_lowcore.program_new_psw.addr),
[rx] "=d" (_rx), [ry] "+d" (_ry));
S390_lowcore.program_new_psw = old;

if (_ry == 0xc)
return -EOPNOTSUPP;
if (rx)
*rx = _rx;
if (ry)
*ry = _ry;
return 0;
}

static int diag260(unsigned long *max_physmem_end)
{
unsigned long diag260_physmem_end;
int rc, i;

struct {
Expand All @@ -101,12 +127,23 @@ static int diag260(void)
} storage_extents[8] __aligned(16); /* VM supports up to 8 extends */

memset(storage_extents, 0, sizeof(storage_extents));
rc = __diag260((unsigned long)storage_extents, sizeof(storage_extents));
rc = __diag260_0x10((unsigned long)storage_extents,
sizeof(storage_extents));
if (rc == -1)
return -1;

for (i = 0; i < min_t(int, rc, ARRAY_SIZE(storage_extents)); i++)
add_mem_detect_block(storage_extents[i].start, storage_extents[i].end + 1);

/*
* Especially QEMU might report a bigger value via diag260 for
* memory devices / memory hotplug, not indicated via SCLP as
* initial memory. Ignore any errors if we reached this point.
*/
if (!__diag260_0xc(NULL, &diag260_physmem_end)) {
*max_physmem_end = max_t(unsigned long, *max_physmem_end,
diag260_physmem_end + 1);
}
return 0;
}

Expand Down Expand Up @@ -158,7 +195,7 @@ void detect_memory(void)
return;
}

if (!diag260()) {
if (!diag260(&max_physmem_end)) {
mem_detect.info_source = MEM_DETECT_DIAG260;
return;
}
Expand Down

0 comments on commit a235f9f

Please sign in to comment.