From patchwork Tue Jan 21 08:43:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?SsO8cmdlbiBHcm/Dnw==?= X-Patchwork-Id: 11343187 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 96DF16C1 for ; Tue, 21 Jan 2020 08:45:21 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7D70E22522 for ; Tue, 21 Jan 2020 08:45:21 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7D70E22522 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=suse.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1itp8Z-0004VC-AI; Tue, 21 Jan 2020 08:43:51 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1itp8X-0004UP-L4 for xen-devel@lists.xenproject.org; Tue, 21 Jan 2020 08:43:49 +0000 X-Inumbo-ID: 1bffdea4-3c2a-11ea-8e9a-bc764e2007e4 Received: from mx2.suse.de (unknown [195.135.220.15]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 1bffdea4-3c2a-11ea-8e9a-bc764e2007e4; Tue, 21 Jan 2020 08:43:34 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 57A03B2C3; Tue, 21 Jan 2020 08:43:33 +0000 (UTC) From: Juergen Gross To: xen-devel@lists.xenproject.org Date: Tue, 21 Jan 2020 09:43:22 +0100 Message-Id: <20200121084330.18309-2-jgross@suse.com> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20200121084330.18309-1-jgross@suse.com> References: <20200121084330.18309-1-jgross@suse.com> Subject: [Xen-devel] [PATCH v3 1/9] xen: add a generic way to include binary files as variables X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Juergen Gross , Stefano Stabellini , Julien Grall , Wei Liu , Konrad Rzeszutek Wilk , George Dunlap , Andrew Cooper , Ian Jackson , Jan Beulich , Daniel De Graaf MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Add a new script xen/tools/binfile for including a binary file at build time being usable via a pointer and a size variable in the hypervisor. Make use of that generic tool in xsm. Signed-off-by: Juergen Gross --- V3: - new patch --- .gitignore | 1 + xen/tools/binfile | 29 +++++++++++++++++++++++++++++ xen/xsm/flask/Makefile | 5 ++++- xen/xsm/flask/flask-policy.S | 16 ---------------- 4 files changed, 34 insertions(+), 17 deletions(-) create mode 100755 xen/tools/binfile delete mode 100644 xen/xsm/flask/flask-policy.S diff --git a/.gitignore b/.gitignore index 4ca679ddbc..b2624df79a 100644 --- a/.gitignore +++ b/.gitignore @@ -313,6 +313,7 @@ xen/test/livepatch/*.livepatch xen/tools/kconfig/.tmp_gtkcheck xen/tools/kconfig/.tmp_qtcheck xen/tools/symbols +xen/xsm/flask/flask-policy.S xen/xsm/flask/include/av_perm_to_string.h xen/xsm/flask/include/av_permissions.h xen/xsm/flask/include/class_to_string.h diff --git a/xen/tools/binfile b/xen/tools/binfile new file mode 100755 index 0000000000..122111ff6d --- /dev/null +++ b/xen/tools/binfile @@ -0,0 +1,29 @@ +#!/bin/sh +# usage: binfile [-i] +# -i add to .init.rodata (default: .rodata) section + +[ "$1" = "-i" ] && { + shift + section=".init" +} + +target=$1 +binsource=$2 +varname=$3 + +cat <$target +#include + + .section $section.rodata, "a", %progbits + + .global $varname +$varname: + .incbin "$binsource" +.Lend: + + .type $varname, %object + .size $varname, . - $varname + + .global ${varname}_size + ASM_INT(${varname}_size, .Lend - $varname) +EOF diff --git a/xen/xsm/flask/Makefile b/xen/xsm/flask/Makefile index 7c3f381287..a807521235 100644 --- a/xen/xsm/flask/Makefile +++ b/xen/xsm/flask/Makefile @@ -30,6 +30,9 @@ $(AV_H_FILES): $(AV_H_DEPEND) obj-bin-$(CONFIG_XSM_FLASK_POLICY) += flask-policy.o flask-policy.o: policy.bin +flask-policy.S: $(XEN_ROOT)/xen/tools/binfile + $(XEN_ROOT)/xen/tools/binfile -i $@ policy.bin xsm_flask_init_policy + FLASK_BUILD_DIR := $(CURDIR) POLICY_SRC := $(FLASK_BUILD_DIR)/xenpolicy-$(XEN_FULLVERSION) @@ -39,4 +42,4 @@ policy.bin: FORCE .PHONY: clean clean:: - rm -f $(ALL_H_FILES) *.o $(DEPS_RM) policy.* $(POLICY_SRC) + rm -f $(ALL_H_FILES) *.o $(DEPS_RM) policy.* $(POLICY_SRC) flask-policy.S diff --git a/xen/xsm/flask/flask-policy.S b/xen/xsm/flask/flask-policy.S deleted file mode 100644 index d38aa39964..0000000000 --- a/xen/xsm/flask/flask-policy.S +++ /dev/null @@ -1,16 +0,0 @@ -#include - - .section .init.rodata, "a", %progbits - -/* const unsigned char xsm_flask_init_policy[] __initconst */ - .global xsm_flask_init_policy -xsm_flask_init_policy: - .incbin "policy.bin" -.Lend: - - .type xsm_flask_init_policy, %object - .size xsm_flask_init_policy, . - xsm_flask_init_policy - -/* const unsigned int __initconst xsm_flask_init_policy_size */ - .global xsm_flask_init_policy_size - ASM_INT(xsm_flask_init_policy_size, .Lend - xsm_flask_init_policy) From patchwork Tue Jan 21 08:43:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?SsO8cmdlbiBHcm/Dnw==?= X-Patchwork-Id: 11343191 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E128917EA for ; Tue, 21 Jan 2020 08:45:26 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B155D22522 for ; Tue, 21 Jan 2020 08:45:26 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B155D22522 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=suse.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1itp8O-0004SR-QT; Tue, 21 Jan 2020 08:43:40 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1itp8N-0004SM-CU for xen-devel@lists.xenproject.org; Tue, 21 Jan 2020 08:43:39 +0000 X-Inumbo-ID: 1bff8d14-3c2a-11ea-ba47-12813bfff9fa Received: from mx2.suse.de (unknown [195.135.220.15]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id 1bff8d14-3c2a-11ea-ba47-12813bfff9fa; Tue, 21 Jan 2020 08:43:35 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id A389EB2C4; Tue, 21 Jan 2020 08:43:33 +0000 (UTC) From: Juergen Gross To: xen-devel@lists.xenproject.org Date: Tue, 21 Jan 2020 09:43:23 +0100 Message-Id: <20200121084330.18309-3-jgross@suse.com> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20200121084330.18309-1-jgross@suse.com> References: <20200121084330.18309-1-jgross@suse.com> Subject: [Xen-devel] [PATCH v3 2/9] xen: split parameter related definitions in own header file X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Juergen Gross , Kevin Tian , Stefano Stabellini , Julien Grall , Jun Nakajima , Wei Liu , Konrad Rzeszutek Wilk , George Dunlap , Andrew Cooper , Paul Durrant , Ian Jackson , Christopher Clark , Dario Faggioli , Lukasz Hawrylko , Jan Beulich , Daniel De Graaf , Volodymyr Babchuk , =?utf-8?q?Roger_Pau_Monn?= =?utf-8?q?=C3=A9?= MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Move the parameter related definitions from init.h into a new header file param.h. This will avoid include hell when new dependencies are added to parameter definitions. Signed-off-by: Juergen Gross Acked-by: Julien Grall Acked-by: Dario Faggioli Acked-by: Paul Durrant Acked-by: Jan Beulich Reviewed-by: Kevin Tian --- V3: - new patch --- xen/arch/arm/acpi/boot.c | 1 + xen/arch/arm/cpuerrata.c | 1 + xen/arch/arm/domain_build.c | 1 + xen/arch/arm/gic-v3-lpi.c | 1 + xen/arch/arm/setup.c | 1 + xen/arch/arm/smpboot.c | 1 + xen/arch/arm/traps.c | 1 + xen/arch/x86/acpi/boot.c | 1 + xen/arch/x86/acpi/cpu_idle.c | 1 + xen/arch/x86/acpi/cpufreq/cpufreq.c | 1 + xen/arch/x86/acpi/power.c | 1 + xen/arch/x86/apic.c | 1 + xen/arch/x86/cpu/amd.c | 1 + xen/arch/x86/cpu/common.c | 1 + xen/arch/x86/cpu/mcheck/mce.c | 1 + xen/arch/x86/cpu/mcheck/mce_intel.c | 1 + xen/arch/x86/cpu/mtrr/generic.c | 1 + xen/arch/x86/cpu/mwait-idle.c | 1 + xen/arch/x86/cpu/vpmu.c | 1 + xen/arch/x86/cpuid.c | 1 + xen/arch/x86/dom0_build.c | 1 + xen/arch/x86/e820.c | 1 + xen/arch/x86/genapic/probe.c | 1 + xen/arch/x86/genapic/x2apic.c | 1 + xen/arch/x86/hpet.c | 1 + xen/arch/x86/hvm/asid.c | 1 + xen/arch/x86/hvm/hvm.c | 1 + xen/arch/x86/hvm/quirks.c | 1 + xen/arch/x86/hvm/viridian/viridian.c | 1 + xen/arch/x86/hvm/vmx/vmcs.c | 1 + xen/arch/x86/hvm/vmx/vmx.c | 1 + xen/arch/x86/io_apic.c | 1 + xen/arch/x86/irq.c | 1 + xen/arch/x86/microcode.c | 1 + xen/arch/x86/mm.c | 1 + xen/arch/x86/mm/p2m.c | 1 + xen/arch/x86/msi.c | 1 + xen/arch/x86/nmi.c | 1 + xen/arch/x86/numa.c | 1 + xen/arch/x86/oprofile/nmi_int.c | 1 + xen/arch/x86/psr.c | 1 + xen/arch/x86/pv/domain.c | 1 + xen/arch/x86/pv/shim.c | 1 + xen/arch/x86/setup.c | 1 + xen/arch/x86/shutdown.c | 1 + xen/arch/x86/spec_ctrl.c | 1 + xen/arch/x86/tboot.c | 1 + xen/arch/x86/time.c | 1 + xen/arch/x86/traps.c | 1 + xen/arch/x86/tsx.c | 1 + xen/arch/x86/x86_64/mmconfig-shared.c | 1 + xen/arch/x86/xstate.c | 1 + xen/common/argo.c | 1 + xen/common/core_parking.c | 1 + xen/common/cpupool.c | 1 + xen/common/debugtrace.c | 1 + xen/common/domain.c | 1 + xen/common/efi/boot.c | 1 + xen/common/gdbstub.c | 1 + xen/common/grant_table.c | 1 + xen/common/kernel.c | 1 + xen/common/kexec.c | 1 + xen/common/memory.c | 1 + xen/common/page_alloc.c | 1 + xen/common/rcupdate.c | 1 + xen/common/sched_credit.c | 1 + xen/common/sched_credit2.c | 1 + xen/common/schedule.c | 1 + xen/common/shutdown.c | 1 + xen/common/timer.c | 1 + xen/common/trace.c | 1 + xen/drivers/acpi/apei/hest.c | 1 + xen/drivers/acpi/tables.c | 1 + xen/drivers/char/arm-uart.c | 1 + xen/drivers/char/console.c | 1 + xen/drivers/char/ehci-dbgp.c | 1 + xen/drivers/char/ns16550.c | 1 + xen/drivers/char/serial.c | 1 + xen/drivers/cpufreq/cpufreq.c | 1 + xen/drivers/passthrough/amd/iommu_acpi.c | 1 + xen/drivers/passthrough/iommu.c | 1 + xen/drivers/passthrough/pci.c | 1 + xen/drivers/passthrough/vtd/dmar.c | 1 + xen/drivers/passthrough/vtd/quirks.c | 1 + xen/drivers/passthrough/vtd/x86/vtd.c | 1 + xen/drivers/passthrough/x86/ats.c | 1 + xen/drivers/video/vesa.c | 1 + xen/drivers/video/vga.c | 1 + xen/include/xen/init.h | 120 ----------------------------- xen/include/xen/param.h | 126 +++++++++++++++++++++++++++++++ xen/xsm/flask/flask_op.c | 1 + xen/xsm/xsm_core.c | 1 + 92 files changed, 216 insertions(+), 120 deletions(-) create mode 100644 xen/include/xen/param.h diff --git a/xen/arch/arm/acpi/boot.c b/xen/arch/arm/acpi/boot.c index bf9c78b02c..30e4bd1bc5 100644 --- a/xen/arch/arm/acpi/boot.c +++ b/xen/arch/arm/acpi/boot.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include diff --git a/xen/arch/arm/cpuerrata.c b/xen/arch/arm/cpuerrata.c index da72b02442..0248893de0 100644 --- a/xen/arch/arm/cpuerrata.c +++ b/xen/arch/arm/cpuerrata.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index dd9c3b73ba..d2d11eda26 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/arm/gic-v3-lpi.c b/xen/arch/arm/gic-v3-lpi.c index 78b9521b21..869bc97fa1 100644 --- a/xen/arch/arm/gic-v3-lpi.c +++ b/xen/arch/arm/gic-v3-lpi.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index 9dd3738d44..5d8eb46203 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/arm/smpboot.c b/xen/arch/arm/smpboot.c index 00b64c3322..cae2179126 100644 --- a/xen/arch/arm/smpboot.c +++ b/xen/arch/arm/smpboot.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c index a20474f87c..6f9bec22d3 100644 --- a/xen/arch/arm/traps.c +++ b/xen/arch/arm/traps.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/acpi/boot.c b/xen/arch/x86/acpi/boot.c index 15542a9bdf..2aae4b480a 100644 --- a/xen/arch/x86/acpi/boot.c +++ b/xen/arch/x86/acpi/boot.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/acpi/cpu_idle.c b/xen/arch/x86/acpi/cpu_idle.c index 5edd1844f4..b9d99a0468 100644 --- a/xen/arch/x86/acpi/cpu_idle.c +++ b/xen/arch/x86/acpi/cpu_idle.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/acpi/cpufreq/cpufreq.c b/xen/arch/x86/acpi/cpufreq/cpufreq.c index f05275578d..281be131a3 100644 --- a/xen/arch/x86/acpi/cpufreq/cpufreq.c +++ b/xen/arch/x86/acpi/cpufreq/cpufreq.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/acpi/power.c b/xen/arch/x86/acpi/power.c index 8078352312..f5f4aa9bda 100644 --- a/xen/arch/x86/acpi/power.c +++ b/xen/arch/x86/acpi/power.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/apic.c b/xen/arch/x86/apic.c index a6a7754d77..2d68396feb 100644 --- a/xen/arch/x86/apic.c +++ b/xen/arch/x86/apic.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c index 8b5f0f2e4c..e351dd227f 100644 --- a/xen/arch/x86/cpu/amd.c +++ b/xen/arch/x86/cpu/amd.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c index e5ad17d8d9..1b33f1ed71 100644 --- a/xen/arch/x86/cpu/common.c +++ b/xen/arch/x86/cpu/common.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/cpu/mcheck/mce.c b/xen/arch/x86/cpu/mcheck/mce.c index 198595ff97..d61e582af3 100644 --- a/xen/arch/x86/cpu/mcheck/mce.c +++ b/xen/arch/x86/cpu/mcheck/mce.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/cpu/mcheck/mce_intel.c b/xen/arch/x86/cpu/mcheck/mce_intel.c index 70738852b9..6f23ea5329 100644 --- a/xen/arch/x86/cpu/mcheck/mce_intel.c +++ b/xen/arch/x86/cpu/mcheck/mce_intel.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/cpu/mtrr/generic.c b/xen/arch/x86/cpu/mtrr/generic.c index cc0bf4c310..89634f918f 100644 --- a/xen/arch/x86/cpu/mtrr/generic.c +++ b/xen/arch/x86/cpu/mtrr/generic.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/cpu/mwait-idle.c b/xen/arch/x86/cpu/mwait-idle.c index 52413e6da1..1c5d6eb023 100644 --- a/xen/arch/x86/cpu/mwait-idle.c +++ b/xen/arch/x86/cpu/mwait-idle.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/cpu/vpmu.c b/xen/arch/x86/cpu/vpmu.c index b62095eef2..3c778450ac 100644 --- a/xen/arch/x86/cpu/vpmu.c +++ b/xen/arch/x86/cpu/vpmu.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c index b1ed33d524..aee221dc44 100644 --- a/xen/arch/x86/cpuid.c +++ b/xen/arch/x86/cpuid.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include diff --git a/xen/arch/x86/dom0_build.c b/xen/arch/x86/dom0_build.c index 28b964e018..909b01330d 100644 --- a/xen/arch/x86/dom0_build.c +++ b/xen/arch/x86/dom0_build.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/e820.c b/xen/arch/x86/e820.c index 082f9928a1..0fe9af3ca6 100644 --- a/xen/arch/x86/e820.c +++ b/xen/arch/x86/e820.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/genapic/probe.c b/xen/arch/x86/genapic/probe.c index 1fcc1734f5..d4d7a554a0 100644 --- a/xen/arch/x86/genapic/probe.c +++ b/xen/arch/x86/genapic/probe.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/genapic/x2apic.c b/xen/arch/x86/genapic/x2apic.c index 1cb16bc10d..f9b5e49761 100644 --- a/xen/arch/x86/genapic/x2apic.c +++ b/xen/arch/x86/genapic/x2apic.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/hpet.c b/xen/arch/x86/hpet.c index 57f68fa81b..ae99993d90 100644 --- a/xen/arch/x86/hpet.c +++ b/xen/arch/x86/hpet.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/hvm/asid.c b/xen/arch/x86/hvm/asid.c index 9d3c671a5f..8e00a28443 100644 --- a/xen/arch/x86/hvm/asid.c +++ b/xen/arch/x86/hvm/asid.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 4723f5d09c..19dc703603 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/hvm/quirks.c b/xen/arch/x86/hvm/quirks.c index 881c6b99d2..54cc66c382 100644 --- a/xen/arch/x86/hvm/quirks.c +++ b/xen/arch/x86/hvm/quirks.c @@ -19,6 +19,7 @@ #include #include #include +#include #include s8 __read_mostly hvm_port80_allowed = -1; diff --git a/xen/arch/x86/hvm/viridian/viridian.c b/xen/arch/x86/hvm/viridian/viridian.c index 44c8e6cac6..f2302dc1e6 100644 --- a/xen/arch/x86/hvm/viridian/viridian.c +++ b/xen/arch/x86/hvm/viridian/viridian.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c index 634d1946d3..65445afeb0 100644 --- a/xen/arch/x86/hvm/vmx/vmcs.c +++ b/xen/arch/x86/hvm/vmx/vmcs.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index f83f102638..4fc9d1128c 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include diff --git a/xen/arch/x86/io_apic.c b/xen/arch/x86/io_apic.c index 4125ea0c0c..e98e08e9c8 100644 --- a/xen/arch/x86/io_apic.c +++ b/xen/arch/x86/io_apic.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c index 310ac00a60..cc2eb8e925 100644 --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/microcode.c b/xen/arch/x86/microcode.c index 6ced293d88..2f22bc2bb2 100644 --- a/xen/arch/x86/microcode.c +++ b/xen/arch/x86/microcode.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 654190e9e9..9d5f45b506 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -103,6 +103,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c index 3119269073..09e4d1910a 100644 --- a/xen/arch/x86/mm/p2m.c +++ b/xen/arch/x86/mm/p2m.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/msi.c b/xen/arch/x86/msi.c index df97ce0c72..c85cf9f85a 100644 --- a/xen/arch/x86/msi.c +++ b/xen/arch/x86/msi.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/nmi.c b/xen/arch/x86/nmi.c index e26121a737..a5c6bdd0ce 100644 --- a/xen/arch/x86/nmi.c +++ b/xen/arch/x86/nmi.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/numa.c b/xen/arch/x86/numa.c index 7e1f563012..6ef15b34d5 100644 --- a/xen/arch/x86/numa.c +++ b/xen/arch/x86/numa.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/oprofile/nmi_int.c b/xen/arch/x86/oprofile/nmi_int.c index 3dfb8fef93..8f97f7522c 100644 --- a/xen/arch/x86/oprofile/nmi_int.c +++ b/xen/arch/x86/oprofile/nmi_int.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/psr.c b/xen/arch/x86/psr.c index 8bf1c23751..d7f8864651 100644 --- a/xen/arch/x86/psr.c +++ b/xen/arch/x86/psr.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c index 4da0b2afff..c3473b9a47 100644 --- a/xen/arch/x86/pv/domain.c +++ b/xen/arch/x86/pv/domain.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include diff --git a/xen/arch/x86/pv/shim.c b/xen/arch/x86/pv/shim.c index 7a898fdbe5..76fb380100 100644 --- a/xen/arch/x86/pv/shim.c +++ b/xen/arch/x86/pv/shim.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index d858883404..9aa171f733 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/shutdown.c b/xen/arch/x86/shutdown.c index 005c0bf4fa..acef033143 100644 --- a/xen/arch/x86/shutdown.c +++ b/xen/arch/x86/shutdown.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c index aa632bdcee..20f562902b 100644 --- a/xen/arch/x86/spec_ctrl.c +++ b/xen/arch/x86/spec_ctrl.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include diff --git a/xen/arch/x86/tboot.c b/xen/arch/x86/tboot.c index 5020c4ad49..8c232270b4 100644 --- a/xen/arch/x86/tboot.c +++ b/xen/arch/x86/tboot.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c index f6b26f8883..cf3e51fb5e 100644 --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 97499a0c79..56067f85d1 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/x86/tsx.c b/xen/arch/x86/tsx.c index 2d202a0d4e..39e483640a 100644 --- a/xen/arch/x86/tsx.c +++ b/xen/arch/x86/tsx.c @@ -1,4 +1,5 @@ #include +#include #include /* diff --git a/xen/arch/x86/x86_64/mmconfig-shared.c b/xen/arch/x86/x86_64/mmconfig-shared.c index cc08b52a35..0c55c7206e 100644 --- a/xen/arch/x86/x86_64/mmconfig-shared.c +++ b/xen/arch/x86/x86_64/mmconfig-shared.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include diff --git a/xen/arch/x86/xstate.c b/xen/arch/x86/xstate.c index 243495ed07..078419a171 100644 --- a/xen/arch/x86/xstate.c +++ b/xen/arch/x86/xstate.c @@ -5,6 +5,7 @@ * */ +#include #include #include #include diff --git a/xen/common/argo.c b/xen/common/argo.c index 2b91e94499..aa3443a377 100644 --- a/xen/common/argo.c +++ b/xen/common/argo.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/common/core_parking.c b/xen/common/core_parking.c index a6669e1766..411106c675 100644 --- a/xen/common/core_parking.c +++ b/xen/common/core_parking.c @@ -19,6 +19,7 @@ #include #include #include +#include #include diff --git a/xen/common/cpupool.c b/xen/common/cpupool.c index d66b541a94..9712614f16 100644 --- a/xen/common/cpupool.c +++ b/xen/common/cpupool.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/common/debugtrace.c b/xen/common/debugtrace.c index a788e55b4c..c21ec99ee0 100644 --- a/xen/common/debugtrace.c +++ b/xen/common/debugtrace.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/common/domain.c b/xen/common/domain.c index ee3f9ffd3e..086177d3c8 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c index bf7bb95999..b9f461505c 100644 --- a/xen/common/efi/boot.c +++ b/xen/common/efi/boot.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #if EFI_PAGE_SIZE != PAGE_SIZE diff --git a/xen/common/gdbstub.c b/xen/common/gdbstub.c index 6234834a20..848c1f4327 100644 --- a/xen/common/gdbstub.c +++ b/xen/common/gdbstub.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index 5536d282b9..2ecf38dfbe 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/common/kernel.c b/xen/common/kernel.c index 760917dab5..22941cec94 100644 --- a/xen/common/kernel.c +++ b/xen/common/kernel.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/common/kexec.c b/xen/common/kexec.c index a262cc5a18..9af7de4df3 100644 --- a/xen/common/kexec.c +++ b/xen/common/kexec.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/common/memory.c b/xen/common/memory.c index 309e872edf..e262e63e4a 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c index 919a270587..97902d42c1 100644 --- a/xen/common/page_alloc.c +++ b/xen/common/page_alloc.c @@ -126,6 +126,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/common/rcupdate.c b/xen/common/rcupdate.c index a56103c6f7..11cfc196fd 100644 --- a/xen/common/rcupdate.c +++ b/xen/common/rcupdate.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/common/sched_credit.c b/xen/common/sched_credit.c index aa41a3301b..2ab89140db 100644 --- a/xen/common/sched_credit.c +++ b/xen/common/sched_credit.c @@ -10,6 +10,7 @@ #include #include +#include #include #include #include diff --git a/xen/common/sched_credit2.c b/xen/common/sched_credit2.c index f7c477053c..3c65269aef 100644 --- a/xen/common/sched_credit2.c +++ b/xen/common/sched_credit2.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include diff --git a/xen/common/schedule.c b/xen/common/schedule.c index 54a07ff9e8..cef2414659 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -16,6 +16,7 @@ #ifndef COMPAT #include #include +#include #include #include #include diff --git a/xen/common/shutdown.c b/xen/common/shutdown.c index 2ed4d62214..912593915b 100644 --- a/xen/common/shutdown.c +++ b/xen/common/shutdown.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include diff --git a/xen/common/timer.c b/xen/common/timer.c index 645206a989..1bb265ceea 100644 --- a/xen/common/timer.c +++ b/xen/common/timer.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/common/trace.c b/xen/common/trace.c index ebfc735b31..a2a389a1c7 100644 --- a/xen/common/trace.c +++ b/xen/common/trace.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/drivers/acpi/apei/hest.c b/xen/drivers/acpi/apei/hest.c index 70734ab0e2..c5f3aaab7c 100644 --- a/xen/drivers/acpi/apei/hest.c +++ b/xen/drivers/acpi/apei/hest.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/drivers/acpi/tables.c b/xen/drivers/acpi/tables.c index b890b73901..8c2a279e18 100644 --- a/xen/drivers/acpi/tables.c +++ b/xen/drivers/acpi/tables.c @@ -24,6 +24,7 @@ #include #include +#include #include #include #include diff --git a/xen/drivers/char/arm-uart.c b/xen/drivers/char/arm-uart.c index 627746ba89..eeb9ceefc0 100644 --- a/xen/drivers/char/arm-uart.c +++ b/xen/drivers/char/arm-uart.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c index 4bcbbfa7d6..913ae1b66a 100644 --- a/xen/drivers/char/console.c +++ b/xen/drivers/char/console.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/drivers/char/ehci-dbgp.c b/xen/drivers/char/ehci-dbgp.c index b6e155d17b..c893d246de 100644 --- a/xen/drivers/char/ehci-dbgp.c +++ b/xen/drivers/char/ehci-dbgp.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c index aa87c57fc9..bd048f307a 100644 --- a/xen/drivers/char/ns16550.c +++ b/xen/drivers/char/ns16550.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/drivers/char/serial.c b/xen/drivers/char/serial.c index 88cd876790..5ecba0af33 100644 --- a/xen/drivers/char/serial.c +++ b/xen/drivers/char/serial.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include diff --git a/xen/drivers/cpufreq/cpufreq.c b/xen/drivers/cpufreq/cpufreq.c index 2d716abf72..e630a47419 100644 --- a/xen/drivers/cpufreq/cpufreq.c +++ b/xen/drivers/cpufreq/cpufreq.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/drivers/passthrough/amd/iommu_acpi.c b/xen/drivers/passthrough/amd/iommu_acpi.c index 9fbc343c58..6c5f8e46ec 100644 --- a/xen/drivers/passthrough/amd/iommu_acpi.c +++ b/xen/drivers/passthrough/amd/iommu_acpi.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include diff --git a/xen/drivers/passthrough/iommu.c b/xen/drivers/passthrough/iommu.c index 4e19cf56cc..9d421e06de 100644 --- a/xen/drivers/passthrough/iommu.c +++ b/xen/drivers/passthrough/iommu.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c index c07a63981a..0d3ced1fcf 100644 --- a/xen/drivers/passthrough/pci.c +++ b/xen/drivers/passthrough/pci.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/drivers/passthrough/vtd/dmar.c b/xen/drivers/passthrough/vtd/dmar.c index f36b99ae37..1784f91b34 100644 --- a/xen/drivers/passthrough/vtd/dmar.c +++ b/xen/drivers/passthrough/vtd/dmar.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/drivers/passthrough/vtd/quirks.c b/xen/drivers/passthrough/vtd/quirks.c index 4dadd9523f..5594270678 100644 --- a/xen/drivers/passthrough/vtd/quirks.c +++ b/xen/drivers/passthrough/vtd/quirks.c @@ -17,6 +17,7 @@ */ #include +#include #include #include #include diff --git a/xen/drivers/passthrough/vtd/x86/vtd.c b/xen/drivers/passthrough/vtd/x86/vtd.c index ff456e1e70..f379afac03 100644 --- a/xen/drivers/passthrough/vtd/x86/vtd.c +++ b/xen/drivers/passthrough/vtd/x86/vtd.c @@ -17,6 +17,7 @@ * Copyright (C) Weidong Han */ +#include #include #include #include diff --git a/xen/drivers/passthrough/x86/ats.c b/xen/drivers/passthrough/x86/ats.c index 3eea7f89fc..8ae0eae4a2 100644 --- a/xen/drivers/passthrough/x86/ats.c +++ b/xen/drivers/passthrough/x86/ats.c @@ -12,6 +12,7 @@ * this program; If not, see . */ +#include #include #include #include diff --git a/xen/drivers/video/vesa.c b/xen/drivers/video/vesa.c index fd2cb1312d..2c1bbd9278 100644 --- a/xen/drivers/video/vesa.c +++ b/xen/drivers/video/vesa.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include diff --git a/xen/drivers/video/vga.c b/xen/drivers/video/vga.c index 666f2e2509..b7f04d0d97 100644 --- a/xen/drivers/video/vga.c +++ b/xen/drivers/video/vga.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/include/xen/init.h b/xen/include/xen/init.h index d0f3a007d0..bfe789e93f 100644 --- a/xen/include/xen/init.h +++ b/xen/include/xen/init.h @@ -71,126 +71,6 @@ typedef void (*exitcall_t)(void); void do_presmp_initcalls(void); void do_initcalls(void); -/* - * Used for kernel command line parameter setup - */ -struct kernel_param { - const char *name; - enum { - OPT_STR, - OPT_UINT, - OPT_BOOL, - OPT_SIZE, - OPT_CUSTOM, - OPT_IGNORE, - } type; - unsigned int len; - union { - void *var; - int (*func)(const char *); - } par; -}; - -extern const struct kernel_param __setup_start[], __setup_end[]; -extern const struct kernel_param __param_start[], __param_end[]; - -#define __dataparam __used_section(".data.param") - -#define __param(att) static const att \ - __attribute__((__aligned__(sizeof(void *)))) struct kernel_param - -#define __setup_str static const __initconst \ - __attribute__((__aligned__(1))) char -#define __kparam __param(__initsetup) - -#define custom_param(_name, _var) \ - __setup_str __setup_str_##_var[] = _name; \ - __kparam __setup_##_var = \ - { .name = __setup_str_##_var, \ - .type = OPT_CUSTOM, \ - .par.func = _var } -#define boolean_param(_name, _var) \ - __setup_str __setup_str_##_var[] = _name; \ - __kparam __setup_##_var = \ - { .name = __setup_str_##_var, \ - .type = OPT_BOOL, \ - .len = sizeof(_var), \ - .par.var = &_var } -#define integer_param(_name, _var) \ - __setup_str __setup_str_##_var[] = _name; \ - __kparam __setup_##_var = \ - { .name = __setup_str_##_var, \ - .type = OPT_UINT, \ - .len = sizeof(_var), \ - .par.var = &_var } -#define size_param(_name, _var) \ - __setup_str __setup_str_##_var[] = _name; \ - __kparam __setup_##_var = \ - { .name = __setup_str_##_var, \ - .type = OPT_SIZE, \ - .len = sizeof(_var), \ - .par.var = &_var } -#define string_param(_name, _var) \ - __setup_str __setup_str_##_var[] = _name; \ - __kparam __setup_##_var = \ - { .name = __setup_str_##_var, \ - .type = OPT_STR, \ - .len = sizeof(_var), \ - .par.var = &_var } -#define ignore_param(_name) \ - __setup_str setup_str_ign[] = _name; \ - __kparam setup_ign = \ - { .name = setup_str_ign, \ - .type = OPT_IGNORE } - -#define __rtparam __param(__dataparam) - -#define custom_runtime_only_param(_name, _var) \ - __rtparam __rtpar_##_var = \ - { .name = _name, \ - .type = OPT_CUSTOM, \ - .par.func = _var } -#define boolean_runtime_only_param(_name, _var) \ - __rtparam __rtpar_##_var = \ - { .name = _name, \ - .type = OPT_BOOL, \ - .len = sizeof(_var), \ - .par.var = &_var } -#define integer_runtime_only_param(_name, _var) \ - __rtparam __rtpar_##_var = \ - { .name = _name, \ - .type = OPT_UINT, \ - .len = sizeof(_var), \ - .par.var = &_var } -#define size_runtime_only_param(_name, _var) \ - __rtparam __rtpar_##_var = \ - { .name = _name, \ - .type = OPT_SIZE, \ - .len = sizeof(_var), \ - .par.var = &_var } -#define string_runtime_only_param(_name, _var) \ - __rtparam __rtpar_##_var = \ - { .name = _name, \ - .type = OPT_STR, \ - .len = sizeof(_var), \ - .par.var = &_var } - -#define custom_runtime_param(_name, _var) \ - custom_param(_name, _var); \ - custom_runtime_only_param(_name, _var) -#define boolean_runtime_param(_name, _var) \ - boolean_param(_name, _var); \ - boolean_runtime_only_param(_name, _var) -#define integer_runtime_param(_name, _var) \ - integer_param(_name, _var); \ - integer_runtime_only_param(_name, _var) -#define size_runtime_param(_name, _var) \ - size_param(_name, _var); \ - size_runtime_only_param(_name, _var) -#define string_runtime_param(_name, _var) \ - string_param(_name, _var); \ - string_runtime_only_param(_name, _var) - #endif /* __ASSEMBLY__ */ #ifdef CONFIG_LATE_HWDOM diff --git a/xen/include/xen/param.h b/xen/include/xen/param.h new file mode 100644 index 0000000000..75471eb4ad --- /dev/null +++ b/xen/include/xen/param.h @@ -0,0 +1,126 @@ +#ifndef _XEN_PARAM_H +#define _XEN_PARAM_H + +#include + +/* + * Used for kernel command line parameter setup + */ +struct kernel_param { + const char *name; + enum { + OPT_STR, + OPT_UINT, + OPT_BOOL, + OPT_SIZE, + OPT_CUSTOM, + OPT_IGNORE, + } type; + unsigned int len; + union { + void *var; + int (*func)(const char *); + } par; +}; + +extern const struct kernel_param __setup_start[], __setup_end[]; +extern const struct kernel_param __param_start[], __param_end[]; + +#define __dataparam __used_section(".data.param") + +#define __param(att) static const att \ + __attribute__((__aligned__(sizeof(void *)))) struct kernel_param + +#define __setup_str static const __initconst \ + __attribute__((__aligned__(1))) char +#define __kparam __param(__initsetup) + +#define custom_param(_name, _var) \ + __setup_str __setup_str_##_var[] = _name; \ + __kparam __setup_##_var = \ + { .name = __setup_str_##_var, \ + .type = OPT_CUSTOM, \ + .par.func = _var } +#define boolean_param(_name, _var) \ + __setup_str __setup_str_##_var[] = _name; \ + __kparam __setup_##_var = \ + { .name = __setup_str_##_var, \ + .type = OPT_BOOL, \ + .len = sizeof(_var), \ + .par.var = &_var } +#define integer_param(_name, _var) \ + __setup_str __setup_str_##_var[] = _name; \ + __kparam __setup_##_var = \ + { .name = __setup_str_##_var, \ + .type = OPT_UINT, \ + .len = sizeof(_var), \ + .par.var = &_var } +#define size_param(_name, _var) \ + __setup_str __setup_str_##_var[] = _name; \ + __kparam __setup_##_var = \ + { .name = __setup_str_##_var, \ + .type = OPT_SIZE, \ + .len = sizeof(_var), \ + .par.var = &_var } +#define string_param(_name, _var) \ + __setup_str __setup_str_##_var[] = _name; \ + __kparam __setup_##_var = \ + { .name = __setup_str_##_var, \ + .type = OPT_STR, \ + .len = sizeof(_var), \ + .par.var = &_var } +#define ignore_param(_name) \ + __setup_str setup_str_ign[] = _name; \ + __kparam setup_ign = \ + { .name = setup_str_ign, \ + .type = OPT_IGNORE } + +#define __rtparam __param(__dataparam) + +#define custom_runtime_only_param(_name, _var) \ + __rtparam __rtpar_##_var = \ + { .name = _name, \ + .type = OPT_CUSTOM, \ + .par.func = _var } +#define boolean_runtime_only_param(_name, _var) \ + __rtparam __rtpar_##_var = \ + { .name = _name, \ + .type = OPT_BOOL, \ + .len = sizeof(_var), \ + .par.var = &_var } +#define integer_runtime_only_param(_name, _var) \ + __rtparam __rtpar_##_var = \ + { .name = _name, \ + .type = OPT_UINT, \ + .len = sizeof(_var), \ + .par.var = &_var } +#define size_runtime_only_param(_name, _var) \ + __rtparam __rtpar_##_var = \ + { .name = _name, \ + .type = OPT_SIZE, \ + .len = sizeof(_var), \ + .par.var = &_var } +#define string_runtime_only_param(_name, _var) \ + __rtparam __rtpar_##_var = \ + { .name = _name, \ + .type = OPT_STR, \ + .len = sizeof(_var), \ + .par.var = &_var } + +#define custom_runtime_param(_name, _var) \ + custom_param(_name, _var); \ + custom_runtime_only_param(_name, _var) +#define boolean_runtime_param(_name, _var) \ + boolean_param(_name, _var); \ + boolean_runtime_only_param(_name, _var) +#define integer_runtime_param(_name, _var) \ + integer_param(_name, _var); \ + integer_runtime_only_param(_name, _var) +#define size_runtime_param(_name, _var) \ + size_param(_name, _var); \ + size_runtime_only_param(_name, _var) +#define string_runtime_param(_name, _var) \ + string_param(_name, _var); \ + string_runtime_only_param(_name, _var) + +#endif /* _XEN_PARAM_H */ diff --git a/xen/xsm/flask/flask_op.c b/xen/xsm/flask/flask_op.c index 1c4decc6cd..a5f2b104e2 100644 --- a/xen/xsm/flask/flask_op.c +++ b/xen/xsm/flask/flask_op.c @@ -13,6 +13,7 @@ #include #include #include +#include #include diff --git a/xen/xsm/xsm_core.c b/xen/xsm/xsm_core.c index a319df253d..5eab21e1b1 100644 --- a/xen/xsm/xsm_core.c +++ b/xen/xsm/xsm_core.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include From patchwork Tue Jan 21 08:43:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?SsO8cmdlbiBHcm/Dnw==?= X-Patchwork-Id: 11343185 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AC0BF6C1 for ; Tue, 21 Jan 2020 08:45:05 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 911CF24653 for ; Tue, 21 Jan 2020 08:45:05 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 911CF24653 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=suse.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1itp8T-0004T5-AZ; Tue, 21 Jan 2020 08:43:45 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1itp8S-0004Ss-5F for xen-devel@lists.xenproject.org; Tue, 21 Jan 2020 08:43:44 +0000 X-Inumbo-ID: 1bff8d16-3c2a-11ea-ba47-12813bfff9fa Received: from mx2.suse.de (unknown [195.135.220.15]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id 1bff8d16-3c2a-11ea-ba47-12813bfff9fa; Tue, 21 Jan 2020 08:43:35 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id F1DC7B2C5; Tue, 21 Jan 2020 08:43:33 +0000 (UTC) From: Juergen Gross To: xen-devel@lists.xenproject.org Date: Tue, 21 Jan 2020 09:43:24 +0100 Message-Id: <20200121084330.18309-4-jgross@suse.com> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20200121084330.18309-1-jgross@suse.com> References: <20200121084330.18309-1-jgross@suse.com> Subject: [Xen-devel] [PATCH v3 3/9] docs: add feature document for Xen hypervisor sysfs-like support X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Juergen Gross , Stefano Stabellini , Julien Grall , Wei Liu , Konrad Rzeszutek Wilk , George Dunlap , Andrew Cooper , Ian Jackson , Jan Beulich MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" On the 2019 Xen developer summit there was agreement that the Xen hypervisor should gain support for a hierarchical name-value store similar to the Linux kernel's sysfs. In the beginning there should only be basic support: entries can be added from the hypervisor itself only, there is a simple hypercall interface to read the data. Add a feature document for setting the base of a discussion regarding the desired functionality and the entries to add. Signed-off-by: Juergen Gross --- V1: - remove the "--" prefixes of the sub-commands of the user tool (Jan Beulich) - rename xenfs to xenhypfs (Jan Beulich) - add "tree" and "write" options to user tool V2: - move example tree to the paths description (Ian Jackson) - specify allowed characters for keys and values (Ian Jackson) V3: - correct introduction (writable entries) --- docs/features/hypervisorfs.pandoc | 86 +++++++++++++++++++++++++++++++++++ docs/misc/hypfs-paths.pandoc | 95 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 181 insertions(+) create mode 100644 docs/features/hypervisorfs.pandoc create mode 100644 docs/misc/hypfs-paths.pandoc diff --git a/docs/features/hypervisorfs.pandoc b/docs/features/hypervisorfs.pandoc new file mode 100644 index 0000000000..8e5deaacfb --- /dev/null +++ b/docs/features/hypervisorfs.pandoc @@ -0,0 +1,86 @@ +% Hypervisor FS +% Revision 1 + +\clearpage + +# Basics +---------------- --------------------- + Status: **Supported** + + Architectures: all + + Components: Hypervisor, toolstack +---------------- --------------------- + +# Overview + +The Hypervisor FS is a hierarchical name-value store for reporting +information to guests, especially dom0. It is similar to the Linux +kernel's sysfs. Entries and directories are created by the hypervisor, +while the toolstack is able to use a hypercall to query the entry +values or (if allowed by the hypervisor) to modify them. + +# User details + +With: + + xenhypfs ls + +the user can list the entries of a specific path of the FS. Using: + + xenhypfs cat + +the content of an entry can be retrieved. Using: + + xenhypfs write + +a writable entry can be modified. With: + + xenhypfs tree + +the complete Hypervisor FS entry tree can be printed. + +The FS paths are documented in `docs/misc/hypfs-paths.pandoc`. + +# Technical details + +Access to the hypervisor filesystem is done via the stable new hypercall +__HYPERVISOR_filesystem_op. + +* hypercall interface specification + * `xen/include/public/filesystem.h` +* hypervisor internal files + * `xen/include/xen/filesystem.h` + * `xen/common/filesystem.c` +* `libxenhypfs` + * `tools/libs/libxenhypfs/*` +* `xenhypfs` + * `tools/misc/xenhypfs.c` +* path documentation + * `docs/misc/hypfs-paths.pandoc` + +# Testing + +Any new parameters or hardware mitigations should be verified to show up +correctly in the filesystem. + +# Areas for improvement + +* More detailed access rights +* Entries per domain and/or per cpupool + +# Known issues + +* None + +# References + +* None + +# History + +------------------------------------------------------------------------ +Date Revision Version Notes +---------- -------- -------- ------------------------------------------- +2019-10-02 1 Xen 4.13 Document written +---------- -------- -------- ------------------------------------------- diff --git a/docs/misc/hypfs-paths.pandoc b/docs/misc/hypfs-paths.pandoc new file mode 100644 index 0000000000..67de8d2cf8 --- /dev/null +++ b/docs/misc/hypfs-paths.pandoc @@ -0,0 +1,95 @@ +# Xenhypfs Paths + +This document attempts to define all the paths which are available +in the Xen hypervisor file system (hypfs). + +The hypervisor file system can be accessed via the xenhypfs tool. + +## Notation + +The hypervisor file system is similar to the Linux kernel's sysfs. +In this document directories are always specified with a trailing "/". + +The following notation conventions apply: + + DIRECTORY/ + + PATH = VALUES [TAGS] + +The first syntax defines a directory. It normally contains related +entries and the general scope of the directory is described. + +The second syntax defines a file entry containing values which are +either set by the hypervisor or, if the file is writable, can be set +by the user. + +PATH can contain simple regex constructs following the Perl compatible +regexp syntax described in pcre(3) or perlre(1). + +A hypervisor file system entry name can be any 0-delimited byte string +not containing any '/' character. The names "." and ".." are reserved +for file system internal use. + +VALUES are strings and can take the following forms: + +* STRING -- an arbitrary 0-delimited byte string. +* INTEGER -- An integer, in decimal representation unless otherwise + noted. +* "a literal string" -- literal strings are contained within quotes. +* (VALUE | VALUE | ... ) -- a set of alternatives. Alternatives are + separated by a "|" and all the alternatives are enclosed in "(" and + ")". + +Additional TAGS may follow as a comma separated set of the following +tags enclosed in square brackets. + +* w -- Path is writable by the user. This capability is usually + limited to the control domain (e.g. dom0). +* ARM | ARM32 | X86: the path is available for the respective architecture + only. +* PV -- Path is valid for PV capable hypervisors only. +* HVM -- Path is valid for HVM capable hypervisors only. +* CONFIG_* -- Path is valid only in case the hypervisor was built with + the respective config option. + +## Example + +A populated Xen hypervisor file system might look like the following example: + + / + buildinfo/ directory containing build-time data + config contents of .config file used to build Xen + cpu-bugs/ x86: directory of cpu bug information + l1tf "Vulnerable" or "Not vulnerable" + mds "Vulnerable" or "Not vulnerable" + meltdown "Vulnerable" or "Not vulnerable" + spec-store-bypass "Vulnerable" or "Not vulnerable" + spectre-v1 "Vulnerable" or "Not vulnerable" + spectre-v2 "Vulnerable" or "Not vulnerable" + mitigations/ directory of mitigation settings + bti-thunk "N/A", "RETPOLINE", "LFENCE" or "JMP" + spec-ctrl "No", "IBRS+" or IBRS-" + ibpb "No" or "Yes" + l1d-flush "No" or "Yes" + md-clear "No" or "VERW" + l1tf-barrier "No" or "Yes" + active-hvm/ directory for mitigations active in hvm doamins + msr-spec-ctrl "No" or "Yes" + rsb "No" or "Yes" + eager-fpu "No" or "Yes" + md-clear "No" or "Yes" + active-pv/ directory for mitigations active in pv doamins + msr-spec-ctrl "No" or "Yes" + rsb "No" or "Yes" + eager-fpu "No" or "Yes" + md-clear "No" or "Yes" + xpti "No" or list of "dom0", "domU", "PCID on" + l1tf-shadow "No" or list of "dom0", "domU" + params/ directory with hypervisor parameter values + (boot/runtime parameters) + +## General Paths + +#### / + +The root of the hypervisor file system. From patchwork Tue Jan 21 08:43:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?SsO8cmdlbiBHcm/Dnw==?= X-Patchwork-Id: 11343199 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3F93F17EA for ; Tue, 21 Jan 2020 08:45:32 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 1B69E24125 for ; Tue, 21 Jan 2020 08:45:32 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1B69E24125 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=suse.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1itp8m-0004dm-Rm; Tue, 21 Jan 2020 08:44:04 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1itp8m-0004dR-6C for xen-devel@lists.xenproject.org; Tue, 21 Jan 2020 08:44:04 +0000 X-Inumbo-ID: 1ed01392-3c2a-11ea-ba47-12813bfff9fa Received: from mx2.suse.de (unknown [195.135.220.15]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id 1ed01392-3c2a-11ea-ba47-12813bfff9fa; Tue, 21 Jan 2020 08:43:39 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 4143CB2BD; Tue, 21 Jan 2020 08:43:34 +0000 (UTC) From: Juergen Gross To: xen-devel@lists.xenproject.org Date: Tue, 21 Jan 2020 09:43:25 +0100 Message-Id: <20200121084330.18309-5-jgross@suse.com> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20200121084330.18309-1-jgross@suse.com> References: <20200121084330.18309-1-jgross@suse.com> Subject: [Xen-devel] [PATCH v3 4/9] xen: add basic hypervisor filesystem support X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Juergen Gross , Stefano Stabellini , Julien Grall , Wei Liu , Konrad Rzeszutek Wilk , George Dunlap , Andrew Cooper , Ian Jackson , Jan Beulich , Volodymyr Babchuk , =?utf-8?q?Roger_Pau_Monn?= =?utf-8?q?=C3=A9?= MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Add the infrastructure for the hypervisor filesystem. This includes the hypercall interface and the base functions for entry creation, deletion and modification. Signed-off-by: Juergen Gross --- V1: - rename files from filesystem.* to hypfs.* - add dummy write entry support - rename hypercall filesystem_op to hypfs_op - add support for unsigned integer entries V2: - test new entry name to be valid V3: - major rework, especially by supporting binary contents of entries - addressed all comments --- xen/arch/arm/traps.c | 1 + xen/arch/x86/hvm/hypercall.c | 1 + xen/arch/x86/hypercall.c | 1 + xen/arch/x86/pv/hypercall.c | 1 + xen/common/Makefile | 1 + xen/common/hypfs.c | 365 +++++++++++++++++++++++++++++++++++++++++++ xen/include/public/hypfs.h | 124 +++++++++++++++ xen/include/public/xen.h | 1 + xen/include/xen/hypercall.h | 8 + xen/include/xen/hypfs.h | 89 +++++++++++ 10 files changed, 592 insertions(+) create mode 100644 xen/common/hypfs.c create mode 100644 xen/include/public/hypfs.h create mode 100644 xen/include/xen/hypfs.h diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c index 6f9bec22d3..87af810667 100644 --- a/xen/arch/arm/traps.c +++ b/xen/arch/arm/traps.c @@ -1382,6 +1382,7 @@ static arm_hypercall_t arm_hypercall_table[] = { #ifdef CONFIG_ARGO HYPERCALL(argo_op, 5), #endif + HYPERCALL(hypfs_op, 5), }; #ifndef NDEBUG diff --git a/xen/arch/x86/hvm/hypercall.c b/xen/arch/x86/hvm/hypercall.c index 33dd2d99d2..210dda4f38 100644 --- a/xen/arch/x86/hvm/hypercall.c +++ b/xen/arch/x86/hvm/hypercall.c @@ -144,6 +144,7 @@ static const hypercall_table_t hvm_hypercall_table[] = { #endif HYPERCALL(xenpmu_op), COMPAT_CALL(dm_op), + HYPERCALL(hypfs_op), HYPERCALL(arch_1) }; diff --git a/xen/arch/x86/hypercall.c b/xen/arch/x86/hypercall.c index 7f299d45c6..05a3f5e25b 100644 --- a/xen/arch/x86/hypercall.c +++ b/xen/arch/x86/hypercall.c @@ -73,6 +73,7 @@ const hypercall_args_t hypercall_args_table[NR_hypercalls] = ARGS(hvm_op, 2), ARGS(dm_op, 3), #endif + ARGS(hypfs_op, 5), ARGS(mca, 1), ARGS(arch_1, 1), }; diff --git a/xen/arch/x86/pv/hypercall.c b/xen/arch/x86/pv/hypercall.c index 17ddf9ea1f..83907d4f00 100644 --- a/xen/arch/x86/pv/hypercall.c +++ b/xen/arch/x86/pv/hypercall.c @@ -85,6 +85,7 @@ const hypercall_table_t pv_hypercall_table[] = { HYPERCALL(hvm_op), COMPAT_CALL(dm_op), #endif + HYPERCALL(hypfs_op), HYPERCALL(mca), HYPERCALL(arch_1), }; diff --git a/xen/common/Makefile b/xen/common/Makefile index 62b34e69e9..a3f66aa0c0 100644 --- a/xen/common/Makefile +++ b/xen/common/Makefile @@ -11,6 +11,7 @@ obj-y += domain.o obj-y += event_2l.o obj-y += event_channel.o obj-y += event_fifo.o +obj-y += hypfs.o obj-$(CONFIG_CRASH_DEBUG) += gdbstub.o obj-$(CONFIG_GRANT_TABLE) += grant_table.o obj-y += guestcopy.o diff --git a/xen/common/hypfs.c b/xen/common/hypfs.c new file mode 100644 index 0000000000..6762d20dfd --- /dev/null +++ b/xen/common/hypfs.c @@ -0,0 +1,365 @@ +/****************************************************************************** + * + * hypfs.c + * + * Simple sysfs-like file system for the hypervisor. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define DIRENTRY_NAME_OFF offsetof(struct xen_hypfs_dirlistentry, name) +#define DIRENTRY_SIZE(name_len) \ + (DIRENTRY_NAME_OFF + ROUNDUP(name_len, alignof(struct xen_hypfs_direntry))) + +static DEFINE_RWLOCK(hypfs_lock); + +HYPFS_DIR_INIT(hypfs_root, ""); + +static int add_entry(struct hypfs_entry_dir *parent, struct hypfs_entry *new) +{ + int ret = -ENOENT; + struct hypfs_entry *e; + + write_lock(&hypfs_lock); + + list_for_each_entry ( e, &parent->dirlist, list ) + { + int cmp = strcmp(e->name, new->name); + + if ( cmp > 0 ) + { + ret = 0; + list_add_tail(&new->list, &e->list); + break; + } + if ( cmp == 0 ) + { + ret = -EEXIST; + break; + } + } + + if ( ret == -ENOENT ) + { + ret = 0; + list_add_tail(&new->list, &parent->dirlist); + } + + if ( !ret ) + { + unsigned int sz = strlen(new->name) + 1; + + parent->e.size += DIRENTRY_SIZE(sz); + } + + write_unlock(&hypfs_lock); + + return ret; +} + +int hypfs_add_entry(struct hypfs_entry_dir *parent, + struct hypfs_entry *entry, bool nofault) +{ + int ret; + + ret = add_entry(parent, entry); + BUG_ON(nofault && ret); + + return ret; +} + +int hypfs_add_dir(struct hypfs_entry_dir *parent, + struct hypfs_entry_dir *dir, bool nofault) +{ + int ret; + + ret = add_entry(parent, &dir->e); + BUG_ON(nofault && ret); + + return ret; +} + +int hypfs_add_leaf(struct hypfs_entry_dir *parent, + struct hypfs_entry_leaf *leaf, bool nofault) +{ + int ret; + + if ( !leaf->content ) + ret = -EINVAL; + else + ret = add_entry(parent, &leaf->e); + BUG_ON(nofault && ret); + + return ret; +} + +static int hypfs_get_path_user(char *buf, XEN_GUEST_HANDLE_PARAM(void) uaddr, + unsigned long len) +{ + if ( len > XEN_HYPFS_MAX_PATHLEN ) + return -EINVAL; + + if ( copy_from_guest(buf, uaddr, len) ) + return -EFAULT; + + if ( buf[len - 1] ) + return -EINVAL; + + return 0; +} + +static struct hypfs_entry *hypfs_get_entry_rel(struct hypfs_entry_dir *dir, + const char *path) +{ + const char *end; + struct hypfs_entry *entry; + unsigned int name_len; + + if ( !*path ) + return &dir->e; + + if ( dir->e.type != XEN_HYPFS_TYPE_DIR ) + return NULL; + + end = strchr(path, '/'); + if ( !end ) + end = strchr(path, '\0'); + name_len = end - path; + + list_for_each_entry ( entry, &dir->dirlist, list ) + { + int cmp = strncmp(path, entry->name, name_len); + struct hypfs_entry_dir *d = container_of(entry, + struct hypfs_entry_dir, e); + + if ( cmp < 0 ) + return NULL; + if ( !cmp && strlen(entry->name) == name_len ) + return *end ? hypfs_get_entry_rel(d, end + 1) : entry; + } + + return NULL; +} + +struct hypfs_entry *hypfs_get_entry(const char *path) +{ + if ( path[0] != '/' ) + return NULL; + + return hypfs_get_entry_rel(&hypfs_root, path + 1); +} + +int hypfs_read_dir(const struct hypfs_entry *entry, + XEN_GUEST_HANDLE_PARAM(void) uaddr) +{ + const struct hypfs_entry_dir *d; + struct hypfs_entry *e; + unsigned int size = entry->size; + + d = container_of(entry, const struct hypfs_entry_dir, e); + + list_for_each_entry ( e, &d->dirlist, list ) + { + struct xen_hypfs_dirlistentry direntry; + unsigned int e_namelen = strlen(e->name) + 1; + unsigned int e_len = DIRENTRY_SIZE(e_namelen); + + direntry.e.flags = e->write ? XEN_HYPFS_WRITEABLE : 0; + direntry.e.type = e->type; + direntry.e.encoding = e->encoding; + direntry.e.content_len = e->size; + direntry.off_next = list_is_last(&e->list, &d->dirlist) ? 0 : e_len; + if ( copy_to_guest(uaddr, &direntry, 1) ) + return -EFAULT; + + if ( copy_to_guest_offset(uaddr, DIRENTRY_NAME_OFF, + e->name, e_namelen) ) + return -EFAULT; + + guest_handle_add_offset(uaddr, e_len); + + ASSERT(e_len <= size); + size -= e_len; + } + + return 0; +} + +int hypfs_read_leaf(const struct hypfs_entry *entry, + XEN_GUEST_HANDLE_PARAM(void) uaddr) +{ + const struct hypfs_entry_leaf *l; + + l = container_of(entry, const struct hypfs_entry_leaf, e); + + return copy_to_guest(uaddr, l->content, entry->size) ? -EFAULT: 0; +} + +static int hypfs_read(const struct hypfs_entry *entry, + XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned long ulen) +{ + struct xen_hypfs_direntry e; + long ret = -EINVAL; + + if ( ulen < sizeof(e) ) + goto out; + + e.flags = entry->write ? XEN_HYPFS_WRITEABLE : 0; + e.type = entry->type; + e.encoding = entry->encoding; + e.content_len = entry->size; + + ret = -EFAULT; + if ( copy_to_guest(uaddr, &e, 1) ) + goto out; + + ret = 0; + if ( ulen < entry->size + sizeof(e) ) + goto out; + + guest_handle_add_offset(uaddr, sizeof(e)); + + ret = entry->read(entry, uaddr); + + out: + return ret; +} + +int hypfs_write_leaf(struct hypfs_entry_leaf *leaf, + XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned long ulen) +{ + char *buf; + int ret; + + if ( ulen > leaf->e.size ) + ulen = leaf->e.size; + + buf = xzalloc_array(char, ulen); + if ( !buf ) + return -ENOMEM; + + ret = -EFAULT; + if ( copy_from_guest(buf, uaddr, ulen) ) + goto out; + + ret = 0; + if ( leaf->e.type == XEN_HYPFS_TYPE_STRING ) + buf[leaf->e.size - 1] = 0; + memcpy(leaf->write_ptr, buf, ulen); + + out: + xfree(buf); + return ret; +} + +int hypfs_write_bool(struct hypfs_entry_leaf *leaf, + XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned long ulen) +{ + union { + char buf[8]; + uint8_t u8; + uint16_t u16; + uint32_t u32; + uint64_t u64; + } u; + + ASSERT(leaf->e.type == XEN_HYPFS_TYPE_UINT && leaf->e.size <= 8); + + if ( ulen != leaf->e.size ) + return -EDOM; + + if ( copy_from_guest(u.buf, uaddr, ulen) ) + return -EFAULT; + + switch ( leaf->e.size ) + { + case 1: + *(uint8_t *)leaf->write_ptr = !!u.u8; + break; + case 2: + *(uint16_t *)leaf->write_ptr = !!u.u16; + break; + case 4: + *(uint32_t *)leaf->write_ptr = !!u.u32; + break; + case 8: + *(uint64_t *)leaf->write_ptr = !!u.u64; + break; + } + + return 0; +} + +static int hypfs_write(struct hypfs_entry *entry, + XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned long ulen) +{ + struct hypfs_entry_leaf *l; + + if ( !entry->write ) + return -EACCES; + + l = container_of(entry, struct hypfs_entry_leaf, e); + + return entry->write(l, uaddr, ulen); +} + +long do_hypfs_op(unsigned int cmd, + XEN_GUEST_HANDLE_PARAM(void) arg1, unsigned long arg2, + XEN_GUEST_HANDLE_PARAM(void) arg3, unsigned long arg4) +{ + int ret; + struct hypfs_entry *entry; + static char path[XEN_HYPFS_MAX_PATHLEN]; + + if ( !is_control_domain(current->domain) && + !is_hardware_domain(current->domain) ) + return -EPERM; + + if ( cmd == XEN_HYPFS_OP_get_version ) + return XEN_HYPFS_VERSION; + + if ( cmd == XEN_HYPFS_OP_write_contents ) + write_lock(&hypfs_lock); + else + read_lock(&hypfs_lock); + + ret = hypfs_get_path_user(path, arg1, arg2); + if ( ret ) + goto out; + + entry = hypfs_get_entry(path); + if ( !entry ) + { + ret = -ENOENT; + goto out; + } + + switch ( cmd ) + { + case XEN_HYPFS_OP_read_contents: + ret = hypfs_read(entry, arg3, arg4); + break; + + case XEN_HYPFS_OP_write_contents: + ret = hypfs_write(entry, arg3, arg4); + break; + + default: + ret = -ENOSYS; + break; + } + + out: + if ( cmd == XEN_HYPFS_OP_write_contents ) + write_unlock(&hypfs_lock); + else + read_unlock(&hypfs_lock); + + return ret; +} diff --git a/xen/include/public/hypfs.h b/xen/include/public/hypfs.h new file mode 100644 index 0000000000..8351511227 --- /dev/null +++ b/xen/include/public/hypfs.h @@ -0,0 +1,124 @@ +/****************************************************************************** + * Xen Hypervisor Filesystem + * + * Copyright (c) 2019, SUSE Software Solutions Germany GmbH + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __XEN_PUBLIC_HYPFS_H__ +#define __XEN_PUBLIC_HYPFS_H__ + +#include "xen.h" + +/* + * Definitions for the __HYPERVISOR_hypfs_op hypercall. + */ + +/* Highest version number of the hypfs interface currently defined. */ +#define XEN_HYPFS_VERSION 1 + +/* Maximum length of a path in the filesystem. */ +#define XEN_HYPFS_MAX_PATHLEN 1024 + +struct xen_hypfs_direntry { + uint16_t flags; +#define XEN_HYPFS_WRITEABLE 0x0001 + uint8_t type; +#define XEN_HYPFS_TYPE_DIR 0x0000 +#define XEN_HYPFS_TYPE_BLOB 0x0001 +#define XEN_HYPFS_TYPE_STRING 0x0002 +#define XEN_HYPFS_TYPE_UINT 0x0003 +#define XEN_HYPFS_TYPE_INT 0x0004 +#define XEN_HYPFS_TYPE_BOOL 0x0005 + uint8_t encoding; +#define XEN_HYPFS_ENC_PLAIN 0x0000 +#define XEN_HYPFS_ENC_GZIP 0x0001 + uint32_t content_len; +}; + +struct xen_hypfs_dirlistentry { + struct xen_hypfs_direntry e; + /* Offset in bytes to next entry (0 == this is the last entry). */ + uint16_t off_next; + char name[XEN_FLEX_ARRAY_DIM]; +}; + +/* + * Hypercall operations. + */ + +/* + * XEN_HYPFS_OP_get_version + * + * Read highest interface version supported by the hypervisor. + * + * Possible return values: + * >0: highest supported interface version + * <0: negative Xen errno value + */ +#define XEN_HYPFS_OP_get_version 0 + +/* + * XEN_HYPFS_OP_read_contents + * + * Read contents of a filesystem entry. + * + * Returns the direntry and contents of an entry in the buffer supplied by the + * caller (struct xen_hypfs_direntry with the contents following directly + * after it). + * The data buffer must be at least the size of the direntry returned in order + * to have success. If the data buffer was not large enough for all the data + * no entry data is returned, but the direntry will contain the needed size + * for the returned data. + * The format of the contents is according to its entry type and encoding. + * + * arg1: XEN_GUEST_HANDLE(path name) + * arg2: length of path name (including trailing zero byte) + * arg3: XEN_GUEST_HANDLE(data buffer written by hypervisor) + * arg4: data buffer size + * + * Possible return values: + * 0: success (at least the direntry was returned) + * <0 : negative Xen errno value + */ +#define XEN_HYPFS_OP_read_contents 1 + +/* + * XEN_HYPFS_OP_write_contents + * + * Write contents of a filesystem entry. + * + * Writes an entry with the contents of a buffer supplied by the caller. + * The data type and encoding can't be changed. The size can be changed only + * for blobs and strings. + * + * arg1: XEN_GUEST_HANDLE(path name) + * arg2: length of path name (including trailing zero byte) + * arg3: XEN_GUEST_HANDLE(content buffer read by hypervisor) + * arg4: content buffer size + * + * Possible return values: + * 0: success + * <0 : negative Xen errno value + */ +#define XEN_HYPFS_OP_write_contents 2 + +#endif /* __XEN_PUBLIC_HYPFS_H__ */ diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h index d2198dffad..bf80f1da8c 100644 --- a/xen/include/public/xen.h +++ b/xen/include/public/xen.h @@ -130,6 +130,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_ulong_t); #define __HYPERVISOR_argo_op 39 #define __HYPERVISOR_xenpmu_op 40 #define __HYPERVISOR_dm_op 41 +#define __HYPERVISOR_hypfs_op 42 /* Architecture-specific hypercall definitions. */ #define __HYPERVISOR_arch_0 48 diff --git a/xen/include/xen/hypercall.h b/xen/include/xen/hypercall.h index ad8ad27b23..349a0f6487 100644 --- a/xen/include/xen/hypercall.h +++ b/xen/include/xen/hypercall.h @@ -150,6 +150,14 @@ do_dm_op( unsigned int nr_bufs, XEN_GUEST_HANDLE_PARAM(xen_dm_op_buf_t) bufs); +extern long +do_hypfs_op( + unsigned int cmd, + XEN_GUEST_HANDLE_PARAM(void) arg1, + unsigned long arg2, + XEN_GUEST_HANDLE_PARAM(void) arg3, + unsigned long arg4); + #ifdef CONFIG_COMPAT extern int diff --git a/xen/include/xen/hypfs.h b/xen/include/xen/hypfs.h new file mode 100644 index 0000000000..a1c2140398 --- /dev/null +++ b/xen/include/xen/hypfs.h @@ -0,0 +1,89 @@ +#ifndef __XEN_HYPFS_H__ +#define __XEN_HYPFS_H__ + +#include +#include +#include + +struct hypfs_entry_leaf; + +struct hypfs_entry { + unsigned short type; + unsigned short encoding; + unsigned int size; + const char *name; + struct list_head list; + int (*read)(const struct hypfs_entry *entry, + XEN_GUEST_HANDLE_PARAM(void) uaddr); + int (*write)(struct hypfs_entry_leaf *leaf, + XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned long ulen); +}; + +struct hypfs_entry_leaf { + struct hypfs_entry e; + union { + const void *content; + void *write_ptr; + }; +}; + +struct hypfs_entry_dir { + struct hypfs_entry e; + struct list_head dirlist; +}; + +#define HYPFS_DIR_INIT(var, nam) \ + struct hypfs_entry_dir var = { \ + .e.type = XEN_HYPFS_TYPE_DIR, \ + .e.encoding = XEN_HYPFS_ENC_PLAIN, \ + .e.name = nam, \ + .e.size = 0, \ + .e.list = LIST_HEAD_INIT(var.e.list), \ + .e.read = hypfs_read_dir, \ + .dirlist = LIST_HEAD_INIT(var.dirlist), \ + } + +/* Content and size need to be set via hypfs_string_set(). */ +#define HYPFS_STRING_INIT(var, nam) \ + struct hypfs_entry_leaf var = { \ + .e.type = XEN_HYPFS_TYPE_STRING, \ + .e.encoding = XEN_HYPFS_ENC_PLAIN, \ + .e.name = nam, \ + .e.read = hypfs_read_leaf, \ + } + +static inline void hypfs_string_set(struct hypfs_entry_leaf *leaf, + const char *str) +{ + leaf->content = str; + leaf->e.size = strlen(str) + 1; +} + +#define HYPFS_UINT_INIT(var, nam, uint) \ + struct hypfs_entry_leaf var = { \ + .e.type = XEN_HYPFS_TYPE_UINT, \ + .e.encoding = XEN_HYPFS_ENC_PLAIN, \ + .e.name = nam, \ + .e.size = sizeof(uint), \ + .e.read = hypfs_read_leaf, \ + .content = &uint, \ + } + + +extern struct hypfs_entry_dir hypfs_root; + +struct hypfs_entry *hypfs_get_entry(const char *path); +int hypfs_add_dir(struct hypfs_entry_dir *parent, + struct hypfs_entry_dir *dir, bool nofault); +int hypfs_add_leaf(struct hypfs_entry_dir *parent, + struct hypfs_entry_leaf *leaf, bool nofault); +int hypfs_read_dir(const struct hypfs_entry *entry, + XEN_GUEST_HANDLE_PARAM(void) uaddr); +int hypfs_read_leaf(const struct hypfs_entry *entry, + XEN_GUEST_HANDLE_PARAM(void) uaddr); +int hypfs_write_leaf(struct hypfs_entry_leaf *leaf, + XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned long ulen); +int hypfs_write_bool(struct hypfs_entry_leaf *leaf, + XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned long ulen); + +#endif /* __XEN_HYPFS_H__ */ From patchwork Tue Jan 21 08:43:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?SsO8cmdlbiBHcm/Dnw==?= X-Patchwork-Id: 11343195 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8689017EA for ; Tue, 21 Jan 2020 08:45:30 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 624F424125 for ; Tue, 21 Jan 2020 08:45:30 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 624F424125 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=suse.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1itp8Y-0004Ut-V9; Tue, 21 Jan 2020 08:43:50 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1itp8X-0004U6-5g for xen-devel@lists.xenproject.org; Tue, 21 Jan 2020 08:43:49 +0000 X-Inumbo-ID: 1c5ba3c4-3c2a-11ea-ba47-12813bfff9fa Received: from mx2.suse.de (unknown [195.135.220.15]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id 1c5ba3c4-3c2a-11ea-ba47-12813bfff9fa; Tue, 21 Jan 2020 08:43:35 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 84DE4B2C6; Tue, 21 Jan 2020 08:43:34 +0000 (UTC) From: Juergen Gross To: xen-devel@lists.xenproject.org Date: Tue, 21 Jan 2020 09:43:26 +0100 Message-Id: <20200121084330.18309-6-jgross@suse.com> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20200121084330.18309-1-jgross@suse.com> References: <20200121084330.18309-1-jgross@suse.com> Subject: [Xen-devel] [PATCH v3 5/9] libs: add libxenhypfs X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Juergen Gross , Stefano Stabellini , Julien Grall , Wei Liu , Konrad Rzeszutek Wilk , George Dunlap , Andrew Cooper , Ian Jackson , Jan Beulich MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Add the new library libxenhypfs for access to the hypervisor filesystem. Signed-off-by: Juergen Gross --- V1: - rename to libxenhypfs - add xenhypfs_write() V3: - major rework due to new hypervisor interface - add decompression capability --- .gitignore | 2 + tools/Rules.mk | 6 + tools/libs/Makefile | 1 + tools/libs/hypfs/Makefile | 16 ++ tools/libs/hypfs/core.c | 535 ++++++++++++++++++++++++++++++++++++ tools/libs/hypfs/include/xenhypfs.h | 75 +++++ tools/libs/hypfs/libxenhypfs.map | 10 + tools/libs/hypfs/xenhypfs.pc.in | 10 + 8 files changed, 655 insertions(+) create mode 100644 tools/libs/hypfs/Makefile create mode 100644 tools/libs/hypfs/core.c create mode 100644 tools/libs/hypfs/include/xenhypfs.h create mode 100644 tools/libs/hypfs/libxenhypfs.map create mode 100644 tools/libs/hypfs/xenhypfs.pc.in diff --git a/.gitignore b/.gitignore index b2624df79a..e98c3f056d 100644 --- a/.gitignore +++ b/.gitignore @@ -109,6 +109,8 @@ tools/libs/evtchn/headers.chk tools/libs/evtchn/xenevtchn.pc tools/libs/gnttab/headers.chk tools/libs/gnttab/xengnttab.pc +tools/libs/hypfs/headers.chk +tools/libs/hypfs/xenhypfs.pc tools/libs/call/headers.chk tools/libs/call/xencall.pc tools/libs/foreignmemory/headers.chk diff --git a/tools/Rules.mk b/tools/Rules.mk index 52f47be3f8..a04697a33c 100644 --- a/tools/Rules.mk +++ b/tools/Rules.mk @@ -19,6 +19,7 @@ XEN_LIBXENGNTTAB = $(XEN_ROOT)/tools/libs/gnttab XEN_LIBXENCALL = $(XEN_ROOT)/tools/libs/call XEN_LIBXENFOREIGNMEMORY = $(XEN_ROOT)/tools/libs/foreignmemory XEN_LIBXENDEVICEMODEL = $(XEN_ROOT)/tools/libs/devicemodel +XEN_LIBXENHYPFS = $(XEN_ROOT)/tools/libs/hypfs XEN_LIBXC = $(XEN_ROOT)/tools/libxc XEN_XENLIGHT = $(XEN_ROOT)/tools/libxl # Currently libxlutil lives in the same directory as libxenlight @@ -134,6 +135,11 @@ SHDEPS_libxendevicemodel = $(SHLIB_libxentoollog) $(SHLIB_libxentoolcore) $(SHLI LDLIBS_libxendevicemodel = $(SHDEPS_libxendevicemodel) $(XEN_LIBXENDEVICEMODEL)/libxendevicemodel$(libextension) SHLIB_libxendevicemodel = $(SHDEPS_libxendevicemodel) -Wl,-rpath-link=$(XEN_LIBXENDEVICEMODEL) +CFLAGS_libxenhypfs = -I$(XEN_LIBXENHYPFS)/include $(CFLAGS_xeninclude) +SHDEPS_libxenhypfs = $(SHLIB_libxentoollog) $(SHLIB_libxentoolcore) $(SHLIB_xencall) +LDLIBS_libxenhypfs = $(SHDEPS_libxenhypfs) $(XEN_LIBXENHYPFS)/libxenhypfs$(libextension) +SHLIB_libxenhypfs = $(SHDEPS_libxenhypfs) -Wl,-rpath-link=$(XEN_LIBXENHYPFS) + # code which compiles against libxenctrl get __XEN_TOOLS__ and # therefore sees the unstable hypercall interfaces. CFLAGS_libxenctrl = -I$(XEN_LIBXC)/include $(CFLAGS_libxentoollog) $(CFLAGS_libxenforeignmemory) $(CFLAGS_libxendevicemodel) $(CFLAGS_xeninclude) -D__XEN_TOOLS__ diff --git a/tools/libs/Makefile b/tools/libs/Makefile index 88901e7341..69cdfb5975 100644 --- a/tools/libs/Makefile +++ b/tools/libs/Makefile @@ -9,6 +9,7 @@ SUBDIRS-y += gnttab SUBDIRS-y += call SUBDIRS-y += foreignmemory SUBDIRS-y += devicemodel +SUBDIRS-y += hypfs ifeq ($(CONFIG_RUMP),y) SUBDIRS-y := toolcore diff --git a/tools/libs/hypfs/Makefile b/tools/libs/hypfs/Makefile new file mode 100644 index 0000000000..06dd449929 --- /dev/null +++ b/tools/libs/hypfs/Makefile @@ -0,0 +1,16 @@ +XEN_ROOT = $(CURDIR)/../../.. +include $(XEN_ROOT)/tools/Rules.mk + +MAJOR = 1 +MINOR = 0 +LIBNAME := hypfs +USELIBS := toollog toolcore call + +APPEND_LDFLAGS += -lz + +SRCS-y += core.c + +include ../libs.mk + +$(PKG_CONFIG_LOCAL): PKG_CONFIG_INCDIR = $(XEN_LIBXENHYPFS)/include +$(PKG_CONFIG_LOCAL): PKG_CONFIG_CFLAGS_LOCAL = $(CFLAGS_xeninclude) diff --git a/tools/libs/hypfs/core.c b/tools/libs/hypfs/core.c new file mode 100644 index 0000000000..0144c20266 --- /dev/null +++ b/tools/libs/hypfs/core.c @@ -0,0 +1,535 @@ +/* + * Copyright (c) 2019 SUSE Software Solutions Germany GmbH + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; If not, see . + */ + +#define __XEN_TOOLS__ 1 + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#define BUF_SIZE 4096 + +struct xenhypfs_handle { + xentoollog_logger *logger, *logger_tofree; + unsigned int flags; + xencall_handle *xcall; +}; + +xenhypfs_handle *xenhypfs_open(xentoollog_logger *logger, + unsigned open_flags) +{ + xenhypfs_handle *fshdl = calloc(1, sizeof(*fshdl)); + + if (!fshdl) + return NULL; + + fshdl->flags = open_flags; + fshdl->logger = logger; + fshdl->logger_tofree = NULL; + + if (!fshdl->logger) { + fshdl->logger = fshdl->logger_tofree = + (xentoollog_logger*) + xtl_createlogger_stdiostream(stderr, XTL_PROGRESS, 0); + if (!fshdl->logger) + goto err; + } + + fshdl->xcall = xencall_open(fshdl->logger, 0); + if (!fshdl->xcall) + goto err; + + /* No need to remember supported version, we only support V1. */ + if (xencall1(fshdl->xcall, __HYPERVISOR_hypfs_op, + XEN_HYPFS_OP_get_version) < 0) + goto err; + + return fshdl; + +err: + xtl_logger_destroy(fshdl->logger_tofree); + xencall_close(fshdl->xcall); + free(fshdl); + return NULL; +} + +int xenhypfs_close(xenhypfs_handle *fshdl) +{ + if (!fshdl) + return 0; + + xencall_close(fshdl->xcall); + xtl_logger_destroy(fshdl->logger_tofree); + free(fshdl); + return 0; +} + +static int xenhypfs_get_pathbuf(xenhypfs_handle *fshdl, const char *path, + char **path_buf) +{ + int ret = -1; + int path_sz; + + if (!fshdl) { + errno = EBADF; + goto out; + } + + path_sz = strlen(path) + 1; + if (path_sz > XEN_HYPFS_MAX_PATHLEN) + { + errno = ENAMETOOLONG; + goto out; + } + + *path_buf = xencall_alloc_buffer(fshdl->xcall, path_sz); + if (!*path_buf) { + errno = ENOMEM; + goto out; + } + strcpy(*path_buf, path); + + ret = path_sz; + + out: + return ret; +} + +static void *xenhypfs_inflate(void *in_data, size_t *sz) +{ + unsigned char *workbuf; + void *content = NULL; + unsigned int out_sz; + z_stream z = { .opaque = NULL }; + int ret; + + workbuf = malloc(BUF_SIZE); + if (!workbuf) + return NULL; + + z.next_in = in_data; + z.avail_in = *sz; + ret = inflateInit2(&z, MAX_WBITS + 32); /* 32 == gzip */ + + for (*sz = 0; ret == Z_OK; *sz += out_sz) { + z.next_out = workbuf; + z.avail_out = BUF_SIZE; + ret = inflate(&z, Z_SYNC_FLUSH); + if (ret != Z_OK && ret != Z_STREAM_END) + break; + + out_sz = z.next_out - workbuf; + content = realloc(content, *sz + out_sz); + if (!content) { + ret = Z_MEM_ERROR; + break; + } + memcpy(content + *sz, workbuf, out_sz); + } + + inflateEnd(&z); + if (ret != Z_STREAM_END) { + free(content); + content = NULL; + errno = EIO; + } + free(workbuf); + return content; +} + +static void xenhypfs_set_attrs(struct xen_hypfs_direntry *entry, + struct xenhypfs_dirent *dirent) +{ + dirent->size = entry->content_len; + + switch(entry->type) { + case XEN_HYPFS_TYPE_DIR: + dirent->type = xenhypfs_type_dir; + break; + case XEN_HYPFS_TYPE_BLOB: + dirent->type = xenhypfs_type_blob; + break; + case XEN_HYPFS_TYPE_STRING: + dirent->type = xenhypfs_type_string; + break; + case XEN_HYPFS_TYPE_UINT: + dirent->type = xenhypfs_type_uint; + break; + case XEN_HYPFS_TYPE_INT: + dirent->type = xenhypfs_type_int; + break; + case XEN_HYPFS_TYPE_BOOL: + dirent->type = xenhypfs_type_bool; + break; + default: + dirent->type = xenhypfs_type_blob; + } + + switch (entry->encoding) { + case XEN_HYPFS_ENC_PLAIN: + dirent->encoding = xenhypfs_enc_plain; + break; + case XEN_HYPFS_ENC_GZIP: + dirent->encoding = xenhypfs_enc_gzip; + break; + default: + dirent->encoding = xenhypfs_enc_plain; + dirent->type = xenhypfs_type_blob; + } + + dirent->is_writable = entry->flags & XEN_HYPFS_WRITEABLE; +} + +void *xenhypfs_read_raw(xenhypfs_handle *fshdl, const char *path, + struct xenhypfs_dirent **dirent) +{ + void *retbuf = NULL, *content = NULL; + char *path_buf = NULL; + const char *name; + struct xen_hypfs_direntry *entry; + int ret; + int sz, path_sz; + + *dirent = NULL; + ret = xenhypfs_get_pathbuf(fshdl, path, &path_buf); + if (ret < 0) + goto out; + + path_sz = ret; + + for (sz = BUF_SIZE;; sz = sizeof(*entry) + entry->content_len) { + if (retbuf) + xencall_free_buffer(fshdl->xcall, retbuf); + + retbuf = xencall_alloc_buffer(fshdl->xcall, sz); + if (!retbuf) { + errno = ENOMEM; + goto out; + } + entry = retbuf; + + ret = xencall5(fshdl->xcall, __HYPERVISOR_hypfs_op, + XEN_HYPFS_OP_read_contents, + (unsigned long)path_buf, path_sz, + (unsigned long)retbuf, sz); + if (ret < 0) { + errno = -ret; + goto out; + } + + if (sz <= sizeof(*entry) + entry->content_len) + break; + } + + content = malloc(entry->content_len); + if (!content) + goto out; + memcpy(content, entry + 1, entry->content_len); + + name = strrchr(path, '/'); + if (!name) + name = path; + else { + name++; + if (!*name) + name--; + } + *dirent = calloc(1, sizeof(struct xenhypfs_dirent) + strlen(name) + 1); + if (!*dirent) { + free(content); + content = NULL; + errno = ENOMEM; + goto out; + } + (*dirent)->name = (char *)(*dirent + 1); + strcpy((*dirent)->name, name); + xenhypfs_set_attrs(entry, *dirent); + + out: + ret = errno; + xencall_free_buffer(fshdl->xcall, path_buf); + xencall_free_buffer(fshdl->xcall, retbuf); + errno = ret; + + return content; +} + +char *xenhypfs_read(xenhypfs_handle *fshdl, const char *path) +{ + char *buf, *ret_buf = NULL; + struct xenhypfs_dirent *dirent; + int ret; + + buf = xenhypfs_read_raw(fshdl, path, &dirent); + if (!buf) + goto out; + + switch (dirent->encoding) { + case xenhypfs_enc_plain: + break; + case xenhypfs_enc_gzip: + ret_buf = xenhypfs_inflate(buf, &dirent->size); + if (!ret_buf) + goto out; + free(buf); + buf = ret_buf; + ret_buf = NULL; + break; + } + + switch (dirent->type) { + case xenhypfs_type_dir: + errno = EISDIR; + break; + case xenhypfs_type_blob: + errno = EDOM; + break; + case xenhypfs_type_string: + ret_buf = buf; + buf = NULL; + break; + case xenhypfs_type_uint: + case xenhypfs_type_bool: + switch (dirent->size) { + case 1: + ret = asprintf(&ret_buf, "%"PRIu8, *(uint8_t *)buf); + break; + case 2: + ret = asprintf(&ret_buf, "%"PRIu16, *(uint16_t *)buf); + break; + case 4: + ret = asprintf(&ret_buf, "%"PRIu32, *(uint32_t *)buf); + break; + case 8: + ret = asprintf(&ret_buf, "%"PRIu64, *(uint64_t *)buf); + break; + default: + ret = -1; + errno = EDOM; + } + if (ret < 0) + ret_buf = NULL; + break; + case xenhypfs_type_int: + switch (dirent->size) { + case 1: + ret = asprintf(&ret_buf, "%"PRId8, *(int8_t *)buf); + break; + case 2: + ret = asprintf(&ret_buf, "%"PRId16, *(int16_t *)buf); + break; + case 4: + ret = asprintf(&ret_buf, "%"PRId32, *(int32_t *)buf); + break; + case 8: + ret = asprintf(&ret_buf, "%"PRId64, *(int64_t *)buf); + break; + default: + ret = -1; + errno = EDOM; + } + if (ret < 0) + ret_buf = NULL; + break; + } + + out: + ret = errno; + free(buf); + free(dirent); + errno = ret; + + return ret_buf; +} + +struct xenhypfs_dirent *xenhypfs_readdir(xenhypfs_handle *fshdl, + const char *path, + unsigned int *num_entries) +{ + void *buf, *curr; + int ret; + char *names; + struct xenhypfs_dirent *ret_buf = NULL, *dirent; + unsigned int n = 0, name_sz = 0; + struct xen_hypfs_dirlistentry *entry; + + buf = xenhypfs_read_raw(fshdl, path, &dirent); + if (!buf) + goto out; + + if (dirent->type != xenhypfs_type_dir || + dirent->encoding != xenhypfs_enc_plain) { + errno = ENOTDIR; + goto out; + } + + if (dirent->size) { + curr = buf; + for (n = 1;; n++) { + entry = curr; + name_sz += strlen(entry->name) + 1; + if (!entry->off_next) + break; + + curr += entry->off_next; + } + } + + ret_buf = malloc(n * sizeof(*ret_buf) + name_sz); + if (!ret_buf) + goto out; + + *num_entries = n; + names = (char *)(ret_buf + n); + curr = buf; + for (n = 0; n < *num_entries; n++) { + entry = curr; + xenhypfs_set_attrs(&entry->e, ret_buf + n); + ret_buf[n].name = names; + strcpy(names, entry->name); + names += strlen(entry->name) + 1; + curr += entry->off_next; + } + + out: + ret = errno; + free(buf); + free(dirent); + errno = ret; + + return ret_buf; +} + +int xenhypfs_write(xenhypfs_handle *fshdl, const char *path, const char *val) +{ + void *buf = NULL; + char *path_buf = NULL, *val_end; + int ret, saved_errno; + int sz, path_sz; + struct xen_hypfs_direntry *entry; + uint64_t mask; + + ret = xenhypfs_get_pathbuf(fshdl, path, &path_buf); + if (ret < 0) + goto out; + + path_sz = ret; + ret = -1; + + sz = BUF_SIZE; + buf = xencall_alloc_buffer(fshdl->xcall, sz); + if (!buf) { + errno = ENOMEM; + goto out; + } + + ret = xencall5(fshdl->xcall, __HYPERVISOR_hypfs_op, + XEN_HYPFS_OP_read_contents, + (unsigned long)path_buf, path_sz, + (unsigned long)buf, sizeof(*entry)); + if (ret) + goto out; + ret = -1; + entry = buf; + if (!(entry->flags & XEN_HYPFS_WRITEABLE)) { + errno = EACCES; + goto out; + } + if (entry->encoding != XEN_HYPFS_ENC_PLAIN) { + /* Writing compressed data currently not supported. */ + errno = EDOM; + goto out; + } + + switch (entry->type) { + case XEN_HYPFS_TYPE_STRING: + if (sz < strlen(val) + 1) { + sz = strlen(val) + 1; + xencall_free_buffer(fshdl->xcall, buf); + buf = xencall_alloc_buffer(fshdl->xcall, sz); + if (!buf) { + errno = ENOMEM; + goto out; + } + } + strcpy(buf, val); + break; + case XEN_HYPFS_TYPE_UINT: + sz = entry->content_len; + errno = 0; + *(unsigned long long *)buf = strtoull(val, &val_end, 0); + if (errno || !*val || *val_end) + goto out; + mask = ~0ULL << (8 * sz); + if ((*(uint64_t *)buf & mask) && ((*(uint64_t *)buf & mask) != mask)) { + errno = ERANGE; + goto out; + } + break; + case XEN_HYPFS_TYPE_INT: + sz = entry->content_len; + errno = 0; + *(unsigned long long *)buf = strtoll(val, &val_end, 0); + if (errno || !*val || *val_end) + goto out; + mask = (sz == 8) ? 0 : ~0ULL << (8 * sz); + if ((*(uint64_t *)buf & mask) && ((*(uint64_t *)buf & mask) != mask)) { + errno = ERANGE; + goto out; + } + break; + case XEN_HYPFS_TYPE_BOOL: + *(unsigned long long *)buf = 0; + if (!strcmp(val, "1") || !strcmp(val, "on") || !strcmp(val, "yes") || + !strcmp(val, "true") || !strcmp(val, "enable")) + *(unsigned long long *)buf = 1; + else if (strcmp(val, "0") && strcmp(val, "no") && strcmp(val, "off") && + strcmp(val, "false") && strcmp(val, "disable")) { + errno = EDOM; + goto out; + } + break; + default: + /* No support for other types (yet). */ + errno = EDOM; + goto out; + } + + ret = xencall5(fshdl->xcall, __HYPERVISOR_hypfs_op, + XEN_HYPFS_OP_write_contents, + (unsigned long)path_buf, path_sz, + (unsigned long)buf, sz); + + out: + saved_errno = errno; + xencall_free_buffer(fshdl->xcall, path_buf); + xencall_free_buffer(fshdl->xcall, buf); + errno = saved_errno; + return ret; +} diff --git a/tools/libs/hypfs/include/xenhypfs.h b/tools/libs/hypfs/include/xenhypfs.h new file mode 100644 index 0000000000..29c69712ce --- /dev/null +++ b/tools/libs/hypfs/include/xenhypfs.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2019 SUSE Software Solutions Germany GmbH + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; If not, see . + */ +#ifndef XENHYPFS_H +#define XENHYPFS_H + +#include +#include +#include + +/* Callers who don't care don't need to #include */ +struct xentoollog_logger; + +typedef struct xenhypfs_handle xenhypfs_handle; + +struct xenhypfs_dirent { + char *name; + size_t size; + enum { + xenhypfs_type_dir, + xenhypfs_type_blob, + xenhypfs_type_string, + xenhypfs_type_uint, + xenhypfs_type_int, + xenhypfs_type_bool + } type; + enum { + xenhypfs_enc_plain, + xenhypfs_enc_gzip + } encoding; + bool is_writable; +}; + +xenhypfs_handle *xenhypfs_open(struct xentoollog_logger *logger, + unsigned int open_flags); +int xenhypfs_close(xenhypfs_handle *fshdl); + +/* Returned buffer and dirent should be freed via free(). */ +void *xenhypfs_read_raw(xenhypfs_handle *fshdl, const char *path, + struct xenhypfs_dirent **dirent); + +/* Returned buffer should be freed via free(). */ +char *xenhypfs_read(xenhypfs_handle *fshdl, const char *path); + +/* Returned buffer should be freed via free(). */ +struct xenhypfs_dirent *xenhypfs_readdir(xenhypfs_handle *fshdl, + const char *path, + unsigned int *num_entries); + +int xenhypfs_write(xenhypfs_handle *fshdl, const char *path, const char *val); + +#endif /* XENHYPFS_H */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libs/hypfs/libxenhypfs.map b/tools/libs/hypfs/libxenhypfs.map new file mode 100644 index 0000000000..47f1edda3e --- /dev/null +++ b/tools/libs/hypfs/libxenhypfs.map @@ -0,0 +1,10 @@ +VERS_1.0 { + global: + xenhypfs_open; + xenhypfs_close; + xenhypfs_read_raw; + xenhypfs_read; + xenhypfs_readdir; + xenhypfs_write; + local: *; /* Do not expose anything by default */ +}; diff --git a/tools/libs/hypfs/xenhypfs.pc.in b/tools/libs/hypfs/xenhypfs.pc.in new file mode 100644 index 0000000000..9cb968f0db --- /dev/null +++ b/tools/libs/hypfs/xenhypfs.pc.in @@ -0,0 +1,10 @@ +prefix=@@prefix@@ +includedir=@@incdir@@ +libdir=@@libdir@@ + +Name: Xenhypfs +Description: The Xenhypfs library for Xen hypervisor +Version: @@version@@ +Cflags: -I${includedir} @@cflagslocal@@ +Libs: @@libsflag@@${libdir} -lxenhypfs +Requires.private: xentoolcore,xentoollog,xencall From patchwork Tue Jan 21 08:43:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?SsO8cmdlbiBHcm/Dnw==?= X-Patchwork-Id: 11343189 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 62A7D17EA for ; Tue, 21 Jan 2020 08:45:25 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 48FD722522 for ; Tue, 21 Jan 2020 08:45:25 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 48FD722522 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=suse.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1itp8e-0004Y1-5x; Tue, 21 Jan 2020 08:43:56 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1itp8c-0004X9-Lk for xen-devel@lists.xenproject.org; Tue, 21 Jan 2020 08:43:54 +0000 X-Inumbo-ID: 1ed0a51e-3c2a-11ea-8e9a-bc764e2007e4 Received: from mx2.suse.de (unknown [195.135.220.15]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 1ed0a51e-3c2a-11ea-8e9a-bc764e2007e4; Tue, 21 Jan 2020 08:43:39 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id C3B3CB2C8; Tue, 21 Jan 2020 08:43:34 +0000 (UTC) From: Juergen Gross To: xen-devel@lists.xenproject.org Date: Tue, 21 Jan 2020 09:43:27 +0100 Message-Id: <20200121084330.18309-7-jgross@suse.com> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20200121084330.18309-1-jgross@suse.com> References: <20200121084330.18309-1-jgross@suse.com> Subject: [Xen-devel] [PATCH v3 6/9] tools: add xenfs tool X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Juergen Gross , Stefano Stabellini , Julien Grall , Wei Liu , Konrad Rzeszutek Wilk , George Dunlap , Andrew Cooper , Ian Jackson , Jan Beulich MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Add the xenfs tool for accessing the hypervisor filesystem. Signed-off-by: Juergen Gross Acked-by: Wei Liu --- V1: - rename to xenhypfs - don't use "--" for subcommands - add write support V2: - escape non-printable characters per default with cat subcommand (Ian Jackson) - add -b option to cat subcommand (Ian Jackson) - add man page V3: - adapt to new hypfs interface --- .gitignore | 1 + docs/man/xenhypfs.1.pod | 61 ++++++++++++++++ tools/misc/Makefile | 6 ++ tools/misc/xenhypfs.c | 189 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 257 insertions(+) create mode 100644 docs/man/xenhypfs.1.pod create mode 100644 tools/misc/xenhypfs.c diff --git a/.gitignore b/.gitignore index e98c3f056d..fd5610718d 100644 --- a/.gitignore +++ b/.gitignore @@ -367,6 +367,7 @@ tools/libxl/test_timedereg tools/libxl/test_fdderegrace tools/firmware/etherboot/eb-roms.h tools/firmware/etherboot/gpxe-git-snapshot.tar.gz +tools/misc/xenhypfs tools/misc/xenwatchdogd tools/misc/xen-hvmcrash tools/misc/xen-lowmemd diff --git a/docs/man/xenhypfs.1.pod b/docs/man/xenhypfs.1.pod new file mode 100644 index 0000000000..37aa488fcc --- /dev/null +++ b/docs/man/xenhypfs.1.pod @@ -0,0 +1,61 @@ +=head1 NAME + +xenhypfs - Xen tool to access Xen hypervisor file system + +=head1 SYNOPSIS + +B I [I] [I] + +=head1 DESCRIPTION + +The B program is used to access the Xen hypervisor file system. +It can be used to show the available entries, to show their contents and +(if allowed) to modify their contents. + +=head1 SUBCOMMANDS + +=over 4 + +=item B I + +List the available entries below I. + +=item B [I<-b>] I + +Show the contents of the entry specified by I. Non-printable characters +other than white space characters (like tab, new line) will be shown as +B<\xnn> (B being a two digit hex number) unless the option B<-b> is +specified. + +=item B I I + +Set the contents of the entry specified by I to I. + +=item B + +Show all the entries of the file system as a tree. + +=back + +=head1 RETURN CODES + +=over 4 + +=item B<0> + +Success + +=item B<1> + +Invalid usage (e.g. unknown subcommand, unknown option, missing parameter). + +=item B<2> + +Entry not found while traversing the tree. + +=item B<3> + +Access right violation. + +=back + diff --git a/tools/misc/Makefile b/tools/misc/Makefile index 63947bfadc..9fdb13597f 100644 --- a/tools/misc/Makefile +++ b/tools/misc/Makefile @@ -24,6 +24,7 @@ INSTALL_SBIN-$(CONFIG_X86) += xen-lowmemd INSTALL_SBIN-$(CONFIG_X86) += xen-mfndump INSTALL_SBIN-$(CONFIG_X86) += xen-ucode INSTALL_SBIN += xencov +INSTALL_SBIN += xenhypfs INSTALL_SBIN += xenlockprof INSTALL_SBIN += xenperf INSTALL_SBIN += xenpm @@ -86,6 +87,9 @@ xenperf: xenperf.o xenpm: xenpm.o $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(APPEND_LDFLAGS) +xenhypfs: xenhypfs.o + $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenhypfs) $(APPEND_LDFLAGS) + xenlockprof: xenlockprof.o $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(APPEND_LDFLAGS) @@ -94,6 +98,8 @@ xen-hptool.o: CFLAGS += -I$(XEN_ROOT)/tools/libxc $(CFLAGS_libxencall) xen-hptool: xen-hptool.o $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenevtchn) $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore) $(APPEND_LDFLAGS) +xenhypfs.o: CFLAGS += $(CFLAGS_libxenhypfs) + # xen-mfndump incorrectly uses libxc internals xen-mfndump.o: CFLAGS += -I$(XEN_ROOT)/tools/libxc $(CFLAGS_libxencall) xen-mfndump: xen-mfndump.o diff --git a/tools/misc/xenhypfs.c b/tools/misc/xenhypfs.c new file mode 100644 index 0000000000..0b834bf4fa --- /dev/null +++ b/tools/misc/xenhypfs.c @@ -0,0 +1,189 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include + +static struct xenhypfs_handle *hdl; + +static int usage(void) +{ + fprintf(stderr, "usage: xenhypfs ls \n"); + fprintf(stderr, " xenhypfs cat [-b] \n"); + fprintf(stderr, " xenhypfs write \n"); + fprintf(stderr, " xenhypfs tree\n"); + + return 1; +} + +static void xenhypfs_print_escaped(char *string) +{ + char *c; + + for (c = string; *c; c++) { + if (isgraph(*c) || isspace(*c)) + printf("%c", *c); + else + printf("\\x%02x", *c); + } + printf("\n"); +} + +static int xenhypfs_cat(int argc, char *argv[]) +{ + int ret = 0; + char *result; + char *path; + bool bin = false; + + switch (argc) { + case 1: + path = argv[0]; + break; + + case 2: + if (strcmp(argv[0], "-b")) + return usage(); + bin = true; + path = argv[1]; + break; + + default: + return usage(); + } + + result = xenhypfs_read(hdl, path); + if (!result) { + perror("could not read"); + ret = 3; + } else { + if (!bin) + printf("%s\n", result); + else + xenhypfs_print_escaped(result); + free(result); + } + + return ret; +} + +static int xenhypfs_wr(char *path, char *val) +{ + int ret; + + ret = xenhypfs_write(hdl, path, val); + if (ret) { + perror("could not write"); + ret = 3; + } + + return ret; +} + +static char *xenhypfs_type(struct xenhypfs_dirent *ent) +{ + char *res; + + switch (ent->type) { + case xenhypfs_type_dir: + res = " "; + break; + case xenhypfs_type_blob: + res = " "; + break; + case xenhypfs_type_string: + res = ""; + break; + case xenhypfs_type_uint: + res = " "; + break; + case xenhypfs_type_int: + res = " "; + break; + default: + res = "<\?\?\?> "; + break; + } + + return res; +} + +static int xenhypfs_ls(char *path) +{ + struct xenhypfs_dirent *ent; + unsigned int n, i; + int ret = 0; + + ent = xenhypfs_readdir(hdl, path, &n); + if (!ent) { + perror("could not read dir"); + ret = 3; + } else { + for (i = 0; i < n; i++) + printf("%s r%c %s\n", xenhypfs_type(ent + i), + ent[i].is_writable ? 'w' : '-', ent[i].name); + + free(ent); + } + + return ret; +} + +static int xenhypfs_tree_sub(char *path, unsigned int depth) +{ + struct xenhypfs_dirent *ent; + unsigned int n, i; + int ret = 0; + char *p; + + ent = xenhypfs_readdir(hdl, path, &n); + if (!ent) + return 2; + + for (i = 0; i < n; i++) { + printf("%*s%s%s\n", depth * 2, "", ent[i].name, + ent[i].type == xenhypfs_type_dir ? "/" : ""); + if (ent[i].type == xenhypfs_type_dir) { + asprintf(&p, "%s%s%s", path, (depth == 1) ? "" : "/", ent[i].name); + if (xenhypfs_tree_sub(p, depth + 1)) + ret = 2; + } + } + + free(ent); + + return ret; +} + +static int xenhypfs_tree(void) +{ + printf("/\n"); + + return xenhypfs_tree_sub("/", 1); +} + +int main(int argc, char *argv[]) +{ + int ret; + + hdl = xenhypfs_open(NULL, 0); + + if (!hdl) { + fprintf(stderr, "Could not open libxenhypfs\n"); + ret = 2; + } else if (argc >= 3 && !strcmp(argv[1], "cat")) + ret = xenhypfs_cat(argc - 2, argv + 2); + else if (argc == 3 && !strcmp(argv[1], "ls")) + ret = xenhypfs_ls(argv[2]); + else if (argc == 4 && !strcmp(argv[1], "write")) + ret = xenhypfs_wr(argv[2], argv[3]); + else if (argc == 2 && !strcmp(argv[1], "tree")) + ret = xenhypfs_tree(); + else + ret = usage(); + + xenhypfs_close(hdl); + + return ret; +} From patchwork Tue Jan 21 08:43:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?SsO8cmdlbiBHcm/Dnw==?= X-Patchwork-Id: 11343197 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E092F184C for ; Tue, 21 Jan 2020 08:45:30 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C6CAF24654 for ; Tue, 21 Jan 2020 08:45:30 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C6CAF24654 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=suse.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1itp8h-0004aN-Gb; Tue, 21 Jan 2020 08:43:59 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1itp8h-0004a3-5i for xen-devel@lists.xenproject.org; Tue, 21 Jan 2020 08:43:59 +0000 X-Inumbo-ID: 1f295b6f-3c2a-11ea-ba47-12813bfff9fa Received: from mx2.suse.de (unknown [195.135.220.15]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id 1f295b6f-3c2a-11ea-ba47-12813bfff9fa; Tue, 21 Jan 2020 08:43:40 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 0602BB2C9; Tue, 21 Jan 2020 08:43:34 +0000 (UTC) From: Juergen Gross To: xen-devel@lists.xenproject.org Date: Tue, 21 Jan 2020 09:43:28 +0100 Message-Id: <20200121084330.18309-8-jgross@suse.com> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20200121084330.18309-1-jgross@suse.com> References: <20200121084330.18309-1-jgross@suse.com> Subject: [Xen-devel] [PATCH v3 7/9] xen: provide version information in hypfs X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Juergen Gross , Stefano Stabellini , Julien Grall , Wei Liu , Konrad Rzeszutek Wilk , George Dunlap , Andrew Cooper , Ian Jackson , Jan Beulich MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Provide version and compile information in /buildinfo/ node of the Xen hypervisor file system. As this information is accessible by dom0 only no additional security problem arises. Signed-off-by: Juergen Gross Reviewed-by: Jan Beulich --- V3: - new patch --- docs/misc/hypfs-paths.pandoc | 45 ++++++++++++++++++++++++++++++++++++++++++++ xen/common/kernel.c | 45 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/docs/misc/hypfs-paths.pandoc b/docs/misc/hypfs-paths.pandoc index 67de8d2cf8..1f63c5c13e 100644 --- a/docs/misc/hypfs-paths.pandoc +++ b/docs/misc/hypfs-paths.pandoc @@ -93,3 +93,48 @@ A populated Xen hypervisor file system might look like the following example: #### / The root of the hypervisor file system. + +#### /buildinfo/ + +A directory containing static information generated while building the +hypervisor. + +#### /buildinfo/changeset = STRING + +Git commit of the hypervisor. + +#### /buildinfo/compileinfo/ + +A directory containing information about compilation of Xen. + +#### /buildinfo/compileinfo/compile_by = STRING + +Information who compiled the hypervisor. + +#### /buildinfo/compileinfo/compile_date = STRING + +Date of the hypervisor compilation. + +#### /buildinfo/compileinfo/compile_domain = STRING + +Information about the compile domain. + +#### /buildinfo/compileinfo/compiler = STRING + +The compiler used to build Xen. + +#### /buildinfo/version/ + +A directory containing version information of the hypervisor. + +#### /buildinfo/version/extra = STRING + +Extra version information. + +#### /buildinfo/version/major = INTEGER + +The major version of Xen. + +#### /buildinfo/version/minor = INTEGER + +The minor version of Xen. diff --git a/xen/common/kernel.c b/xen/common/kernel.c index 22941cec94..3186fd59c2 100644 --- a/xen/common/kernel.c +++ b/xen/common/kernel.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -373,6 +374,50 @@ void __init do_initcalls(void) (*call)(); } +static unsigned int major_version; +static unsigned int minor_version; + +static HYPFS_DIR_INIT(buildinfo, "buildinfo"); +static HYPFS_DIR_INIT(compileinfo, "compileinfo"); +static HYPFS_DIR_INIT(version, "version"); +static HYPFS_UINT_INIT(major, "major", major_version); +static HYPFS_UINT_INIT(minor, "minor", minor_version); +static HYPFS_STRING_INIT(changeset, "changeset"); +static HYPFS_STRING_INIT(compiler, "compiler"); +static HYPFS_STRING_INIT(compile_by, "compile_by"); +static HYPFS_STRING_INIT(compile_date, "compile_date"); +static HYPFS_STRING_INIT(compile_domain, "compile_domain"); +static HYPFS_STRING_INIT(extra, "extra"); + +static int __init buildinfo_init(void) +{ + hypfs_add_dir(&hypfs_root, &buildinfo, true); + + hypfs_string_set(&changeset, xen_changeset()); + hypfs_add_leaf(&buildinfo, &changeset, true); + + hypfs_add_dir(&buildinfo, &compileinfo, true); + hypfs_string_set(&compiler, xen_compiler()); + hypfs_string_set(&compile_by, xen_compile_by()); + hypfs_string_set(&compile_date, xen_compile_date()); + hypfs_string_set(&compile_domain, xen_compile_domain()); + hypfs_add_leaf(&compileinfo, &compiler, true); + hypfs_add_leaf(&compileinfo, &compile_by, true); + hypfs_add_leaf(&compileinfo, &compile_date, true); + hypfs_add_leaf(&compileinfo, &compile_domain, true); + + major_version = xen_major_version(); + minor_version = xen_minor_version(); + hypfs_add_dir(&buildinfo, &version, true); + hypfs_string_set(&extra, xen_extra_version()); + hypfs_add_leaf(&version, &extra, true); + hypfs_add_leaf(&version, &major, true); + hypfs_add_leaf(&version, &minor, true); + + return 0; +} +__initcall(buildinfo_init); + # define DO(fn) long do_##fn #endif From patchwork Tue Jan 21 08:43:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?SsO8cmdlbiBHcm/Dnw==?= X-Patchwork-Id: 11343193 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AAE8B6C1 for ; Tue, 21 Jan 2020 08:45:27 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 91ACB22522 for ; Tue, 21 Jan 2020 08:45:27 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 91ACB22522 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=suse.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1itp8d-0004Xg-RA; Tue, 21 Jan 2020 08:43:55 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1itp8c-0004Wt-5y for xen-devel@lists.xenproject.org; Tue, 21 Jan 2020 08:43:54 +0000 X-Inumbo-ID: 1f295b70-3c2a-11ea-ba47-12813bfff9fa Received: from mx2.suse.de (unknown [195.135.220.15]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id 1f295b70-3c2a-11ea-ba47-12813bfff9fa; Tue, 21 Jan 2020 08:43:40 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 3B514B2CA; Tue, 21 Jan 2020 08:43:35 +0000 (UTC) From: Juergen Gross To: xen-devel@lists.xenproject.org Date: Tue, 21 Jan 2020 09:43:29 +0100 Message-Id: <20200121084330.18309-9-jgross@suse.com> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20200121084330.18309-1-jgross@suse.com> References: <20200121084330.18309-1-jgross@suse.com> Subject: [Xen-devel] [PATCH v3 8/9] xen: add /buildinfo/config entry to hypervisor filesystem X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Juergen Gross , Stefano Stabellini , Julien Grall , Wei Liu , Konrad Rzeszutek Wilk , George Dunlap , Andrew Cooper , Ian Jackson , Jan Beulich MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Add the /buildinfo/config entry to the hypervisor filesystem. This entry contains the .config file used to build the hypervisor. Signed-off-by: Juergen Gross --- V3: - store data in gzip format - use binfile mechanism to create data file - move code to kernel.c --- .gitignore | 2 ++ docs/misc/hypfs-paths.pandoc | 4 ++++ xen/common/Makefile | 12 ++++++++++++ xen/common/kernel.c | 10 ++++++++++ xen/include/xen/kernel.h | 3 +++ 5 files changed, 31 insertions(+) diff --git a/.gitignore b/.gitignore index fd5610718d..bc8e053ccb 100644 --- a/.gitignore +++ b/.gitignore @@ -297,6 +297,8 @@ xen/arch/*/efi/boot.c xen/arch/*/efi/compat.c xen/arch/*/efi/efi.h xen/arch/*/efi/runtime.c +xen/common/config_data.S +xen/common/config.gz xen/include/headers*.chk xen/include/asm xen/include/asm-*/asm-offsets.h diff --git a/docs/misc/hypfs-paths.pandoc b/docs/misc/hypfs-paths.pandoc index 1f63c5c13e..e8ae52ea45 100644 --- a/docs/misc/hypfs-paths.pandoc +++ b/docs/misc/hypfs-paths.pandoc @@ -123,6 +123,10 @@ Information about the compile domain. The compiler used to build Xen. +#### /buildinfo/config = STRING + +The contents of the `xen/.config` file at the time of the hypervisor build. + #### /buildinfo/version/ A directory containing version information of the hypervisor. diff --git a/xen/common/Makefile b/xen/common/Makefile index a3f66aa0c0..64017dd130 100644 --- a/xen/common/Makefile +++ b/xen/common/Makefile @@ -1,6 +1,7 @@ obj-$(CONFIG_ARGO) += argo.o obj-y += bitmap.o obj-y += bsearch.o +obj-y += config_data.o obj-$(CONFIG_CORE_PARKING) += core_parking.o obj-y += cpu.o obj-y += cpupool.o @@ -79,3 +80,14 @@ subdir-$(CONFIG_UBSAN) += ubsan subdir-$(CONFIG_NEEDS_LIBELF) += libelf subdir-$(CONFIG_HAS_DEVICE_TREE) += libfdt + +config.gz: ../.config + gzip -c $< >$@ + +config_data.o: config.gz + +config_data.S: $(XEN_ROOT)/xen/tools/binfile + $(XEN_ROOT)/xen/tools/binfile $@ config.gz xen_config_data + +clean:: + rm config_data.S config.gz 2>/dev/null || true diff --git a/xen/common/kernel.c b/xen/common/kernel.c index 3186fd59c2..b5ee3011f5 100644 --- a/xen/common/kernel.c +++ b/xen/common/kernel.c @@ -388,6 +388,13 @@ static HYPFS_STRING_INIT(compile_by, "compile_by"); static HYPFS_STRING_INIT(compile_date, "compile_date"); static HYPFS_STRING_INIT(compile_domain, "compile_domain"); static HYPFS_STRING_INIT(extra, "extra"); +static struct hypfs_entry_leaf config = { + .e.type = XEN_HYPFS_TYPE_STRING, + .e.encoding = XEN_HYPFS_ENC_GZIP, + .e.name = "config", + .e.read = hypfs_read_leaf, + .content = &xen_config_data +}; static int __init buildinfo_init(void) { @@ -414,6 +421,9 @@ static int __init buildinfo_init(void) hypfs_add_leaf(&version, &major, true); hypfs_add_leaf(&version, &minor, true); + config.e.size = xen_config_data_size; + hypfs_add_leaf(&buildinfo, &config, true); + return 0; } __initcall(buildinfo_init); diff --git a/xen/include/xen/kernel.h b/xen/include/xen/kernel.h index 548b64da9f..2f883031f9 100644 --- a/xen/include/xen/kernel.h +++ b/xen/include/xen/kernel.h @@ -100,5 +100,8 @@ extern enum system_state { bool_t is_active_kernel_text(unsigned long addr); +extern char xen_config_data; +extern unsigned int xen_config_data_size; + #endif /* _LINUX_KERNEL_H */ From patchwork Tue Jan 21 08:43:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?SsO8cmdlbiBHcm/Dnw==?= X-Patchwork-Id: 11343201 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C6BF817EA for ; Tue, 21 Jan 2020 08:45:42 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A1D1B22522 for ; Tue, 21 Jan 2020 08:45:42 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A1D1B22522 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=suse.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1itp8s-0004iS-C7; Tue, 21 Jan 2020 08:44:10 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1itp8r-0004h7-62 for xen-devel@lists.xenproject.org; Tue, 21 Jan 2020 08:44:09 +0000 X-Inumbo-ID: 1f750802-3c2a-11ea-ba47-12813bfff9fa Received: from mx2.suse.de (unknown [195.135.220.15]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id 1f750802-3c2a-11ea-ba47-12813bfff9fa; Tue, 21 Jan 2020 08:43:40 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 9D128B2CB; Tue, 21 Jan 2020 08:43:35 +0000 (UTC) From: Juergen Gross To: xen-devel@lists.xenproject.org Date: Tue, 21 Jan 2020 09:43:30 +0100 Message-Id: <20200121084330.18309-10-jgross@suse.com> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20200121084330.18309-1-jgross@suse.com> References: <20200121084330.18309-1-jgross@suse.com> Subject: [Xen-devel] [PATCH v3 9/9] xen: add runtime parameter access support to hypfs X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Juergen Gross , Kevin Tian , Stefano Stabellini , Julien Grall , Jun Nakajima , Wei Liu , Konrad Rzeszutek Wilk , George Dunlap , Andrew Cooper , Ian Jackson , Jan Beulich , Volodymyr Babchuk , =?utf-8?q?Roger_Pau_Monn?= =?utf-8?q?=C3=A9?= MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Add support to read and modify values of hypervisor runtime parameters via the hypervisor file system. As runtime parameters can be modified via a sysctl, too, this path has to take the hypfs rw_lock as writer. For custom runtime parameters the resulting parameter value needs to be stored in a string buffer for being consumable by the file system. Signed-off-by: Juergen Gross --- V3: - complete rework - support custom parameters, too - support parameter writing --- docs/misc/hypfs-paths.pandoc | 9 ++++++ xen/arch/arm/xen.lds.S | 5 +++ xen/arch/x86/hvm/vmx/vmcs.c | 17 +++++++++- xen/arch/x86/pv/domain.c | 7 ++++- xen/arch/x86/xen.lds.S | 5 +++ xen/common/grant_table.c | 17 +++++++--- xen/common/hypfs.c | 38 +++++++++++++++++++++++ xen/common/kernel.c | 23 +++++++++++++- xen/drivers/char/console.c | 49 +++++++++++++++++++++++++---- xen/include/xen/hypfs.h | 4 +++ xen/include/xen/param.h | 74 +++++++++++++++++++++++++++++++++++++++----- 11 files changed, 226 insertions(+), 22 deletions(-) diff --git a/docs/misc/hypfs-paths.pandoc b/docs/misc/hypfs-paths.pandoc index e8ae52ea45..1554039e46 100644 --- a/docs/misc/hypfs-paths.pandoc +++ b/docs/misc/hypfs-paths.pandoc @@ -142,3 +142,12 @@ The major version of Xen. #### /buildinfo/version/minor = INTEGER The minor version of Xen. + +#### /params/ + +A directory of runtime parameters. + +#### /params/* + +The single parameters. The description of the different parameters can be +found in `docs/misc/xen-command-line.pandoc`. diff --git a/xen/arch/arm/xen.lds.S b/xen/arch/arm/xen.lds.S index a497f6a48d..0061a8dfea 100644 --- a/xen/arch/arm/xen.lds.S +++ b/xen/arch/arm/xen.lds.S @@ -89,6 +89,11 @@ SECTIONS __start_schedulers_array = .; *(.data.schedulers) __end_schedulers_array = .; + + . = ALIGN(8); + __paramhypfs_start = .; + *(.data.paramhypfs) + __paramhypfs_end = .; *(.data.rel) *(.data.rel.*) CONSTRUCTORS diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c index 65445afeb0..36ddccfb73 100644 --- a/xen/arch/x86/hvm/vmx/vmcs.c +++ b/xen/arch/x86/hvm/vmx/vmcs.c @@ -70,6 +70,17 @@ integer_param("ple_window", ple_window); static bool __read_mostly opt_ept_pml = true; static s8 __read_mostly opt_ept_ad = -1; int8_t __read_mostly opt_ept_exec_sp = -1; +static char opt_ept_setting[16] = "pml=1"; + + +static void update_ept_param(void) +{ + snprintf(opt_ept_setting, sizeof(opt_ept_setting), "pml=%d", opt_ept_pml); + if ( opt_ept_ad >= 0 ) + param_append_str(opt_ept_setting, ",ad=%d", opt_ept_ad); + if ( opt_ept_exec_sp >= 0 ) + param_append_str(opt_ept_setting, ",exec-sp=%d", opt_ept_exec_sp); +} static int __init parse_ept_param(const char *s) { @@ -93,6 +104,8 @@ static int __init parse_ept_param(const char *s) s = ss + 1; } while ( *ss ); + update_ept_param(); + return rc; } custom_param("ept", parse_ept_param); @@ -115,6 +128,8 @@ static int parse_ept_param_runtime(const char *s) opt_ept_exec_sp = val; + update_ept_param(); + rcu_read_lock(&domlist_read_lock); for_each_domain ( d ) { @@ -144,7 +159,7 @@ static int parse_ept_param_runtime(const char *s) return 0; } -custom_runtime_only_param("ept", parse_ept_param_runtime); +custom_runtime_only_param("ept", parse_ept_param_runtime, opt_ept_setting); /* Dynamic (run-time adjusted) execution control flags. */ u32 vmx_pin_based_exec_control __read_mostly; diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c index c3473b9a47..9e0d24ce81 100644 --- a/xen/arch/x86/pv/domain.c +++ b/xen/arch/x86/pv/domain.c @@ -22,6 +22,7 @@ static __read_mostly enum { PCID_XPTI, PCID_NOXPTI } opt_pcid = PCID_XPTI; +static char opt_pcid_val[7] = "xpti"; static int parse_pcid(const char *s) { @@ -31,10 +32,12 @@ static int parse_pcid(const char *s) { case 0: opt_pcid = PCID_OFF; + snprintf(opt_pcid_val, sizeof(opt_pcid_val), "off"); break; case 1: opt_pcid = PCID_ALL; + snprintf(opt_pcid_val, sizeof(opt_pcid_val), "on"); break; default: @@ -42,10 +45,12 @@ static int parse_pcid(const char *s) { case 0: opt_pcid = PCID_NOXPTI; + snprintf(opt_pcid_val, sizeof(opt_pcid_val), "noxpti"); break; case 1: opt_pcid = PCID_XPTI; + snprintf(opt_pcid_val, sizeof(opt_pcid_val), "xpti"); break; default: @@ -57,7 +62,7 @@ static int parse_pcid(const char *s) return rc; } -custom_runtime_param("pcid", parse_pcid); +custom_runtime_param("pcid", parse_pcid, opt_pcid_val); static void noreturn continue_nonidle_domain(struct vcpu *v) { diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S index 29ef507432..9b717602db 100644 --- a/xen/arch/x86/xen.lds.S +++ b/xen/arch/x86/xen.lds.S @@ -280,6 +280,11 @@ SECTIONS __start_schedulers_array = .; *(.data.schedulers) __end_schedulers_array = .; + + . = ALIGN(8); + __paramhypfs_start = .; + *(.data.paramhypfs) + __paramhypfs_end = .; } :text DECL_SECTION(.data) { diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index 2ecf38dfbe..2de2c7e373 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -85,8 +85,10 @@ struct grant_table { struct grant_table_arch arch; }; +#define PAR_VAL_SZ 12 + static int parse_gnttab_limit(const char *param, const char *arg, - unsigned int *valp) + unsigned int *valp, char *par_val) { const char *e; unsigned long val; @@ -99,28 +101,33 @@ static int parse_gnttab_limit(const char *param, const char *arg, return -ERANGE; *valp = val; + snprintf(par_val, PAR_VAL_SZ, "%lu", val); return 0; } unsigned int __read_mostly opt_max_grant_frames = 64; +static char gnttab_max_frames_val[PAR_VAL_SZ] = "64"; static int parse_gnttab_max_frames(const char *arg) { return parse_gnttab_limit("gnttab_max_frames", arg, - &opt_max_grant_frames); + &opt_max_grant_frames, gnttab_max_frames_val); } -custom_runtime_param("gnttab_max_frames", parse_gnttab_max_frames); +custom_runtime_param("gnttab_max_frames", parse_gnttab_max_frames, + gnttab_max_frames_val); static unsigned int __read_mostly opt_max_maptrack_frames = 1024; +static char max_maptrack_frames_val[PAR_VAL_SZ] = "1024"; static int parse_gnttab_max_maptrack_frames(const char *arg) { return parse_gnttab_limit("gnttab_max_maptrack_frames", arg, - &opt_max_maptrack_frames); + &opt_max_maptrack_frames, + max_maptrack_frames_val); } custom_runtime_param("gnttab_max_maptrack_frames", - parse_gnttab_max_maptrack_frames); + parse_gnttab_max_maptrack_frames, max_maptrack_frames_val); #ifndef GNTTAB_MAX_VERSION #define GNTTAB_MAX_VERSION 2 diff --git a/xen/common/hypfs.c b/xen/common/hypfs.c index 6762d20dfd..667636d63e 100644 --- a/xen/common/hypfs.c +++ b/xen/common/hypfs.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -296,6 +297,33 @@ int hypfs_write_bool(struct hypfs_entry_leaf *leaf, return 0; } +int hypfs_write_custom(struct hypfs_entry_leaf *leaf, + XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned long ulen) +{ + struct param_hypfs *p; + char *buf; + int ret; + + buf = xzalloc_array(char, ulen); + if ( !buf ) + return -ENOMEM; + + ret = -EFAULT; + if ( copy_from_guest(buf, uaddr, ulen) ) + goto out; + + ret = -EDOM; + if ( buf[ulen - 1] ) + goto out; + + p = container_of(leaf, struct param_hypfs, hypfs); + ret = p->param->par.func(buf); + + out: + xfree(buf); + return ret; +} + static int hypfs_write(struct hypfs_entry *entry, XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned long ulen) { @@ -363,3 +391,13 @@ long do_hypfs_op(unsigned int cmd, return ret; } + +void hypfs_write_lock(void) +{ + write_lock(&hypfs_lock); +} + +void hypfs_write_unlock(void) +{ + write_unlock(&hypfs_lock); +} diff --git a/xen/common/kernel.c b/xen/common/kernel.c index b5ee3011f5..e9a501e0e1 100644 --- a/xen/common/kernel.c +++ b/xen/common/kernel.c @@ -198,7 +198,13 @@ static void __init _cmdline_parse(const char *cmdline) int runtime_parse(const char *line) { - return parse_params(line, __param_start, __param_end); + int ret; + + hypfs_write_lock(); + ret = parse_params(line, __param_start, __param_end); + hypfs_write_unlock(); + + return ret; } /** @@ -428,6 +434,21 @@ static int __init buildinfo_init(void) } __initcall(buildinfo_init); +static HYPFS_DIR_INIT(params, "params"); + +static int __init param_init(void) +{ + struct param_hypfs *param; + + hypfs_add_dir(&hypfs_root, ¶ms, true); + + for ( param = __paramhypfs_start; param < __paramhypfs_end; param++ ) + hypfs_add_leaf(¶ms, ¶m->hypfs, true); + + return 0; +} +__initcall(param_init); + # define DO(fn) long do_##fn #endif diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c index 913ae1b66a..5440145549 100644 --- a/xen/drivers/char/console.c +++ b/xen/drivers/char/console.c @@ -78,9 +78,11 @@ enum con_timestamp_mode }; static enum con_timestamp_mode __read_mostly opt_con_timestamp_mode = TSM_NONE; +static char con_timestamp_mode_val[7] = "none"; static int parse_console_timestamps(const char *s); -custom_runtime_param("console_timestamps", parse_console_timestamps); +custom_runtime_param("console_timestamps", parse_console_timestamps, + con_timestamp_mode_val); /* conring_size: allows a large console ring than default (16kB). */ static uint32_t __initdata opt_conring_size; @@ -118,13 +120,17 @@ static DEFINE_SPINLOCK(console_lock); #ifdef NDEBUG #define XENLOG_UPPER_THRESHOLD 2 /* Do not print INFO and DEBUG */ #define XENLOG_LOWER_THRESHOLD 2 /* Always print ERR and WARNING */ +#define XENLOG_DEFAULT_VAL "warning/warning" #define XENLOG_GUEST_UPPER_THRESHOLD 2 /* Do not print INFO and DEBUG */ #define XENLOG_GUEST_LOWER_THRESHOLD 0 /* Rate-limit ERR and WARNING */ +#define XENLOG_GUEST_DEFAULT_VAL "none/warning" #else #define XENLOG_UPPER_THRESHOLD 4 /* Do not discard anything */ #define XENLOG_LOWER_THRESHOLD 4 /* Print everything */ +#define XENLOG_DEFAULT_VAL "all/all" #define XENLOG_GUEST_UPPER_THRESHOLD 4 /* Do not discard anything */ #define XENLOG_GUEST_LOWER_THRESHOLD 4 /* Print everything */ +#define XENLOG_GUEST_DEFAULT_VAL "all/all" #endif /* * The XENLOG_DEFAULT is the default given to printks that @@ -133,16 +139,20 @@ static DEFINE_SPINLOCK(console_lock); #define XENLOG_DEFAULT 1 /* XENLOG_WARNING */ #define XENLOG_GUEST_DEFAULT 1 /* XENLOG_WARNING */ +#define LOGLVL_VAL_SZ 16 static int __read_mostly xenlog_upper_thresh = XENLOG_UPPER_THRESHOLD; static int __read_mostly xenlog_lower_thresh = XENLOG_LOWER_THRESHOLD; +static char xenlog_val[LOGLVL_VAL_SZ] = XENLOG_DEFAULT_VAL; static int __read_mostly xenlog_guest_upper_thresh = XENLOG_GUEST_UPPER_THRESHOLD; static int __read_mostly xenlog_guest_lower_thresh = XENLOG_GUEST_LOWER_THRESHOLD; +static char xenlog_guest_val[LOGLVL_VAL_SZ] = XENLOG_GUEST_DEFAULT_VAL; static int parse_loglvl(const char *s); static int parse_guest_loglvl(const char *s); +static char *lvl2opt[] = { "none", "error", "warning", "info", "all" }; /* * := none|error|warning|info|debug|all * loglvl=[/] @@ -151,8 +161,8 @@ static int parse_guest_loglvl(const char *s); * Similar definitions for guest_loglvl, but applies to guest tracing. * Defaults: loglvl=warning ; guest_loglvl=none/warning */ -custom_runtime_param("loglvl", parse_loglvl); -custom_runtime_param("guest_loglvl", parse_guest_loglvl); +custom_runtime_param("loglvl", parse_loglvl, xenlog_val); +custom_runtime_param("guest_loglvl", parse_guest_loglvl, xenlog_guest_val); static atomic_t print_everything = ATOMIC_INIT(0); @@ -173,7 +183,7 @@ static int __parse_loglvl(const char *s, const char **ps) return 2; /* sane fallback */ } -static int _parse_loglvl(const char *s, int *lower, int *upper) +static int _parse_loglvl(const char *s, int *lower, int *upper, char *val) { *lower = *upper = __parse_loglvl(s, &s); if ( *s == '/' ) @@ -181,18 +191,21 @@ static int _parse_loglvl(const char *s, int *lower, int *upper) if ( *upper < *lower ) *upper = *lower; + snprintf(val, LOGLVL_VAL_SZ, "%s/%s", lvl2opt[*lower], lvl2opt[*upper]); + return *s ? -EINVAL : 0; } static int parse_loglvl(const char *s) { - return _parse_loglvl(s, &xenlog_lower_thresh, &xenlog_upper_thresh); + return _parse_loglvl(s, &xenlog_lower_thresh, &xenlog_upper_thresh, + xenlog_val); } static int parse_guest_loglvl(const char *s) { return _parse_loglvl(s, &xenlog_guest_lower_thresh, - &xenlog_guest_upper_thresh); + &xenlog_guest_upper_thresh, xenlog_guest_val); } static char *loglvl_str(int lvl) @@ -731,22 +744,46 @@ static int parse_console_timestamps(const char *s) { case 0: opt_con_timestamp_mode = TSM_NONE; + snprintf(con_timestamp_mode_val, sizeof(con_timestamp_mode_val), + "none"); return 0; case 1: opt_con_timestamp_mode = TSM_DATE; + snprintf(con_timestamp_mode_val, sizeof(con_timestamp_mode_val), + "date"); return 0; } if ( *s == '\0' || /* Compat for old booleanparam() */ !strcmp(s, "date") ) + { opt_con_timestamp_mode = TSM_DATE; + snprintf(con_timestamp_mode_val, sizeof(con_timestamp_mode_val), + "date"); + } else if ( !strcmp(s, "datems") ) + { opt_con_timestamp_mode = TSM_DATE_MS; + snprintf(con_timestamp_mode_val, sizeof(con_timestamp_mode_val), + "datems"); + } else if ( !strcmp(s, "boot") ) + { opt_con_timestamp_mode = TSM_BOOT; + snprintf(con_timestamp_mode_val, sizeof(con_timestamp_mode_val), + "boot"); + } else if ( !strcmp(s, "raw") ) + { opt_con_timestamp_mode = TSM_RAW; + snprintf(con_timestamp_mode_val, sizeof(con_timestamp_mode_val), + "raw"); + } else if ( !strcmp(s, "none") ) + { opt_con_timestamp_mode = TSM_NONE; + snprintf(con_timestamp_mode_val, sizeof(con_timestamp_mode_val), + "none"); + } else return -EINVAL; diff --git a/xen/include/xen/hypfs.h b/xen/include/xen/hypfs.h index a1c2140398..d1ea095dc1 100644 --- a/xen/include/xen/hypfs.h +++ b/xen/include/xen/hypfs.h @@ -85,5 +85,9 @@ int hypfs_write_leaf(struct hypfs_entry_leaf *leaf, XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned long ulen); int hypfs_write_bool(struct hypfs_entry_leaf *leaf, XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned long ulen); +int hypfs_write_custom(struct hypfs_entry_leaf *leaf, + XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned long ulen); +void hypfs_write_lock(void); +void hypfs_write_unlock(void); #endif /* __XEN_HYPFS_H__ */ diff --git a/xen/include/xen/param.h b/xen/include/xen/param.h index 75471eb4ad..b4ef3e7a22 100644 --- a/xen/include/xen/param.h +++ b/xen/include/xen/param.h @@ -1,6 +1,7 @@ #ifndef _XEN_PARAM_H #define _XEN_PARAM_H +#include #include /* @@ -23,10 +24,17 @@ struct kernel_param { } par; }; +struct param_hypfs { + const struct kernel_param *param; + struct hypfs_entry_leaf hypfs; +}; + extern const struct kernel_param __setup_start[], __setup_end[]; extern const struct kernel_param __param_start[], __param_end[]; +extern struct param_hypfs __paramhypfs_start[], __paramhypfs_end[]; #define __dataparam __used_section(".data.param") +#define __paramhypfs __used_section(".data.paramhypfs") #define __param(att) static const att \ __attribute__((__aligned__(sizeof(void *)))) struct kernel_param @@ -76,40 +84,87 @@ extern const struct kernel_param __param_start[], __param_end[]; .type = OPT_IGNORE } #define __rtparam __param(__dataparam) +#define __paramfs static __paramhypfs \ + __attribute__((__aligned__(sizeof(void *)))) struct param_hypfs -#define custom_runtime_only_param(_name, _var) \ +#define custom_runtime_only_param(_name, _var, contvar) \ __rtparam __rtpar_##_var = \ { .name = _name, \ .type = OPT_CUSTOM, \ - .par.func = _var } + .par.func = _var }; \ + __paramfs __parfs_##_var = \ + { .param = &__rtpar_##_var, \ + .hypfs.e.type = XEN_HYPFS_TYPE_STRING, \ + .hypfs.e.encoding = XEN_HYPFS_ENC_PLAIN, \ + .hypfs.e.name = _name, \ + .hypfs.e.size = sizeof(contvar), \ + .hypfs.e.read = hypfs_read_leaf, \ + .hypfs.e.write = hypfs_write_custom, \ + .hypfs.content = &contvar } #define boolean_runtime_only_param(_name, _var) \ __rtparam __rtpar_##_var = \ { .name = _name, \ .type = OPT_BOOL, \ .len = sizeof(_var), \ - .par.var = &_var } + .par.var = &_var }; \ + __paramfs __parfs_##_var = \ + { .param = &__rtpar_##_var, \ + .hypfs.e.type = XEN_HYPFS_TYPE_UINT, \ + .hypfs.e.encoding = XEN_HYPFS_ENC_PLAIN, \ + .hypfs.e.name = _name, \ + .hypfs.e.size = sizeof(_var), \ + .hypfs.e.read = hypfs_read_leaf, \ + .hypfs.e.write = hypfs_write_bool, \ + .hypfs.content = &_var } #define integer_runtime_only_param(_name, _var) \ __rtparam __rtpar_##_var = \ { .name = _name, \ .type = OPT_UINT, \ .len = sizeof(_var), \ - .par.var = &_var } + .par.var = &_var }; \ + __paramfs __parfs_##_var = \ + { .param = &__rtpar_##_var, \ + .hypfs.e.type = XEN_HYPFS_TYPE_UINT, \ + .hypfs.e.encoding = XEN_HYPFS_ENC_PLAIN, \ + .hypfs.e.name = _name, \ + .hypfs.e.size = sizeof(_var), \ + .hypfs.e.read = hypfs_read_leaf, \ + .hypfs.e.write = hypfs_write_leaf, \ + .hypfs.content = &_var } #define size_runtime_only_param(_name, _var) \ __rtparam __rtpar_##_var = \ { .name = _name, \ .type = OPT_SIZE, \ .len = sizeof(_var), \ - .par.var = &_var } + .par.var = &_var }; \ + __paramfs __parfs_##_var = \ + { .param = &__rtpar_##_var, \ + .hypfs.e.type = XEN_HYPFS_TYPE_UINT, \ + .hypfs.e.encoding = XEN_HYPFS_ENC_PLAIN, \ + .hypfs.e.name = _name, \ + .hypfs.e.size = sizeof(_var), \ + .hypfs.e.read = hypfs_read_leaf, \ + .hypfs.e.write = hypfs_write_leaf, \ + .hypfs.content = &_var } #define string_runtime_only_param(_name, _var) \ __rtparam __rtpar_##_var = \ { .name = _name, \ .type = OPT_STR, \ .len = sizeof(_var), \ - .par.var = &_var } + .par.var = &_var }; \ + __paramfs __parfs_##_var = \ + { .param = &__rtpar_##_var, \ + .hypfs.e.type = XEN_HYPFS_TYPE_STRING, \ + .hypfs.e.encoding = XEN_HYPFS_ENC_PLAIN, \ + .hypfs.e.name = _name, \ + .hypfs.e.size = sizeof(_var), \ + .hypfs.e.read = hypfs_read_leaf, \ + .hypfs.e.write = hypfs_write_leaf, \ + .hypfs.content = &_var } -#define custom_runtime_param(_name, _var) \ +#define custom_runtime_param(_name, _var, contvar) \ custom_param(_name, _var); \ - custom_runtime_only_param(_name, _var) + custom_runtime_only_param(_name, _var, contvar) #define boolean_runtime_param(_name, _var) \ boolean_param(_name, _var); \ boolean_runtime_only_param(_name, _var) @@ -123,4 +178,7 @@ extern const struct kernel_param __param_start[], __param_end[]; string_param(_name, _var); \ string_runtime_only_param(_name, _var) +#define param_append_str(var, fmt, val) \ + snprintf(var + strlen(var), sizeof(var) - strlen(var), fmt, val) + #endif /* _XEN_PARAM_H */