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 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 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