xref: /kvm-unit-tests/lib/s390x/hardware.c (revision c604fa931a1cb70c3649ac1b7223178fc79eab6a)
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 "hardware.h"
17 #include "stsi.h"
18 
19 /* The string "QEMU" in EBCDIC */
20 static const uint8_t qemu_ebcdic[] = { 0xd8, 0xc5, 0xd4, 0xe4 };
21 /* The string "KVM/" in EBCDIC */
22 static const uint8_t kvm_ebcdic[] = { 0xd2, 0xe5, 0xd4, 0x61 };
23 
24 static enum s390_host do_detect_host(void *buf)
25 {
26 	struct sysinfo_3_2_2 *stsi_322 = buf;
27 
28 	if (stsi_get_fc() == 2)
29 		return HOST_IS_LPAR;
30 
31 	if (stsi_get_fc() != 3)
32 		return HOST_IS_UNKNOWN;
33 
34 	if (!stsi(buf, 1, 1, 1)) {
35 		/*
36 		 * If the manufacturer string is "QEMU" in EBCDIC, then we
37 		 * are on TCG (otherwise the string is "IBM" in EBCDIC)
38 		 */
39 		if (!memcmp((char *)buf + 32, qemu_ebcdic, sizeof(qemu_ebcdic)))
40 			return HOST_IS_TCG;
41 	}
42 
43 	if (!stsi(buf, 3, 2, 2)) {
44 		/*
45 		 * If the manufacturer string is "KVM/" in EBCDIC, then we
46 		 * are on KVM.
47 		 */
48 		if (!memcmp(&stsi_322->vm[0].cpi, kvm_ebcdic, sizeof(kvm_ebcdic)))
49 			return HOST_IS_KVM;
50 	}
51 
52 	return HOST_IS_UNKNOWN;
53 }
54 
55 enum s390_host detect_host(void)
56 {
57 	static enum s390_host host = HOST_IS_UNKNOWN;
58 	static bool initialized = false;
59 	void *buf;
60 
61 	if (initialized)
62 		return host;
63 
64 	buf = alloc_page();
65 	host = do_detect_host(buf);
66 	free_page(buf);
67 	initialized = true;
68 	return host;
69 }
70