Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6e98e643 authored by Vasily Gorbik's avatar Vasily Gorbik Committed by Martin Schwidefsky
Browse files

s390/mem_detect: introduce z/VM specific diag260 call



In the case when z/VM memory is defined with "define storage config"
command, SCLP storage info is not available. Utilize diag260 "storage
configuration" call, to get information about z/VM specific guest memory
definitions with potential memory holes.

Reviewed-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent fddbaa5c
Loading
Loading
Loading
Loading
+52 −0
Original line number Diff line number Diff line
@@ -71,6 +71,53 @@ static unsigned long get_mem_detect_end(void)
	return 0;
}

static int __diag260(unsigned long rx1, unsigned long rx2)
{
	register unsigned long _rx1 asm("2") = rx1;
	register unsigned long _rx2 asm("3") = rx2;
	register unsigned long _ry asm("4") = 0x10; /* storage configuration */
	int rc = -1;				    /* fail */
	unsigned long reg1, reg2;
	psw_t old = S390_lowcore.program_new_psw;

	asm volatile(
		"	epsw	%0,%1\n"
		"	st	%0,%[psw_pgm]\n"
		"	st	%1,%[psw_pgm]+4\n"
		"	larl	%0,1f\n"
		"	stg	%0,%[psw_pgm]+8\n"
		"	diag	%[rx],%[ry],0x260\n"
		"	ipm	%[rc]\n"
		"	srl	%[rc],28\n"
		"1:\n"
		: "=&d" (reg1), "=&a" (reg2),
		  [psw_pgm] "=Q" (S390_lowcore.program_new_psw),
		  [rc] "+&d" (rc), [ry] "+d" (_ry)
		: [rx] "d" (_rx1), "d" (_rx2)
		: "cc", "memory");
	S390_lowcore.program_new_psw = old;
	return rc == 0 ? _ry : -1;
}

static int diag260(void)
{
	int rc, i;

	struct {
		unsigned long start;
		unsigned long end;
	} 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));
	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);
	return 0;
}

static int tprot(unsigned long addr)
{
	unsigned long pgm_addr;
@@ -132,6 +179,11 @@ void detect_memory(void)
		return;
	}

	if (!diag260()) {
		mem_detect.info_source = MEM_DETECT_DIAG260;
		return;
	}

	scan_memory(rzm);
	mem_detect.info_source = MEM_DETECT_TPROT_LOOP;
	if (!max_physmem_end)
+1 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
enum mem_info_source {
	MEM_DETECT_NONE = 0,
	MEM_DETECT_SCLP_STOR_INFO,
	MEM_DETECT_DIAG260,
	MEM_DETECT_TPROT_LOOP
};