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