/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Functions to retrieve information about the host system. * * Copyright (c) 2020 Red Hat Inc * Copyright 2022 IBM Corp. * * Authors: * Thomas Huth * Claudio Imbrenda */ #include #include #include #include #include "hardware.h" #include "stsi.h" /* The string "QEMU" in EBCDIC */ static const uint8_t qemu_ebcdic[] = { 0xd8, 0xc5, 0xd4, 0xe4 }; /* The string "KVM/" in EBCDIC */ static const uint8_t kvm_ebcdic[] = { 0xd2, 0xe5, 0xd4, 0x61 }; static enum s390_host do_detect_host(void) { uint8_t buf[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE))); struct sysinfo_3_2_2 *stsi_322 = (struct sysinfo_3_2_2 *)buf; if (stsi_get_fc() == 2) return HOST_IS_LPAR; if (stsi_get_fc() != 3) return HOST_IS_UNKNOWN; if (!stsi(buf, 1, 1, 1)) { /* * If the manufacturer string is "QEMU" in EBCDIC, then we * are on TCG (otherwise the string is "IBM" in EBCDIC) */ if (!memcmp((char *)buf + 32, qemu_ebcdic, sizeof(qemu_ebcdic))) return HOST_IS_TCG; } if (!stsi(buf, 3, 2, 2)) { /* * If the manufacturer string is "KVM/" in EBCDIC, then we * are on KVM. */ if (!memcmp(&stsi_322->vm[0].cpi, kvm_ebcdic, sizeof(kvm_ebcdic))) return HOST_IS_KVM; } return HOST_IS_UNKNOWN; } enum s390_host detect_host(void) { static enum s390_host host = HOST_IS_UNKNOWN; static bool initialized = false; if (initialized) return host; host = do_detect_host(); initialized = true; return host; }