aboutsummaryrefslogtreecommitdiff
path: root/pc-bios
diff options
context:
space:
mode:
authorThomas Huth <thuth@redhat.com>2018-05-22 11:53:51 +0200
committerThomas Huth <thuth@redhat.com>2018-06-18 15:08:44 +0200
commit0d8261b506933c245b79ca6a57422dc81d8989c1 (patch)
tree3848d2de747d133ffbd9527fc5da4425b45a8352 /pc-bios
parentec623990b34ab0e271141356af96d67a0c4e980d (diff)
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>
Diffstat (limited to 'pc-bios')
-rw-r--r--pc-bios/s390-ccw/netmain.c56
1 files changed, 55 insertions, 1 deletions
diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c
index c059546480..0392131c27 100644
--- a/pc-bios/s390-ccw/netmain.c
+++ b/pc-bios/s390-ccw/netmain.c
@@ -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];
@@ -236,6 +239,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) {