| /* 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 <thuth@redhat.com> | |
| * Claudio Imbrenda <imbrenda@linux.ibm.com> | |
| */ | |
| #include <libcflat.h> | |
| #include <alloc_page.h> | |
| #include <asm/arch_def.h> | |
| #include <asm/page.h> | |
| #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; | |
| } |