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: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
Родитель
fddbaa5c42
Коммит
6e98e64329
|
@ -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)
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
enum mem_info_source {
|
||||
MEM_DETECT_NONE = 0,
|
||||
MEM_DETECT_SCLP_STOR_INFO,
|
||||
MEM_DETECT_DIAG260,
|
||||
MEM_DETECT_TPROT_LOOP
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче