diff options
Diffstat (limited to '')
-rw-r--r-- | sys-utils/lscpu-virt.c | 59 |
1 files changed, 35 insertions, 24 deletions
diff --git a/sys-utils/lscpu-virt.c b/sys-utils/lscpu-virt.c index 6b6deb8..dc786a8 100644 --- a/sys-utils/lscpu-virt.c +++ b/sys-utils/lscpu-virt.c @@ -1,3 +1,14 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Copyright (C) 2008 Cai Qian <qcai@redhat.com> + * Copyright (C) 2008-2023 Karel Zak <kzak@redhat.com> + */ #include <errno.h> #include <stdlib.h> #include <sys/types.h> @@ -6,6 +17,7 @@ #include <unistd.h> #include <string.h> #include <stdio.h> +#include <signal.h> #include "lscpu.h" @@ -15,7 +27,6 @@ #ifdef INCLUDE_VMWARE_BDOOR # include <stdint.h> -# include <signal.h> # include <strings.h> # include <setjmp.h> # ifdef HAVE_SYS_IO_H @@ -395,17 +406,13 @@ static int read_hypervisor_powerpc(struct lscpu_cxt *cxt, int *type) && ul_path_access(cxt->procfs, F_OK, "device-tree/hmc-managed?") == 0 && ul_path_access(cxt->procfs, F_OK, "device-tree/chosen/qemu,graphic-width") != 0) { - FILE *fd; + char buf[256]; vendor = VIRT_VENDOR_PHYP; *type = VIRT_TYPE_PARA; - fd = ul_path_fopen(cxt->procfs, "r", "device-tree/ibm,partition-name"); - if (fd) { - char buf[256]; - if (fscanf(fd, "%255s", buf) == 1 && !strcmp(buf, "full")) - *type = VIRT_TYPE_NONE; - fclose(fd); - } + if (ul_path_scanf(cxt->procfs, "device-tree/ibm,partition-name", "%255s", buf) == 1 && + !strcmp(buf, "full")) + *type = VIRT_TYPE_NONE; /* Qemu */ } else if (is_devtree_compatible(cxt, "qemu,pseries")) { @@ -447,6 +454,7 @@ void vmware_bdoor(uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) } static jmp_buf segv_handler_env; +static sigset_t oset; static void segv_handler(__attribute__((__unused__)) int sig, @@ -460,6 +468,7 @@ static int is_vmware_platform(void) { uint32_t eax, ebx, ecx, edx; struct sigaction act, oact; + sigset_t set; /* * FIXME: Not reliable for non-root users. Note it works as expected if @@ -478,8 +487,16 @@ static int is_vmware_platform(void) * the signal. All this magic is needed because lscpu * isn't supposed to require root privileges. */ - if (sigsetjmp(segv_handler_env, 1)) + if (sigsetjmp(segv_handler_env, 1)) { + if (sigprocmask(SIG_SETMASK, &oset, NULL)) + err(EXIT_FAILURE, _("cannot restore signal mask")); return 0; + } + + sigemptyset(&set); + sigaddset(&set, SIGSEGV); + if (sigprocmask(SIG_UNBLOCK, &set, &oset)) + err(EXIT_FAILURE, _("cannot unblock signal")); memset(&act, 0, sizeof(act)); act.sa_sigaction = segv_handler; @@ -493,6 +510,9 @@ static int is_vmware_platform(void) if (sigaction(SIGSEGV, &oact, NULL)) err(EXIT_FAILURE, _("cannot restore signal handler")); + if (sigprocmask(SIG_SETMASK, &oset, NULL)) + err(EXIT_FAILURE, _("cannot restore signal mask")); + return eax != (uint32_t)-1 && ebx == VMWARE_BDOOR_MAGIC; } @@ -551,9 +571,7 @@ struct lscpu_virt *lscpu_read_virtualization(struct lscpu_cxt *cxt) if (virt->vendor == VIRT_VENDOR_XEN) { uint32_t features; - fd = ul_prefix_fopen(cxt->prefix, "r", _PATH_SYS_HYP_FEATURES); - - if (fd && fscanf(fd, "%x", &features) == 1) { + if (ul_path_scanf(cxt->rootfs, _PATH_SYS_HYP_FEATURES, "%x", &features) == 1) { /* Xen PV domain */ if (features & XEN_FEATURES_PV_MASK) virt->type = VIRT_TYPE_PARA; @@ -562,25 +580,18 @@ struct lscpu_virt *lscpu_read_virtualization(struct lscpu_cxt *cxt) == XEN_FEATURES_PVH_MASK) virt->type = VIRT_TYPE_PARA; } - if (fd) - fclose(fd); } } else if ((virt->vendor = read_hypervisor_powerpc(cxt, &virt->type))) { ; /* Xen para-virt or dom0 */ } else if (ul_path_access(cxt->procfs, F_OK, "xen") == 0) { + char xenbuf[256]; int dom0 = 0; - fd = ul_path_fopen(cxt->procfs, "r", "xen/capabilities"); - if (fd) { - char xenbuf[256]; - - if (fscanf(fd, "%255s", xenbuf) == 1 && - !strcmp(xenbuf, "control_d")) - dom0 = 1; - fclose(fd); - } + if (ul_path_scanf(cxt->procfs, "xen/capabilities", "%255s", xenbuf) == 1 && + !strcmp(xenbuf, "control_d")) + dom0 = 1; virt->type = dom0 ? VIRT_TYPE_NONE : VIRT_TYPE_PARA; virt->vendor = VIRT_VENDOR_XEN; |