summaryrefslogtreecommitdiffstats
path: root/sys-utils/lscpu-virt.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys-utils/lscpu-virt.c')
-rw-r--r--sys-utils/lscpu-virt.c59
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;