pc-bios/s390-ccw/net: Try to load pxelinux.cfg file accoring to the UUID

With the STSI instruction, we can get the UUID of the current VM instance,
so we can support loading pxelinux config files via UUID in the file name,
too.

Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Tested-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
This commit is contained in:
Thomas Huth 2018-05-22 11:53:51 +02:00
parent ec623990b3
commit 0d8261b506

View file

@ -44,6 +44,9 @@ extern char _start[];
#define KERNEL_MAX_SIZE ((long)_start)
#define ARCH_COMMAND_LINE_SIZE 896 /* Taken from Linux kernel */
/* STSI 3.2.2 offset of first vmdb + offset of uuid inside vmdb */
#define STSI322_VMDB_UUID_OFFSET ((8 + 12) * 4)
char stack[PAGE_SIZE * 8] __attribute__((aligned(PAGE_SIZE)));
IplParameterBlock iplb __attribute__((aligned(PAGE_SIZE)));
static char cfgbuf[2048];
@ -235,6 +238,56 @@ static void net_release(filename_ip_t *fn_ip)
}
}
/**
* Retrieve the Universally Unique Identifier of the VM.
* @return UUID string, or NULL in case of errors
*/
static const char *get_uuid(void)
{
register int r0 asm("0");
register int r1 asm("1");
uint8_t *mem, *buf, uuid[16];
int i, cc, chk = 0;
static char uuid_str[37];
mem = malloc(2 * PAGE_SIZE);
if (!mem) {
puts("Out of memory ... can not get UUID.");
return NULL;
}
buf = (uint8_t *)(((uint64_t)mem + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1));
memset(buf, 0, PAGE_SIZE);
/* Get SYSIB 3.2.2 */
r0 = (3 << 28) | 2;
r1 = 2;
asm volatile(" stsi 0(%[addr])\n"
" ipm %[cc]\n"
" srl %[cc],28\n"
: [cc] "=d" (cc)
: "d" (r0), "d" (r1), [addr] "a" (buf)
: "cc", "memory");
if (cc) {
return NULL;
}
for (i = 0; i < 16; i++) {
uuid[i] = buf[STSI322_VMDB_UUID_OFFSET + i];
chk |= uuid[i];
}
free(mem);
if (!chk) {
return NULL;
}
sprintf(uuid_str, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-"
"%02x%02x%02x%02x%02x%02x", uuid[0], uuid[1], uuid[2], uuid[3],
uuid[4], uuid[5], uuid[6], uuid[7], uuid[8], uuid[9], uuid[10],
uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
return uuid_str;
}
/**
* Load a kernel with initrd (i.e. with the information that we've got from
* a pxelinux.cfg config file)
@ -285,7 +338,8 @@ static int net_try_pxelinux_cfg(filename_ip_t *fn_ip)
struct pl_cfg_entry entries[MAX_PXELINUX_ENTRIES];
int num_ent, def_ent = 0;
num_ent = pxelinux_load_parse_cfg(fn_ip, mac, NULL, DEFAULT_TFTP_RETRIES,
num_ent = pxelinux_load_parse_cfg(fn_ip, mac, get_uuid(),
DEFAULT_TFTP_RETRIES,
cfgbuf, sizeof(cfgbuf),
entries, MAX_PXELINUX_ENTRIES, &def_ent);
if (num_ent > 0) {