1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3 * Functions to retrieve information about the host system.
4 *
5 * Copyright (c) 2020 Red Hat Inc
6 * Copyright 2022 IBM Corp.
7 *
8 * Authors:
9 * Thomas Huth <thuth@redhat.com>
10 * Claudio Imbrenda <imbrenda@linux.ibm.com>
11 */
12
13 #include <libcflat.h>
14 #include <alloc_page.h>
15 #include <asm/arch_def.h>
16 #include <asm/page.h>
17 #include "hardware.h"
18 #include "stsi.h"
19
20 /* The string "QEMU" in EBCDIC */
21 static const uint8_t qemu_ebcdic[] = { 0xd8, 0xc5, 0xd4, 0xe4 };
22 /* The string "KVM/" in EBCDIC */
23 static const uint8_t kvm_ebcdic[] = { 0xd2, 0xe5, 0xd4, 0x61 };
24
do_detect_host(void)25 static enum s390_host do_detect_host(void)
26 {
27 uint8_t buf[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
28 struct sysinfo_3_2_2 *stsi_322 = (struct sysinfo_3_2_2 *)buf;
29
30 if (stsi_get_fc() == 2)
31 return HOST_IS_LPAR;
32
33 if (stsi_get_fc() != 3)
34 return HOST_IS_UNKNOWN;
35
36 if (!stsi(buf, 1, 1, 1)) {
37 /*
38 * If the manufacturer string is "QEMU" in EBCDIC, then we
39 * are on TCG (otherwise the string is "IBM" in EBCDIC)
40 */
41 if (!memcmp((char *)buf + 32, qemu_ebcdic, sizeof(qemu_ebcdic)))
42 return HOST_IS_TCG;
43 }
44
45 if (!stsi(buf, 3, 2, 2)) {
46 /*
47 * If the manufacturer string is "KVM/" in EBCDIC, then we
48 * are on KVM.
49 */
50 if (!memcmp(&stsi_322->vm[0].cpi, kvm_ebcdic, sizeof(kvm_ebcdic)))
51 return HOST_IS_KVM;
52 }
53
54 return HOST_IS_UNKNOWN;
55 }
56
detect_host(void)57 enum s390_host detect_host(void)
58 {
59 static enum s390_host host = HOST_IS_UNKNOWN;
60 static bool initialized = false;
61
62 if (initialized)
63 return host;
64
65 host = do_detect_host();
66 initialized = true;
67 return host;
68 }
69