All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xen-devel] [PATCH v3 0/9] Add hypervisor sysfs-like support
@ 2020-01-21  8:43 Juergen Gross
  2020-01-21  8:43 ` [Xen-devel] [PATCH v3 1/9] xen: add a generic way to include binary files as variables Juergen Gross
                   ` (9 more replies)
  0 siblings, 10 replies; 42+ messages in thread
From: Juergen Gross @ 2020-01-21  8:43 UTC (permalink / raw)
  To: xen-devel
  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, Roger Pau Monné

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.

This is a first implementation of that idea adding the basic
functionality to hypervisor and tools side. The interface to any
user program making use of that "xen-hypfs" is a new library
"libxenhypfs" with a stable interface.

As a followup switching libxl to use the hypervisor file system for
runtime parameter modifications is possible. This would enable
removal of the XEN_SYSCTL_set_parameter sysctl operation.

Changes in V3:
- major rework, especially by supporting binary contents of entries
- added several new patches (1, 2, 7)
- full support of all runtime parameters
- support of writing entries (especially runtime parameters)

Changes in V2:
- all comments to V1 addressed
- added man-page for xenhypfs tool
- added runtime parameter read access for string parameters

Changes in V1:
- renamed xenfs ->xenhypfs
- added writable entries support at the interface level and in the
  xenhypfs tool
- added runtime parameter read access (integer type only for now)
- added docs/misc/hypfs-paths.pandoc for path descriptions

Juergen Gross (9):
  xen: add a generic way to include binary files as variables
  xen: split parameter related definitions in own header file
  docs: add feature document for Xen hypervisor sysfs-like support
  xen: add basic hypervisor filesystem support
  libs: add libxenhypfs
  tools: add xenfs tool
  xen: provide version information in hypfs
  xen: add /buildinfo/config entry to hypervisor filesystem
  xen: add runtime parameter access support to hypfs

 .gitignore                               |   6 +
 docs/features/hypervisorfs.pandoc        |  86 +++++
 docs/man/xenhypfs.1.pod                  |  61 ++++
 docs/misc/hypfs-paths.pandoc             | 153 +++++++++
 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 +
 tools/misc/Makefile                      |   6 +
 tools/misc/xenhypfs.c                    | 189 +++++++++++
 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                     |   2 +
 xen/arch/arm/xen.lds.S                   |   5 +
 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/hypercall.c             |   1 +
 xen/arch/x86/hvm/quirks.c                |   1 +
 xen/arch/x86/hvm/viridian/viridian.c     |   1 +
 xen/arch/x86/hvm/vmx/vmcs.c              |  18 +-
 xen/arch/x86/hvm/vmx/vmx.c               |   1 +
 xen/arch/x86/hypercall.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                 |   8 +-
 xen/arch/x86/pv/hypercall.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/xen.lds.S                   |   5 +
 xen/arch/x86/xstate.c                    |   1 +
 xen/common/Makefile                      |  13 +
 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                 |  18 +-
 xen/common/hypfs.c                       | 403 +++++++++++++++++++++++
 xen/common/kernel.c                      |  79 ++++-
 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               |  50 ++-
 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/public/hypfs.h               | 124 +++++++
 xen/include/public/xen.h                 |   1 +
 xen/include/xen/hypercall.h              |   8 +
 xen/include/xen/hypfs.h                  |  93 ++++++
 xen/include/xen/init.h                   | 120 -------
 xen/include/xen/kernel.h                 |   3 +
 xen/include/xen/param.h                  | 184 +++++++++++
 xen/tools/binfile                        |  29 ++
 xen/xsm/flask/Makefile                   |   5 +-
 xen/xsm/flask/flask-policy.S             |  16 -
 xen/xsm/flask/flask_op.c                 |   1 +
 xen/xsm/xsm_core.c                       |   1 +
 120 files changed, 2274 insertions(+), 151 deletions(-)
 create mode 100644 docs/features/hypervisorfs.pandoc
 create mode 100644 docs/man/xenhypfs.1.pod
 create mode 100644 docs/misc/hypfs-paths.pandoc
 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
 create mode 100644 tools/misc/xenhypfs.c
 create mode 100644 xen/common/hypfs.c
 create mode 100644 xen/include/public/hypfs.h
 create mode 100644 xen/include/xen/hypfs.h
 create mode 100644 xen/include/xen/param.h
 create mode 100755 xen/tools/binfile
 delete mode 100644 xen/xsm/flask/flask-policy.S

-- 
2.16.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [Xen-devel] [PATCH v3 1/9] xen: add a generic way to include binary files as variables
  2020-01-21  8:43 [Xen-devel] [PATCH v3 0/9] Add hypervisor sysfs-like support Juergen Gross
@ 2020-01-21  8:43 ` Juergen Gross
  2020-02-03 13:39   ` Jan Beulich
  2020-01-21  8:43 ` [Xen-devel] [PATCH v3 2/9] xen: split parameter related definitions in own header file Juergen Gross
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 42+ messages in thread
From: Juergen Gross @ 2020-01-21  8:43 UTC (permalink / raw)
  To: xen-devel
  Cc: Juergen Gross, Stefano Stabellini, Julien Grall, Wei Liu,
	Konrad Rzeszutek Wilk, George Dunlap, Andrew Cooper, Ian Jackson,
	Jan Beulich, Daniel De Graaf

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 <jgross@suse.com>
---
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] <target-src.S> <binary-file> <varname>
+# -i     add to .init.rodata (default: .rodata) section
+
+[ "$1" = "-i" ] && {
+    shift
+    section=".init"
+}
+
+target=$1
+binsource=$2
+varname=$3
+
+cat <<EOF >$target
+#include <asm/asm_defns.h>
+
+        .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 <asm/asm_defns.h>
-
-        .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)
-- 
2.16.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Xen-devel] [PATCH v3 2/9] xen: split parameter related definitions in own header file
  2020-01-21  8:43 [Xen-devel] [PATCH v3 0/9] Add hypervisor sysfs-like support Juergen Gross
  2020-01-21  8:43 ` [Xen-devel] [PATCH v3 1/9] xen: add a generic way to include binary files as variables Juergen Gross
@ 2020-01-21  8:43 ` Juergen Gross
  2020-01-21 13:00   ` Julien Grall
                     ` (5 more replies)
  2020-01-21  8:43 ` [Xen-devel] [PATCH v3 3/9] docs: add feature document for Xen hypervisor sysfs-like support Juergen Gross
                   ` (7 subsequent siblings)
  9 siblings, 6 replies; 42+ messages in thread
From: Juergen Gross @ 2020-01-21  8:43 UTC (permalink / raw)
  To: xen-devel
  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, Roger Pau Monné

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 <jgross@suse.com>
---
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 <xen/errno.h>
 #include <acpi/actables.h>
 #include <xen/mm.h>
+#include <xen/param.h>
 #include <xen/device_tree.h>
 
 #include <asm/acpi.h>
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 <xen/cpumask.h>
 #include <xen/init.h>
 #include <xen/mm.h>
+#include <xen/param.h>
 #include <xen/sizes.h>
 #include <xen/smp.h>
 #include <xen/spinlock.h>
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 <xen/compile.h>
 #include <xen/lib.h>
 #include <xen/mm.h>
+#include <xen/param.h>
 #include <xen/domain_page.h>
 #include <xen/sched.h>
 #include <xen/sizes.h>
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 <xen/lib.h>
 #include <xen/mm.h>
+#include <xen/param.h>
 #include <xen/sched.h>
 #include <xen/sizes.h>
 #include <xen/warning.h>
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 <xen/init.h>
 #include <xen/irq.h>
 #include <xen/mm.h>
+#include <xen/param.h>
 #include <xen/softirq.h>
 #include <xen/keyhandler.h>
 #include <xen/cpu.h>
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 <xen/errno.h>
 #include <xen/init.h>
 #include <xen/mm.h>
+#include <xen/param.h>
 #include <xen/sched.h>
 #include <xen/smp.h>
 #include <xen/softirq.h>
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 <xen/livepatch.h>
 #include <xen/mem_access.h>
 #include <xen/mm.h>
+#include <xen/param.h>
 #include <xen/perfc.h>
 #include <xen/smp.h>
 #include <xen/softirq.h>
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 <xen/acpi.h>
 #include <xen/irq.h>
 #include <xen/mm.h>
+#include <xen/param.h>
 #include <xen/dmi.h>
 #include <asm/fixmap.h>
 #include <asm/page.h>
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 <xen/smp.h>
 #include <xen/guest_access.h>
 #include <xen/keyhandler.h>
+#include <xen/param.h>
 #include <xen/trace.h>
 #include <xen/irq.h>
 #include <asm/cache.h>
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 <xen/errno.h>
 #include <xen/delay.h>
 #include <xen/cpumask.h>
+#include <xen/param.h>
 #include <xen/sched.h>
 #include <xen/timer.h>
 #include <xen/xmalloc.h>
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 <xen/acpi.h>
 #include <xen/errno.h>
 #include <xen/iocap.h>
+#include <xen/param.h>
 #include <xen/sched.h>
 #include <asm/acpi.h>
 #include <asm/irq.h>
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 <xen/errno.h>
 #include <xen/init.h>
 #include <xen/mm.h>
+#include <xen/param.h>
 #include <xen/sched.h>
 #include <xen/irq.h>
 #include <xen/delay.h>
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 <xen/init.h>
 #include <xen/bitops.h>
 #include <xen/mm.h>
+#include <xen/param.h>
 #include <xen/smp.h>
 #include <xen/pci.h>
 #include <asm/io.h>
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 <xen/init.h>
 #include <xen/string.h>
 #include <xen/delay.h>
+#include <xen/param.h>
 #include <xen/smp.h>
 #include <asm/current.h>
 #include <asm/debugreg.h>
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 <xen/init.h>
 #include <xen/types.h>
 #include <xen/kernel.h>
+#include <xen/param.h>
 #include <xen/smp.h>
 #include <xen/errno.h>
 #include <xen/console.h>
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 <xen/event.h>
 #include <xen/kernel.h>
 #include <xen/delay.h>
+#include <xen/param.h>
 #include <xen/smp.h>
 #include <xen/mm.h>
 #include <xen/cpu.h>
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 <xen/lib.h>
 #include <xen/init.h>
 #include <xen/mm.h>
+#include <xen/param.h>
 #include <xen/stdbool.h>
 #include <asm/flushtlb.h>
 #include <asm/invpcid.h>
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 <xen/lib.h>
 #include <xen/cpu.h>
 #include <xen/init.h>
+#include <xen/param.h>
 #include <xen/softirq.h>
 #include <xen/trace.h>
 #include <asm/cpuidle.h>
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 <xen/event.h>
 #include <xen/guest_access.h>
 #include <xen/cpu.h>
+#include <xen/param.h>
 #include <asm/regs.h>
 #include <asm/types.h>
 #include <asm/msr.h>
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 <xen/init.h>
 #include <xen/lib.h>
+#include <xen/param.h>
 #include <xen/sched.h>
 #include <xen/nospec.h>
 #include <asm/cpuid.h>
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 <xen/init.h>
 #include <xen/iocap.h>
 #include <xen/libelf.h>
+#include <xen/param.h>
 #include <xen/pfn.h>
 #include <xen/sched.h>
 #include <xen/sched-if.h>
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 <xen/init.h>
 #include <xen/lib.h>
 #include <xen/mm.h>
+#include <xen/param.h>
 #include <xen/compat.h>
 #include <xen/dmi.h>
 #include <xen/pfn.h>
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 <xen/kernel.h>
 #include <xen/ctype.h>
 #include <xen/init.h>
+#include <xen/param.h>
 #include <asm/cache.h>
 #include <asm/fixmap.h>
 #include <asm/mpspec.h>
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 <xen/init.h>
 #include <xen/cpu.h>
 #include <xen/cpumask.h>
+#include <xen/param.h>
 #include <asm/apicdef.h>
 #include <asm/genapic.h>
 #include <asm/apic.h>
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 <xen/softirq.h>
 #include <xen/irq.h>
 #include <xen/numa.h>
+#include <xen/param.h>
 #include <xen/sched.h>
 #include <asm/fixmap.h>
 #include <asm/div64.h>
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 <xen/init.h>
 #include <xen/lib.h>
+#include <xen/param.h>
 #include <xen/sched.h>
 #include <xen/smp.h>
 #include <xen/percpu.h>
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 <xen/mem_access.h>
 #include <xen/rangeset.h>
 #include <xen/monitor.h>
+#include <xen/param.h>
 #include <xen/warning.h>
 #include <xen/vpci.h>
 #include <xen/nospec.h>
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 <xen/lib.h>
 #include <xen/dmi.h>
 #include <xen/bitmap.h>
+#include <xen/param.h>
 #include <asm/hvm/support.h>
 
 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 <xen/version.h>
 #include <xen/hypercall.h>
 #include <xen/domain_page.h>
+#include <xen/param.h>
 #include <asm/guest_access.h>
 #include <asm/guest/hyperv-tlfs.h>
 #include <asm/paging.h>
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 <xen/init.h>
 #include <xen/mm.h>
 #include <xen/lib.h>
+#include <xen/param.h>
 #include <xen/errno.h>
 #include <xen/domain_page.h>
 #include <xen/event.h>
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 <xen/init.h>
 #include <xen/lib.h>
+#include <xen/param.h>
 #include <xen/trace.h>
 #include <xen/sched.h>
 #include <xen/irq.h>
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 <xen/init.h>
 #include <xen/irq.h>
 #include <xen/delay.h>
+#include <xen/param.h>
 #include <xen/sched.h>
 #include <xen/acpi.h>
 #include <xen/keyhandler.h>
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 <xen/errno.h>
 #include <xen/event.h>
 #include <xen/irq.h>
+#include <xen/param.h>
 #include <xen/perfc.h>
 #include <xen/sched.h>
 #include <xen/keyhandler.h>
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 <xen/kernel.h>
 #include <xen/init.h>
 #include <xen/notifier.h>
+#include <xen/param.h>
 #include <xen/sched.h>
 #include <xen/smp.h>
 #include <xen/softirq.h>
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 <xen/kernel.h>
 #include <xen/lib.h>
 #include <xen/mm.h>
+#include <xen/param.h>
 #include <xen/domain.h>
 #include <xen/sched.h>
 #include <xen/err.h>
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 <xen/iommu.h>
 #include <xen/vm_event.h>
 #include <xen/event.h>
+#include <xen/param.h>
 #include <public/vm_event.h>
 #include <asm/domain.h>
 #include <asm/page.h>
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 <xen/acpi.h>
 #include <xen/cpu.h>
 #include <xen/errno.h>
+#include <xen/param.h>
 #include <xen/pci.h>
 #include <xen/pci_regs.h>
 #include <xen/iocap.h>
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 <xen/init.h>
 #include <xen/lib.h>
 #include <xen/mm.h>
+#include <xen/param.h>
 #include <xen/irq.h>
 #include <xen/delay.h>
 #include <xen/time.h>
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 <xen/nodemask.h>
 #include <xen/numa.h>
 #include <xen/keyhandler.h>
+#include <xen/param.h>
 #include <xen/time.h>
 #include <xen/smp.h>
 #include <xen/pfn.h>
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 <xen/types.h>
 #include <xen/errno.h>
 #include <xen/init.h>
+#include <xen/param.h>
 #include <xen/string.h>
 #include <xen/delay.h>
 #include <xen/xenoprof.h>
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 <xen/cpu.h>
 #include <xen/err.h>
 #include <xen/init.h>
+#include <xen/param.h>
 #include <xen/sched.h>
 #include <asm/psr.h>
 
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 <xen/domain_page.h>
 #include <xen/errno.h>
 #include <xen/lib.h>
+#include <xen/param.h>
 #include <xen/sched.h>
 
 #include <asm/cpufeature.h>
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 <xen/hypercall.h>
 #include <xen/init.h>
 #include <xen/iocap.h>
+#include <xen/param.h>
 #include <xen/shutdown.h>
 #include <xen/types.h>
 #include <xen/consoled.h>
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 <xen/lib.h>
 #include <xen/err.h>
 #include <xen/grant_table.h>
+#include <xen/param.h>
 #include <xen/sched.h>
 #include <xen/domain.h>
 #include <xen/serial.h>
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 <xen/init.h>
 #include <xen/lib.h>
+#include <xen/param.h>
 #include <xen/sched.h>
 #include <xen/smp.h>
 #include <xen/delay.h>
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 <xen/errno.h>
 #include <xen/init.h>
 #include <xen/lib.h>
+#include <xen/param.h>
 #include <xen/warning.h>
 
 #include <asm/microcode.h>
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 <xen/init.h>
 #include <xen/types.h>
 #include <xen/lib.h>
+#include <xen/param.h>
 #include <xen/sched.h>
 #include <xen/domain_page.h>
 #include <xen/iommu.h>
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 <xen/sched.h>
 #include <xen/lib.h>
 #include <xen/init.h>
+#include <xen/param.h>
 #include <xen/time.h>
 #include <xen/timer.h>
 #include <xen/smp.h>
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 <xen/err.h>
 #include <xen/errno.h>
 #include <xen/mm.h>
+#include <xen/param.h>
 #include <xen/console.h>
 #include <xen/shutdown.h>
 #include <xen/guest_access.h>
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 <xen/init.h>
+#include <xen/param.h>
 #include <asm/msr.h>
 
 /*
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 <xen/init.h>
 #include <xen/mm.h>
+#include <xen/param.h>
 #include <xen/acpi.h>
 #include <xen/xmalloc.h>
 #include <xen/pci.h>
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 <xen/param.h>
 #include <xen/percpu.h>
 #include <xen/sched.h>
 #include <asm/current.h>
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 <xen/guest_access.h>
 #include <xen/lib.h>
 #include <xen/nospec.h>
+#include <xen/param.h>
 #include <xen/sched.h>
 #include <xen/time.h>
 #include <xsm/xsm.h>
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 <xen/cpu.h>
 #include <xen/init.h>
 #include <xen/cpumask.h>
+#include <xen/param.h>
 
 #include <asm/smp.h>
 
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 <xen/lib.h>
 #include <xen/init.h>
 #include <xen/cpumask.h>
+#include <xen/param.h>
 #include <xen/percpu.h>
 #include <xen/sched.h>
 #include <xen/sched-if.h>
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 <xen/keyhandler.h>
 #include <xen/lib.h>
 #include <xen/mm.h>
+#include <xen/param.h>
 #include <xen/percpu.h>
 #include <xen/serial.h>
 #include <xen/smp.h>
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 <xen/lib.h>
 #include <xen/ctype.h>
 #include <xen/err.h>
+#include <xen/param.h>
 #include <xen/sched.h>
 #include <xen/sched-if.h>
 #include <xen/domain.h>
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 <xen/lib.h>
 #include <xen/mm.h>
 #include <xen/multiboot.h>
+#include <xen/param.h>
 #include <xen/pci_regs.h>
 #include <xen/pfn.h>
 #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 <xen/watchdog.h>
 #include <asm/debugger.h>
 #include <xen/init.h>
+#include <xen/param.h>
 #include <xen/smp.h>
 #include <xen/console.h>
 #include <xen/errno.h>
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 <xen/lib.h>
 #include <xen/sched.h>
 #include <xen/mm.h>
+#include <xen/param.h>
 #include <xen/event.h>
 #include <xen/trace.h>
 #include <xen/grant_table.h>
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 <xen/init.h>
 #include <xen/lib.h>
 #include <xen/errno.h>
+#include <xen/param.h>
 #include <xen/version.h>
 #include <xen/sched.h>
 #include <xen/paging.h>
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 <xen/ctype.h>
 #include <xen/errno.h>
 #include <xen/guest_access.h>
+#include <xen/param.h>
 #include <xen/watchdog.h>
 #include <xen/sched.h>
 #include <xen/types.h>
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 <xen/types.h>
 #include <xen/lib.h>
 #include <xen/mm.h>
+#include <xen/param.h>
 #include <xen/perfc.h>
 #include <xen/sched.h>
 #include <xen/event.h>
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 <xen/sched.h>
 #include <xen/spinlock.h>
 #include <xen/mm.h>
+#include <xen/param.h>
 #include <xen/irq.h>
 #include <xen/softirq.h>
 #include <xen/domain_page.h>
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 <xen/types.h>
 #include <xen/kernel.h>
 #include <xen/init.h>
+#include <xen/param.h>
 #include <xen/spinlock.h>
 #include <xen/smp.h>
 #include <xen/rcupdate.h>
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 <xen/init.h>
 #include <xen/lib.h>
+#include <xen/param.h>
 #include <xen/sched.h>
 #include <xen/domain.h>
 #include <xen/delay.h>
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 <xen/init.h>
 #include <xen/lib.h>
+#include <xen/param.h>
 #include <xen/sched.h>
 #include <xen/domain.h>
 #include <xen/delay.h>
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 <xen/init.h>
 #include <xen/lib.h>
+#include <xen/param.h>
 #include <xen/sched.h>
 #include <xen/domain.h>
 #include <xen/delay.h>
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 <xen/init.h>
 #include <xen/lib.h>
+#include <xen/param.h>
 #include <xen/sched.h>
 #include <xen/domain.h>
 #include <xen/delay.h>
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 <xen/errno.h>
 #include <xen/sched.h>
 #include <xen/lib.h>
+#include <xen/param.h>
 #include <xen/smp.h>
 #include <xen/perfc.h>
 #include <xen/time.h>
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 <asm/types.h>
 #include <asm/io.h>
 #include <xen/lib.h>
+#include <xen/param.h>
 #include <xen/sched.h>
 #include <xen/smp.h>
 #include <xen/trace.h>
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 <xen/init.h>
 #include <xen/kernel.h>
 #include <xen/mm.h>
+#include <xen/param.h>
 #include <xen/pfn.h>
 #include <acpi/acpi.h>
 #include <acpi/apei.h>
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 <xen/init.h>
 #include <xen/kernel.h>
+#include <xen/param.h>
 #include <xen/smp.h>
 #include <xen/string.h>
 #include <xen/types.h>
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 <asm/types.h>
 #include <xen/console.h>
 #include <xen/device_tree.h>
+#include <xen/param.h>
 #include <xen/serial.h>
 #include <xen/errno.h>
 #include <xen/acpi.h>
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 <xen/init.h>
 #include <xen/event.h>
 #include <xen/console.h>
+#include <xen/param.h>
 #include <xen/serial.h>
 #include <xen/softirq.h>
 #include <xen/keyhandler.h>
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 <xen/console.h>
 #include <xen/delay.h>
 #include <xen/errno.h>
+#include <xen/param.h>
 #include <xen/pci.h>
 #include <xen/serial.h>
 #include <asm/byteorder.h>
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 <xen/console.h>
 #include <xen/init.h>
 #include <xen/irq.h>
+#include <xen/param.h>
 #include <xen/sched.h>
 #include <xen/timer.h>
 #include <xen/serial.h>
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 <xen/delay.h>
 #include <xen/init.h>
 #include <xen/mm.h>
+#include <xen/param.h>
 #include <xen/serial.h>
 #include <xen/cache.h>
 
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 <xen/delay.h>
 #include <xen/cpumask.h>
 #include <xen/list.h>
+#include <xen/param.h>
 #include <xen/sched.h>
 #include <xen/string.h>
 #include <xen/timer.h>
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 <xen/errno.h>
 #include <xen/acpi.h>
+#include <xen/param.h>
 #include <asm/apicdef.h>
 #include <asm/io_apic.h>
 #include <asm/amd-iommu.h>
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 <xen/paging.h>
 #include <xen/guest_access.h>
 #include <xen/event.h>
+#include <xen/param.h>
 #include <xen/softirq.h>
 #include <xen/keyhandler.h>
 #include <xsm/xsm.h>
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 <xen/prefetch.h>
 #include <xen/iommu.h>
 #include <xen/irq.h>
+#include <xen/param.h>
 #include <xen/vm_event.h>
 #include <asm/hvm/irq.h>
 #include <xen/delay.h>
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 <xen/kernel.h>
 #include <xen/acpi.h>
 #include <xen/mm.h>
+#include <xen/param.h>
 #include <xen/xmalloc.h>
 #include <xen/pci.h>
 #include <xen/pci_regs.h>
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 <xen/irq.h>
+#include <xen/param.h>
 #include <xen/sched.h>
 #include <xen/xmalloc.h>
 #include <xen/domain_page.h>
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 <weidong.han@intel.com>
  */
 
+#include <xen/param.h>
 #include <xen/sched.h>
 #include <xen/softirq.h>
 #include <xen/domain_page.h>
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 <http://www.gnu.org/licenses/>.
  */
 
+#include <xen/param.h>
 #include <xen/sched.h>
 #include <xen/pci.h>
 #include <xen/pci_regs.h>
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 <xen/init.h>
 #include <xen/lib.h>
+#include <xen/param.h>
 #include <xen/xmalloc.h>
 #include <xen/kernel.h>
 #include <xen/vga.h>
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 <xen/init.h>
 #include <xen/lib.h>
 #include <xen/mm.h>
+#include <xen/param.h>
 #include <xen/vga.h>
 #include <xen/pci.h>
 #include <asm/io.h>
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 <xen/init.h>
+
+/*
+ * 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 <xsm/xsm.h>
 #include <xen/guest_access.h>
 #include <xen/err.h>
+#include <xen/param.h>
 
 #include <public/xsm/flask_op.h>
 
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 <xen/init.h>
 #include <xen/errno.h>
 #include <xen/lib.h>
+#include <xen/param.h>
 
 #include <xen/hypercall.h>
 #include <xsm/xsm.h>
-- 
2.16.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Xen-devel] [PATCH v3 3/9] docs: add feature document for Xen hypervisor sysfs-like support
  2020-01-21  8:43 [Xen-devel] [PATCH v3 0/9] Add hypervisor sysfs-like support Juergen Gross
  2020-01-21  8:43 ` [Xen-devel] [PATCH v3 1/9] xen: add a generic way to include binary files as variables Juergen Gross
  2020-01-21  8:43 ` [Xen-devel] [PATCH v3 2/9] xen: split parameter related definitions in own header file Juergen Gross
@ 2020-01-21  8:43 ` Juergen Gross
  2020-01-21 13:14   ` Julien Grall
  2020-01-21  8:43 ` [Xen-devel] [PATCH v3 4/9] xen: add basic hypervisor filesystem support Juergen Gross
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 42+ messages in thread
From: Juergen Gross @ 2020-01-21  8:43 UTC (permalink / raw)
  To: xen-devel
  Cc: Juergen Gross, Stefano Stabellini, Julien Grall, Wei Liu,
	Konrad Rzeszutek Wilk, George Dunlap, Andrew Cooper, Ian Jackson,
	Jan Beulich

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 <jgross@suse.com>
---
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 <path>
+
+the user can list the entries of a specific path of the FS. Using:
+
+    xenhypfs cat <path>
+
+the content of an entry can be retrieved. Using:
+
+    xenhypfs write <path> <string>
+
+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.
-- 
2.16.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Xen-devel] [PATCH v3 4/9] xen: add basic hypervisor filesystem support
  2020-01-21  8:43 [Xen-devel] [PATCH v3 0/9] Add hypervisor sysfs-like support Juergen Gross
                   ` (2 preceding siblings ...)
  2020-01-21  8:43 ` [Xen-devel] [PATCH v3 3/9] docs: add feature document for Xen hypervisor sysfs-like support Juergen Gross
@ 2020-01-21  8:43 ` Juergen Gross
  2020-01-31 15:50   ` Wei Liu
  2020-02-03 15:07   ` Jan Beulich
  2020-01-21  8:43 ` [Xen-devel] [PATCH v3 5/9] libs: add libxenhypfs Juergen Gross
                   ` (5 subsequent siblings)
  9 siblings, 2 replies; 42+ messages in thread
From: Juergen Gross @ 2020-01-21  8:43 UTC (permalink / raw)
  To: xen-devel
  Cc: Juergen Gross, Stefano Stabellini, Julien Grall, Wei Liu,
	Konrad Rzeszutek Wilk, George Dunlap, Andrew Cooper, Ian Jackson,
	Jan Beulich, Volodymyr Babchuk, Roger Pau Monné

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 <jgross@suse.com>
---
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 <xen/lib.h>
+#include <xen/err.h>
+#include <xen/guest_access.h>
+#include <xen/hypercall.h>
+#include <xen/hypfs.h>
+#include <xen/rwlock.h>
+#include <public/hypfs.h>
+
+#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 <xen/list.h>
+#include <xen/string.h>
+#include <public/hypfs.h>
+
+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__ */
-- 
2.16.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Xen-devel] [PATCH v3 5/9] libs: add libxenhypfs
  2020-01-21  8:43 [Xen-devel] [PATCH v3 0/9] Add hypervisor sysfs-like support Juergen Gross
                   ` (3 preceding siblings ...)
  2020-01-21  8:43 ` [Xen-devel] [PATCH v3 4/9] xen: add basic hypervisor filesystem support Juergen Gross
@ 2020-01-21  8:43 ` Juergen Gross
  2020-01-31 15:57   ` Wei Liu
  2020-01-21  8:43 ` [Xen-devel] [PATCH v3 6/9] tools: add xenfs tool Juergen Gross
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 42+ messages in thread
From: Juergen Gross @ 2020-01-21  8:43 UTC (permalink / raw)
  To: xen-devel
  Cc: Juergen Gross, Stefano Stabellini, Julien Grall, Wei Liu,
	Konrad Rzeszutek Wilk, George Dunlap, Andrew Cooper, Ian Jackson,
	Jan Beulich

Add the new library libxenhypfs for access to the hypervisor filesystem.

Signed-off-by: Juergen Gross <jgross@suse.com>
---
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 <http://www.gnu.org/licenses/>.
+ */
+
+#define __XEN_TOOLS__ 1
+
+#define _GNU_SOURCE
+
+#include <errno.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <string.h>
+#include <zlib.h>
+
+#include <xentoollog.h>
+#include <xenhypfs.h>
+#include <xencall.h>
+#include <xentoolcore_internal.h>
+
+#include <xen/xen.h>
+#include <xen/hypfs.h>
+
+#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 <http://www.gnu.org/licenses/>.
+ */
+#ifndef XENHYPFS_H
+#define XENHYPFS_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+/* Callers who don't care don't need to #include <xentoollog.h> */
+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
-- 
2.16.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Xen-devel] [PATCH v3 6/9] tools: add xenfs tool
  2020-01-21  8:43 [Xen-devel] [PATCH v3 0/9] Add hypervisor sysfs-like support Juergen Gross
                   ` (4 preceding siblings ...)
  2020-01-21  8:43 ` [Xen-devel] [PATCH v3 5/9] libs: add libxenhypfs Juergen Gross
@ 2020-01-21  8:43 ` Juergen Gross
  2020-01-31 15:59   ` Wei Liu
  2020-01-21  8:43 ` [Xen-devel] [PATCH v3 7/9] xen: provide version information in hypfs Juergen Gross
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 42+ messages in thread
From: Juergen Gross @ 2020-01-21  8:43 UTC (permalink / raw)
  To: xen-devel
  Cc: Juergen Gross, Stefano Stabellini, Julien Grall, Wei Liu,
	Konrad Rzeszutek Wilk, George Dunlap, Andrew Cooper, Ian Jackson,
	Jan Beulich

Add the xenfs tool for accessing the hypervisor filesystem.

Signed-off-by: Juergen Gross <jgross@suse.com>
---
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<xenhypfs> I<subcommand> [I<options>] [I<args>]
+
+=head1 DESCRIPTION
+
+The B<xenhypfs> 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<ls> I<path>
+
+List the available entries below I<path>.
+
+=item B<cat> [I<-b>] I<path>
+
+Show the contents of the entry specified by I<path>. Non-printable characters
+other than white space characters (like tab, new line) will be shown as
+B<\xnn> (B<nn> being a two digit hex number) unless the option B<-b> is
+specified.
+
+=item B<write> I<path> I<value>
+
+Set the contents of the entry specified by I<path> to I<value>.
+
+=item B<tree>
+
+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 <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <xenhypfs.h>
+
+static struct xenhypfs_handle *hdl;
+
+static int usage(void)
+{
+    fprintf(stderr, "usage: xenhypfs ls <path>\n");
+    fprintf(stderr, "       xenhypfs cat [-b] <path>\n");
+    fprintf(stderr, "       xenhypfs write <path> <val>\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 = "<dir>   ";
+        break;
+    case xenhypfs_type_blob:
+        res = "<blob>  ";
+        break;
+    case xenhypfs_type_string:
+        res = "<string>";
+        break;
+    case xenhypfs_type_uint:
+        res = "<uint>  ";
+        break;
+    case xenhypfs_type_int:
+        res = "<int>   ";
+        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;
+}
-- 
2.16.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Xen-devel] [PATCH v3 7/9] xen: provide version information in hypfs
  2020-01-21  8:43 [Xen-devel] [PATCH v3 0/9] Add hypervisor sysfs-like support Juergen Gross
                   ` (5 preceding siblings ...)
  2020-01-21  8:43 ` [Xen-devel] [PATCH v3 6/9] tools: add xenfs tool Juergen Gross
@ 2020-01-21  8:43 ` Juergen Gross
  2020-02-03 17:02   ` Jan Beulich
  2020-01-21  8:43 ` [Xen-devel] [PATCH v3 8/9] xen: add /buildinfo/config entry to hypervisor filesystem Juergen Gross
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 42+ messages in thread
From: Juergen Gross @ 2020-01-21  8:43 UTC (permalink / raw)
  To: xen-devel
  Cc: Juergen Gross, Stefano Stabellini, Julien Grall, Wei Liu,
	Konrad Rzeszutek Wilk, George Dunlap, Andrew Cooper, Ian Jackson,
	Jan Beulich

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 <jgross@suse.com>
---
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 <xen/paging.h>
 #include <xen/guest_access.h>
 #include <xen/hypercall.h>
+#include <xen/hypfs.h>
 #include <xsm/xsm.h>
 #include <asm/current.h>
 #include <public/version.h>
@@ -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
-- 
2.16.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Xen-devel] [PATCH v3 8/9] xen: add /buildinfo/config entry to hypervisor filesystem
  2020-01-21  8:43 [Xen-devel] [PATCH v3 0/9] Add hypervisor sysfs-like support Juergen Gross
                   ` (6 preceding siblings ...)
  2020-01-21  8:43 ` [Xen-devel] [PATCH v3 7/9] xen: provide version information in hypfs Juergen Gross
@ 2020-01-21  8:43 ` Juergen Gross
  2020-01-21  8:43 ` [Xen-devel] [PATCH v3 9/9] xen: add runtime parameter access support to hypfs Juergen Gross
  2020-01-26 22:05 ` [Xen-devel] [PATCH v3 0/9] Add hypervisor sysfs-like support Rich Persaud
  9 siblings, 0 replies; 42+ messages in thread
From: Juergen Gross @ 2020-01-21  8:43 UTC (permalink / raw)
  To: xen-devel
  Cc: Juergen Gross, Stefano Stabellini, Julien Grall, Wei Liu,
	Konrad Rzeszutek Wilk, George Dunlap, Andrew Cooper, Ian Jackson,
	Jan Beulich

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 <jgross@suse.com>
---
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 */
 
-- 
2.16.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Xen-devel] [PATCH v3 9/9] xen: add runtime parameter access support to hypfs
  2020-01-21  8:43 [Xen-devel] [PATCH v3 0/9] Add hypervisor sysfs-like support Juergen Gross
                   ` (7 preceding siblings ...)
  2020-01-21  8:43 ` [Xen-devel] [PATCH v3 8/9] xen: add /buildinfo/config entry to hypervisor filesystem Juergen Gross
@ 2020-01-21  8:43 ` Juergen Gross
  2020-01-26 22:05 ` [Xen-devel] [PATCH v3 0/9] Add hypervisor sysfs-like support Rich Persaud
  9 siblings, 0 replies; 42+ messages in thread
From: Juergen Gross @ 2020-01-21  8:43 UTC (permalink / raw)
  To: xen-devel
  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,
	Roger Pau Monné

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 <jgross@suse.com>
---
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 <xen/guest_access.h>
 #include <xen/hypercall.h>
 #include <xen/hypfs.h>
+#include <xen/param.h>
 #include <xen/rwlock.h>
 #include <public/hypfs.h>
 
@@ -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, &params, true);
+
+    for ( param = __paramhypfs_start; param < __paramhypfs_end; param++ )
+        hypfs_add_leaf(&params, &param->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" };
 /*
  * <lvl> := none|error|warning|info|debug|all
  * loglvl=<lvl_print_always>[/<lvl_print_ratelimit>]
@@ -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 <xen/hypfs.h>
 #include <xen/init.h>
 
 /*
@@ -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 */
-- 
2.16.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* Re: [Xen-devel] [PATCH v3 2/9] xen: split parameter related definitions in own header file
  2020-01-21  8:43 ` [Xen-devel] [PATCH v3 2/9] xen: split parameter related definitions in own header file Juergen Gross
@ 2020-01-21 13:00   ` Julien Grall
  2020-01-21 13:28     ` Jürgen Groß
  2020-01-22  1:34   ` Dario Faggioli
                     ` (4 subsequent siblings)
  5 siblings, 1 reply; 42+ messages in thread
From: Julien Grall @ 2020-01-21 13:00 UTC (permalink / raw)
  To: Juergen Gross, xen-devel
  Cc: Kevin Tian, Stefano Stabellini, Jun Nakajima, Wei Liu,
	Konrad Rzeszutek Wilk, George Dunlap, Andrew Cooper,
	Paul Durrant, Ian Jackson, Christopher Clark, Dario Faggioli,
	Lukasz Hawrylko, Daniel De Graaf, Volodymyr Babchuk,
	Roger Pau Monné

Hi Juergen,

On 21/01/2020 08:43, Juergen Gross wrote:
> 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.

How did you find out the list of places where the new files need to be 
included?

Also, was it build test it on Arm?

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Xen-devel] [PATCH v3 3/9] docs: add feature document for Xen hypervisor sysfs-like support
  2020-01-21  8:43 ` [Xen-devel] [PATCH v3 3/9] docs: add feature document for Xen hypervisor sysfs-like support Juergen Gross
@ 2020-01-21 13:14   ` Julien Grall
  2020-01-21 14:17     ` Jürgen Groß
  0 siblings, 1 reply; 42+ messages in thread
From: Julien Grall @ 2020-01-21 13:14 UTC (permalink / raw)
  To: Juergen Gross, xen-devel
  Cc: Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson

Hi Juergen.

On 21/01/2020 08:43, Juergen Gross wrote:
> 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 <jgross@suse.com>
> ---
> 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

I would like to get some consitency in the formatting at least within a 
same file. In this case, you seem to mostly use a single space the full 
stop. So I think you want to use single space here too.

> +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 <path>
> +
> +the user can list the entries of a specific path of the FS. Using:
> +
> +    xenhypfs cat <path>
> +
> +the content of an entry can be retrieved. Using:
> +
> +    xenhypfs write <path> <string>
> +
> +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

Does this want any update? Such as using 4.14 rather than 4.13.

> +---------- -------- -------- -------------------------------------------
> 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.

It may be clearer if you replace a full stop with :.

However, I am not sure what are actually the tags? Do you have a 
concrete example how they can be used?

> +
> +* 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.

How about Arm64? Also, if it is support by both arm64 and arm32, should 
we use ARM or ARM32,ARM64?

> +* 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.
> 

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Xen-devel] [PATCH v3 2/9] xen: split parameter related definitions in own header file
  2020-01-21 13:00   ` Julien Grall
@ 2020-01-21 13:28     ` Jürgen Groß
  2020-01-21 13:31       ` Julien Grall
  0 siblings, 1 reply; 42+ messages in thread
From: Jürgen Groß @ 2020-01-21 13:28 UTC (permalink / raw)
  To: Julien Grall, xen-devel
  Cc: Kevin Tian, Stefano Stabellini, Jun Nakajima, Wei Liu,
	Konrad Rzeszutek Wilk, George Dunlap, Andrew Cooper,
	Paul Durrant, Ian Jackson, Christopher Clark, Dario Faggioli,
	Lukasz Hawrylko, Daniel De Graaf, Volodymyr Babchuk,
	Roger Pau Monné

On 21.01.20 14:00, Julien Grall wrote:
> Hi Juergen,
> 
> On 21/01/2020 08:43, Juergen Gross wrote:
>> 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.
> 
> How did you find out the list of places where the new files need to be 
> included?

I did a grep for all parameter definitions.

> 
> Also, was it build test it on Arm?

Yes.


Juergen

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Xen-devel] [PATCH v3 2/9] xen: split parameter related definitions in own header file
  2020-01-21 13:28     ` Jürgen Groß
@ 2020-01-21 13:31       ` Julien Grall
  0 siblings, 0 replies; 42+ messages in thread
From: Julien Grall @ 2020-01-21 13:31 UTC (permalink / raw)
  To: Jürgen Groß, xen-devel
  Cc: Kevin Tian, Stefano Stabellini, Jun Nakajima, Wei Liu,
	Konrad Rzeszutek Wilk, George Dunlap, Andrew Cooper,
	Paul Durrant, Ian Jackson, Christopher Clark, Dario Faggioli,
	Lukasz Hawrylko, Daniel De Graaf, Volodymyr Babchuk,
	Roger Pau Monné



On 21/01/2020 13:28, Jürgen Groß wrote:
> On 21.01.20 14:00, Julien Grall wrote:
>> Hi Juergen,
>>
>> On 21/01/2020 08:43, Juergen Gross wrote:
>>> 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.
>>
>> How did you find out the list of places where the new files need to be 
>> included?
> 
> I did a grep for all parameter definitions.
That's what I thought but wanted to check :).

>>
>> Also, was it build test it on Arm?
> 
> Yes.

Thanks!

For Arm + common code:

Acked-by: Julien Grall <julien@xen.org>

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Xen-devel] [PATCH v3 3/9] docs: add feature document for Xen hypervisor sysfs-like support
  2020-01-21 13:14   ` Julien Grall
@ 2020-01-21 14:17     ` Jürgen Groß
  2020-02-03 10:29       ` Julien Grall
  0 siblings, 1 reply; 42+ messages in thread
From: Jürgen Groß @ 2020-01-21 14:17 UTC (permalink / raw)
  To: Julien Grall, xen-devel
  Cc: Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson

On 21.01.20 14:14, Julien Grall wrote:
> Hi Juergen.
> 
> On 21/01/2020 08:43, Juergen Gross wrote:
>> 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 <jgross@suse.com>
>> ---
>> 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
> 
> I would like to get some consitency in the formatting at least within a 
> same file. In this case, you seem to mostly use a single space the full 
> stop. So I think you want to use single space here too.

Either is fine with me.

I'm going to use a single space in case no one steps up and asks for
double spaces after full stops.

> 
>> +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 <path>
>> +
>> +the user can list the entries of a specific path of the FS. Using:
>> +
>> +    xenhypfs cat <path>
>> +
>> +the content of an entry can be retrieved. Using:
>> +
>> +    xenhypfs write <path> <string>
>> +
>> +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
> 
> Does this want any update? Such as using 4.14 rather than 4.13.

Uh, yes.

> 
>> +---------- -------- -------- -------------------------------------------
>> 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.
> 
> It may be clearer if you replace a full stop with :.

Okay.

> 
> However, I am not sure what are actually the tags? Do you have a 
> concrete example how they can be used?

I'll add this one:

/cpu-bugs/active-pv/xpti (0|1) [w,X86,PV]

> 
>> +
>> +* 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.
> 
> How about Arm64? Also, if it is support by both arm64 and arm32, should 
> we use ARM or ARM32,ARM64?

ARM64 should be added and I'd suggest to use "ARM" instead of
"ARM32,ARM64".

> 
>> +* 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.

Juergen

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Xen-devel] [PATCH v3 2/9] xen: split parameter related definitions in own header file
  2020-01-21  8:43 ` [Xen-devel] [PATCH v3 2/9] xen: split parameter related definitions in own header file Juergen Gross
  2020-01-21 13:00   ` Julien Grall
@ 2020-01-22  1:34   ` Dario Faggioli
  2020-01-22 11:28   ` Durrant, Paul
                     ` (3 subsequent siblings)
  5 siblings, 0 replies; 42+ messages in thread
From: Dario Faggioli @ 2020-01-22  1:34 UTC (permalink / raw)
  To: Juergen Gross, xen-devel
  Cc: Kevin Tian, Stefano Stabellini, Julien Grall, Jun Nakajima,
	Wei Liu, Konrad Rzeszutek Wilk, George Dunlap, Andrew Cooper,
	Paul Durrant, Ian Jackson, Christopher Clark, Lukasz Hawrylko,
	Daniel De Graaf, Volodymyr Babchuk, Roger Pau Monné


[-- Attachment #1.1: Type: text/plain, Size: 639 bytes --]

On Tue, 2020-01-21 at 09:43 +0100, Juergen Gross wrote:
> 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 <jgross@suse.com>
>
sched-stuff:

Acked-by: Dario Faggioli <dfaggioli@suse.com>

Regards
-- 
Dario Faggioli, Ph.D
http://about.me/dario.faggioli
Virtualization Software Engineer
SUSE Labs, SUSE https://www.suse.com/
-------------------------------------------------------------------
<<This happens because _I_ choose it to happen!>> (Raistlin Majere)


[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 157 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Xen-devel] [PATCH v3 2/9] xen: split parameter related definitions in own header file
  2020-01-21  8:43 ` [Xen-devel] [PATCH v3 2/9] xen: split parameter related definitions in own header file Juergen Gross
  2020-01-21 13:00   ` Julien Grall
  2020-01-22  1:34   ` Dario Faggioli
@ 2020-01-22 11:28   ` Durrant, Paul
  2020-01-22 16:49   ` Jan Beulich
                     ` (2 subsequent siblings)
  5 siblings, 0 replies; 42+ messages in thread
From: Durrant, Paul @ 2020-01-22 11:28 UTC (permalink / raw)
  To: Juergen Gross, xen-devel
  Cc: Kevin Tian, Stefano Stabellini, Julien Grall, Jun Nakajima,
	Wei Liu, Konrad Rzeszutek Wilk, George Dunlap, Andrew Cooper,
	Ian Jackson, Christopher Clark, Dario Faggioli, Lukasz Hawrylko,
	Daniel De Graaf, Volodymyr Babchuk, Roger Pau Monné

> -----Original Message-----
> From: Juergen Gross <jgross@suse.com>
> Sent: 21 January 2020 08:43
> To: xen-devel@lists.xenproject.org
> Cc: Juergen Gross <jgross@suse.com>; Stefano Stabellini
> <sstabellini@kernel.org>; Julien Grall <julien@xen.org>; Volodymyr Babchuk
> <Volodymyr_Babchuk@epam.com>; Andrew Cooper <andrew.cooper3@citrix.com>;
> George Dunlap <George.Dunlap@eu.citrix.com>; Ian Jackson
> <ian.jackson@eu.citrix.com>; Jan Beulich <jbeulich@suse.com>; Konrad
> Rzeszutek Wilk <konrad.wilk@oracle.com>; Wei Liu <wl@xen.org>; Roger Pau
> Monné <roger.pau@citrix.com>; Durrant, Paul <pdurrant@amazon.co.uk>; Jun
> Nakajima <jun.nakajima@intel.com>; Kevin Tian <kevin.tian@intel.com>;
> Lukasz Hawrylko <lukasz.hawrylko@linux.intel.com>; Christopher Clark
> <christopher.w.clark@gmail.com>; Dario Faggioli <dfaggioli@suse.com>;
> Daniel De Graaf <dgdegra@tycho.nsa.gov>
> Subject: [PATCH v3 2/9] xen: split parameter related definitions in own
> header file
> 
> 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 <jgross@suse.com>

Acked-by: Paul Durrant <pdurrant@amazon.com>

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Xen-devel] [PATCH v3 2/9] xen: split parameter related definitions in own header file
  2020-01-21  8:43 ` [Xen-devel] [PATCH v3 2/9] xen: split parameter related definitions in own header file Juergen Gross
                     ` (2 preceding siblings ...)
  2020-01-22 11:28   ` Durrant, Paul
@ 2020-01-22 16:49   ` Jan Beulich
  2020-02-03  5:37   ` Tian, Kevin
  2020-02-03 12:13   ` Jan Beulich
  5 siblings, 0 replies; 42+ messages in thread
From: Jan Beulich @ 2020-01-22 16:49 UTC (permalink / raw)
  To: Juergen Gross
  Cc: Kevin Tian, Stefano Stabellini, Julien Grall, Wei Liu,
	Konrad Rzeszutek Wilk, George Dunlap, Andrew Cooper,
	Paul Durrant, Ian Jackson, Christopher Clark, Dario Faggioli,
	Lukasz Hawrylko, Jun Nakajima, xen-devel, Daniel De Graaf,
	Volodymyr Babchuk, Roger Pau Monné

On 21.01.2020 09:43, Juergen Gross wrote:
> 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 <jgross@suse.com>

x86:
Acked-by: Jan Beulich <jbeulich@suse.com>

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Xen-devel] [PATCH v3 0/9] Add hypervisor sysfs-like support
  2020-01-21  8:43 [Xen-devel] [PATCH v3 0/9] Add hypervisor sysfs-like support Juergen Gross
                   ` (8 preceding siblings ...)
  2020-01-21  8:43 ` [Xen-devel] [PATCH v3 9/9] xen: add runtime parameter access support to hypfs Juergen Gross
@ 2020-01-26 22:05 ` Rich Persaud
  2020-01-27  5:37   ` Jürgen Groß
  9 siblings, 1 reply; 42+ messages in thread
From: Rich Persaud @ 2020-01-26 22:05 UTC (permalink / raw)
  To: Juergen Gross
  Cc: Jason Andryuk, Daniel Smith, Stefano Stabellini,
	Marek Marczykowski-Górecki, xen-devel, Lars Kurth,
	Kevin Tian, Julien Grall, Konrad Rzeszutek Wilk,
	Christopher Clark, Dario Faggioli, Jun Nakajima, Wei Liu,
	George Dunlap, Andrew Cooper, Paul Durrant, Ian Jackson,
	Lukasz Hawrylko, Daniel De Graaf, Volodymyr Babchuk,
	Roger Pau Monné

On Jan 21, 2020, at 03:45, Juergen Gross <jgross@suse.com> wrote:
> 
> 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.

Is there a short summary of the most recent use cases for this feature and expected interactions with other Xen features (e.g. Panopticon Xen, security controls on information that is visible to guests, e.g. recent discussion on version number hiding). This would impact many subsystems.

Presumably Kconfig could enable/disable this optional feature and all dependencies, and the Xen toolstack would continue to function normally in its absence.

Rich
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Xen-devel] [PATCH v3 0/9] Add hypervisor sysfs-like support
  2020-01-26 22:05 ` [Xen-devel] [PATCH v3 0/9] Add hypervisor sysfs-like support Rich Persaud
@ 2020-01-27  5:37   ` Jürgen Groß
  0 siblings, 0 replies; 42+ messages in thread
From: Jürgen Groß @ 2020-01-27  5:37 UTC (permalink / raw)
  To: Rich Persaud
  Cc: Jason Andryuk, Daniel Smith, Stefano Stabellini,
	Marek Marczykowski-Górecki, xen-devel, Lars Kurth,
	Kevin Tian, Julien Grall, Konrad Rzeszutek Wilk,
	Christopher Clark, Dario Faggioli, Jun Nakajima, Wei Liu,
	George Dunlap, Andrew Cooper, Paul Durrant, Ian Jackson,
	Lukasz Hawrylko, Daniel De Graaf, Volodymyr Babchuk,
	Roger Pau Monné

On 26.01.20 23:05, Rich Persaud wrote:
> On Jan 21, 2020, at 03:45, Juergen Gross <jgross@suse.com> wrote:
>>
>> 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.
> 
> Is there a short summary of the most recent use cases for this feature and expected interactions with other Xen features (e.g. Panopticon Xen, security controls on information that is visible to guests, e.g. recent discussion on version number hiding). This would impact many subsystems.

In the first run access is permitted to dom0 only. Access to other
guests needs to be discussed.

Current use cases are just the buildinfo leafs including the .config
of the hypervisor, plus reading and writing runtime parameters.

I'd like to add per-cpupool parameters (like SMT per cpupool,
scheduling granularity) and maybe per-domain ones (e.g. mitigation
settings). Another area to cover would be debugging interfaces like
lock profiling, performance counters, ...

> Presumably Kconfig could enable/disable this optional feature and all dependencies, and the Xen toolstack would continue to function normally in its absence.

I'd rather go the other way round: have a detailed look which current
privileged interfaces (domctl, sysctl) can be replaced by the file
system and switch over to it with (where necessary) fine grained
access control. I think this is something to discuss at the next Xen
summit in summer (I have already registered a session for that
purpose).


Juergen


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Xen-devel] [PATCH v3 4/9] xen: add basic hypervisor filesystem support
  2020-01-21  8:43 ` [Xen-devel] [PATCH v3 4/9] xen: add basic hypervisor filesystem support Juergen Gross
@ 2020-01-31 15:50   ` Wei Liu
  2020-02-03  9:12     ` Jürgen Groß
  2020-02-03 15:07   ` Jan Beulich
  1 sibling, 1 reply; 42+ messages in thread
From: Wei Liu @ 2020-01-31 15:50 UTC (permalink / raw)
  To: Juergen Gross
  Cc: Stefano Stabellini, Julien Grall, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, xen-devel,
	Volodymyr Babchuk, Roger Pau Monné

On Tue, Jan 21, 2020 at 09:43:25AM +0100, Juergen Gross wrote:
[...]
> 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 <xen/lib.h>

This should come after hypfs.h.

If it has come first it probably means one of the headers below hasn't
included it properly?

> +#include <xen/err.h>
> +#include <xen/guest_access.h>
> +#include <xen/hypercall.h>
> +#include <xen/hypfs.h>
> +#include <xen/rwlock.h>
> +#include <public/hypfs.h>

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Xen-devel] [PATCH v3 5/9] libs: add libxenhypfs
  2020-01-21  8:43 ` [Xen-devel] [PATCH v3 5/9] libs: add libxenhypfs Juergen Gross
@ 2020-01-31 15:57   ` Wei Liu
  2020-02-03  9:14     ` Jürgen Groß
  0 siblings, 1 reply; 42+ messages in thread
From: Wei Liu @ 2020-01-31 15:57 UTC (permalink / raw)
  To: Juergen Gross
  Cc: Stefano Stabellini, Julien Grall, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, xen-devel

On Tue, Jan 21, 2020 at 09:43:26AM +0100, Juergen Gross wrote:
> Add the new library libxenhypfs for access to the hypervisor filesystem.
> 
> Signed-off-by: Juergen Gross <jgross@suse.com>

I've only skimmed read it. The code looks sensible.

One minor comment.

> 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

Need to list libz here?

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Xen-devel] [PATCH v3 6/9] tools: add xenfs tool
  2020-01-21  8:43 ` [Xen-devel] [PATCH v3 6/9] tools: add xenfs tool Juergen Gross
@ 2020-01-31 15:59   ` Wei Liu
  0 siblings, 0 replies; 42+ messages in thread
From: Wei Liu @ 2020-01-31 15:59 UTC (permalink / raw)
  To: Juergen Gross
  Cc: Stefano Stabellini, Julien Grall, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, xen-devel

On Tue, Jan 21, 2020 at 09:43:27AM +0100, Juergen Gross wrote:
> Add the xenfs tool for accessing the hypervisor filesystem.
> 
> Signed-off-by: Juergen Gross <jgross@suse.com>

Acked-by: Wei Liu <wl@xen.org>

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Xen-devel] [PATCH v3 2/9] xen: split parameter related definitions in own header file
  2020-01-21  8:43 ` [Xen-devel] [PATCH v3 2/9] xen: split parameter related definitions in own header file Juergen Gross
                     ` (3 preceding siblings ...)
  2020-01-22 16:49   ` Jan Beulich
@ 2020-02-03  5:37   ` Tian, Kevin
  2020-02-03 12:13   ` Jan Beulich
  5 siblings, 0 replies; 42+ messages in thread
From: Tian, Kevin @ 2020-02-03  5:37 UTC (permalink / raw)
  To: Juergen Gross, xen-devel
  Cc: Stefano Stabellini, Julien Grall, Nakajima, Jun, Wei Liu,
	Konrad Rzeszutek Wilk, George Dunlap, Andrew Cooper,
	Paul Durrant, Ian Jackson, Christopher Clark, Dario Faggioli,
	Lukasz Hawrylko, Daniel De Graaf, Volodymyr Babchuk,
	Roger Pau Monné

> From: Juergen Gross <jgross@suse.com>
> Sent: Tuesday, January 21, 2020 4:43 PM
> 
> 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 <jgross@suse.com>

Reviewed-by: Kevin Tian <kevin.tian@intel.com>

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Xen-devel] [PATCH v3 4/9] xen: add basic hypervisor filesystem support
  2020-01-31 15:50   ` Wei Liu
@ 2020-02-03  9:12     ` Jürgen Groß
  0 siblings, 0 replies; 42+ messages in thread
From: Jürgen Groß @ 2020-02-03  9:12 UTC (permalink / raw)
  To: Wei Liu
  Cc: Stefano Stabellini, Julien Grall, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, xen-devel,
	Volodymyr Babchuk, Roger Pau Monné

On 31.01.20 16:50, Wei Liu wrote:
> On Tue, Jan 21, 2020 at 09:43:25AM +0100, Juergen Gross wrote:
> [...]
>> 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 <xen/lib.h>
> 
> This should come after hypfs.h.
> 
> If it has come first it probably means one of the headers below hasn't
> included it properly?

I'll move it, as the build will still be fine.


Juergen

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Xen-devel] [PATCH v3 5/9] libs: add libxenhypfs
  2020-01-31 15:57   ` Wei Liu
@ 2020-02-03  9:14     ` Jürgen Groß
  2020-06-03  6:10       ` Olaf Hering
  0 siblings, 1 reply; 42+ messages in thread
From: Jürgen Groß @ 2020-02-03  9:14 UTC (permalink / raw)
  To: Wei Liu
  Cc: Stefano Stabellini, Julien Grall, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, xen-devel

On 31.01.20 16:57, Wei Liu wrote:
> On Tue, Jan 21, 2020 at 09:43:26AM +0100, Juergen Gross wrote:
>> Add the new library libxenhypfs for access to the hypervisor filesystem.
>>
>> Signed-off-by: Juergen Gross <jgross@suse.com>
> 
> I've only skimmed read it. The code looks sensible.
> 
> One minor comment.
> 
>> 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
> 
> Need to list libz here?

Probably, yes.


Juergen

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Xen-devel] [PATCH v3 3/9] docs: add feature document for Xen hypervisor sysfs-like support
  2020-01-21 14:17     ` Jürgen Groß
@ 2020-02-03 10:29       ` Julien Grall
  0 siblings, 0 replies; 42+ messages in thread
From: Julien Grall @ 2020-02-03 10:29 UTC (permalink / raw)
  To: Jürgen Groß, xen-devel
  Cc: Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson



On 21/01/2020 14:17, Jürgen Groß wrote:
> On 21.01.20 14:14, Julien Grall wrote:
>> However, I am not sure what are actually the tags? Do you have a 
>> concrete example how they can be used?
> 
> I'll add this one:
> 
> /cpu-bugs/active-pv/xpti (0|1) [w,X86,PV]
> 
>>
>>> +
>>> +* 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.
>>
>> How about Arm64? Also, if it is support by both arm64 and arm32, 
>> should we use ARM or ARM32,ARM64?
> 
> ARM64 should be added and I'd suggest to use "ARM" instead of
> "ARM32,ARM64".

I am happy with that.

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Xen-devel] [PATCH v3 2/9] xen: split parameter related definitions in own header file
  2020-01-21  8:43 ` [Xen-devel] [PATCH v3 2/9] xen: split parameter related definitions in own header file Juergen Gross
                     ` (4 preceding siblings ...)
  2020-02-03  5:37   ` Tian, Kevin
@ 2020-02-03 12:13   ` Jan Beulich
  5 siblings, 0 replies; 42+ messages in thread
From: Jan Beulich @ 2020-02-03 12:13 UTC (permalink / raw)
  To: Juergen Gross, xen-devel
  Cc: Kevin Tian, Stefano Stabellini, Julien Grall, Wei Liu,
	Konrad Rzeszutek Wilk, George Dunlap, Andrew Cooper,
	Paul Durrant, Ian Jackson, Christopher Clark, Dario Faggioli,
	Lukasz Hawrylko, Jun Nakajima, Daniel De Graaf,
	Volodymyr Babchuk, Roger Pau Monné

On 21.01.2020 09:43, Juergen Gross wrote:
> 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 <jgross@suse.com>

There was some re-basing necessary here, which I hope I didn't screw
up. I also decided to commit this despite, from a strictly formal
perspective, there still being missing acks here, based on this
being an entirely mechanical change to those files, and on the
grounds that further re-basing would likely turn out to be needed
with further delays here.

Jan

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Xen-devel] [PATCH v3 1/9] xen: add a generic way to include binary files as variables
  2020-01-21  8:43 ` [Xen-devel] [PATCH v3 1/9] xen: add a generic way to include binary files as variables Juergen Gross
@ 2020-02-03 13:39   ` Jan Beulich
  2020-02-03 14:02     ` Jürgen Groß
  0 siblings, 1 reply; 42+ messages in thread
From: Jan Beulich @ 2020-02-03 13:39 UTC (permalink / raw)
  To: Juergen Gross
  Cc: Stefano Stabellini, Julien Grall, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, xen-devel,
	Daniel De Graaf

On 21.01.2020 09:43, Juergen Gross wrote:
> --- /dev/null
> +++ b/xen/tools/binfile
> @@ -0,0 +1,29 @@
> +#!/bin/sh
> +# usage: binfile [-i] <target-src.S> <binary-file> <varname>
> +# -i     add to .init.rodata (default: .rodata) section
> +
> +[ "$1" = "-i" ] && {
> +    shift
> +    section=".init"
> +}
> +
> +target=$1
> +binsource=$2
> +varname=$3
> +
> +cat <<EOF >$target
> +#include <asm/asm_defns.h>
> +
> +        .section $section.rodata, "a", %progbits
> +
> +        .global $varname
> +$varname:
> +        .incbin "$binsource"
> +.Lend:
> +
> +        .type $varname, %object
> +        .size $varname, . - $varname

I'd prefer if you used .Lend here as well.

I wonder whether, right from the beginning, there wouldn't better
be a way to also request better than byte alignment for such a
blob.

> --- 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

Doesn't objcopy provide a means to convert a binary blob into
an ELF object containing the binary data from the input file?
If so, why involve the assembler and an intermediate file here?

Jan

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Xen-devel] [PATCH v3 1/9] xen: add a generic way to include binary files as variables
  2020-02-03 13:39   ` Jan Beulich
@ 2020-02-03 14:02     ` Jürgen Groß
  2020-02-03 15:18       ` Jan Beulich
  0 siblings, 1 reply; 42+ messages in thread
From: Jürgen Groß @ 2020-02-03 14:02 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Stefano Stabellini, Julien Grall, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, xen-devel,
	Daniel De Graaf

On 03.02.20 14:39, Jan Beulich wrote:
> On 21.01.2020 09:43, Juergen Gross wrote:
>> --- /dev/null
>> +++ b/xen/tools/binfile
>> @@ -0,0 +1,29 @@
>> +#!/bin/sh
>> +# usage: binfile [-i] <target-src.S> <binary-file> <varname>
>> +# -i     add to .init.rodata (default: .rodata) section
>> +
>> +[ "$1" = "-i" ] && {
>> +    shift
>> +    section=".init"
>> +}
>> +
>> +target=$1
>> +binsource=$2
>> +varname=$3
>> +
>> +cat <<EOF >$target
>> +#include <asm/asm_defns.h>
>> +
>> +        .section $section.rodata, "a", %progbits
>> +
>> +        .global $varname
>> +$varname:
>> +        .incbin "$binsource"
>> +.Lend:
>> +
>> +        .type $varname, %object
>> +        .size $varname, . - $varname
> 
> I'd prefer if you used .Lend here as well.

Okay.

> I wonder whether, right from the beginning, there wouldn't better
> be a way to also request better than byte alignment for such a
> blob.

I can add that. What about "-a <n>" for 2^n alignment?

> 
>> --- 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
> 
> Doesn't objcopy provide a means to convert a binary blob into
> an ELF object containing the binary data from the input file?
> If so, why involve the assembler and an intermediate file here?

I can see how to add a symbol for that purpose using a dedicated section
for each blob, but how to add the size information of the blob?

In the end I just followed commit 8d5671eb31e4bf for the inclusion of
the blob.


Juergen

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Xen-devel] [PATCH v3 4/9] xen: add basic hypervisor filesystem support
  2020-01-21  8:43 ` [Xen-devel] [PATCH v3 4/9] xen: add basic hypervisor filesystem support Juergen Gross
  2020-01-31 15:50   ` Wei Liu
@ 2020-02-03 15:07   ` Jan Beulich
  2020-02-04  6:43     ` Jürgen Groß
  1 sibling, 1 reply; 42+ messages in thread
From: Jan Beulich @ 2020-02-03 15:07 UTC (permalink / raw)
  To: Juergen Gross
  Cc: Stefano Stabellini, Julien Grall, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, xen-devel,
	Volodymyr Babchuk, Roger Pau Monné

On 21.01.2020 09:43, Juergen Gross wrote:
> ---
>  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(+)

Even if it's just two structures that you have in the public
header, your assertion of the interface being guest bitness
agnostic should be accompanied by actual proof, i.e. addition
to xen/include/xlat.lst.

> +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);

Would DIRENTRY_SIZE() perhaps better include the "+ 1"?

> +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;
> +}

While this and its two siblings have no caller, the one above
doesn't even have a declaration in the header file. What is
this intended to be used for (from external callers)?

I also think the "nofault" aspect could do with discussing in
the commit message - it seems quite odd to me.

> +static int hypfs_get_path_user(char *buf, XEN_GUEST_HANDLE_PARAM(void) uaddr,
> +                               unsigned long len)

For consistency with naming elsewhere as well as uaddr here -
ulen?

> +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;

Don't these two need switching around, to make sure /a/b/c/
doesn't match a non-dir /a/b/c ?

> +    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,

A hard tab slipped in here.

> +                                                 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;

const?

> +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;

So you return "success" even if the operation didn't complete
successfully. This isn't very nice, plus ...

> +    guest_handle_add_offset(uaddr, sizeof(e));
> +
> +    ret = entry->read(entry, uaddr);

... how is the caller to know whether direntry was at least
copied if this then fails?

> +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;

Silent truncation?

> +    buf = xzalloc_array(char, ulen);

Why the z variant?

> +    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;

And possible further silent truncation? And if the incoming
buffer has no nul byte at ulen-1, you'll then ...

> +    memcpy(leaf->write_ptr, buf, ulen);

... produce a strange concatenation of new and tail of old
contents?

Anyway, this and ...

> + out:
> +    xfree(buf);
> +    return ret;
> +}
> +
> +int hypfs_write_bool(struct hypfs_entry_leaf *leaf,
> +                     XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned long ulen)
> +{

... this function aren't very helpful to review without there
being a caller. Could these be introduced at the time a first
caller appears?

> +    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;

Is this restriction really necessary? Setting e.g. a 4-byte
field from 1-byte input is no problem at all. This being for
booleans I anyway wonder why input might be helpful to have
larger than a single byte. But maybe all of this is again a
result of not seeing what a user of the function would look
like.

> +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;

EINVAL or EOPNOTSUPP please. ENOSYS should be used only for not
implemented top level functions.

> --- /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

For this and the accompanying XEN_HYPFS_OP_get_version, at least
the doc added by patch 3 could actually do with mentioning the
intentions you have with this.

> +/* 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

Meaning I can e.g. have a gzip-ed string or bool (or even dir)?
If this is just for "blob", why have separate fields instead of
e.g. BLOB_RAW and BLOB_GZIP or some such?

Also - why 4 digits in the constants when the fields are uint8_t?
Since these are enum-like, I even wonder if hex is warranted
here.

> +    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];
> +};

The interaction of the last two fields may want spelling out:
I _assume_ name[] is nul-terminated, and off_next exists to
potentially skip trailing padding?

> +/*
> + * 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.

What specifically this means for a dir would be nice to be spelled
out.

> + * 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

This one indeed accesses only the actual data (contents) of the
referenced entry. XEN_HYPFS_OP_read_contents hands back also
the dir entry. Should the latter then better be named just
XEN_HYPFS_OP_read?

> --- 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,

Do you anticipate this parameter to be used for other than path
names? If not, perhaps better XEN_GUEST_HANDLE_PARAM(const_char)?

> --- /dev/null
> +++ b/xen/include/xen/hypfs.h
> @@ -0,0 +1,89 @@
> +#ifndef __XEN_HYPFS_H__
> +#define __XEN_HYPFS_H__
> +
> +#include <xen/list.h>
> +#include <xen/string.h>
> +#include <public/hypfs.h>
> +
> +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,                       \
> +    }

So you've got such helper macros for dir, string, and uint. Why
not e.g. int and bool?

> +
> +
> +extern struct hypfs_entry_dir hypfs_root;

No double blank lines please.

> +struct hypfs_entry *hypfs_get_entry(const char *path);

Does the only caller really need a non-const return type? Even
hypfs_write() doesn't look to modify what its leaf parameter
points at.

And is there indeed an expectation for this to be used from
outside of the source file it's defined in?

Jan

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Xen-devel] [PATCH v3 1/9] xen: add a generic way to include binary files as variables
  2020-02-03 14:02     ` Jürgen Groß
@ 2020-02-03 15:18       ` Jan Beulich
  0 siblings, 0 replies; 42+ messages in thread
From: Jan Beulich @ 2020-02-03 15:18 UTC (permalink / raw)
  To: Jürgen Groß
  Cc: Stefano Stabellini, Julien Grall, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, xen-devel,
	Daniel De Graaf

On 03.02.2020 15:02, Jürgen Groß wrote:
> On 03.02.20 14:39, Jan Beulich wrote:
>> On 21.01.2020 09:43, Juergen Gross wrote:
>>> --- /dev/null
>>> +++ b/xen/tools/binfile
>>> @@ -0,0 +1,29 @@
>>> +#!/bin/sh
>>> +# usage: binfile [-i] <target-src.S> <binary-file> <varname>
>>> +# -i     add to .init.rodata (default: .rodata) section
>>> +
>>> +[ "$1" = "-i" ] && {
>>> +    shift
>>> +    section=".init"
>>> +}
>>> +
>>> +target=$1
>>> +binsource=$2
>>> +varname=$3
>>> +
>>> +cat <<EOF >$target
>>> +#include <asm/asm_defns.h>
>>> +
>>> +        .section $section.rodata, "a", %progbits
>>> +
>>> +        .global $varname
>>> +$varname:
>>> +        .incbin "$binsource"
>>> +.Lend:
>>> +
>>> +        .type $varname, %object
>>> +        .size $varname, . - $varname
>>
>> I'd prefer if you used .Lend here as well.
> 
> Okay.
> 
>> I wonder whether, right from the beginning, there wouldn't better
>> be a way to also request better than byte alignment for such a
>> blob.
> 
> I can add that. What about "-a <n>" for 2^n alignment?

SGTM.

>>> --- 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
>>
>> Doesn't objcopy provide a means to convert a binary blob into
>> an ELF object containing the binary data from the input file?
>> If so, why involve the assembler and an intermediate file here?
> 
> I can see how to add a symbol for that purpose using a dedicated section
> for each blob, but how to add the size information of the blob?

Hmm, right. It would be doable, but perhaps indeed not very nice.
Fair enough then.

Jan

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Xen-devel] [PATCH v3 7/9] xen: provide version information in hypfs
  2020-01-21  8:43 ` [Xen-devel] [PATCH v3 7/9] xen: provide version information in hypfs Juergen Gross
@ 2020-02-03 17:02   ` Jan Beulich
  2020-02-04  6:44     ` Jürgen Groß
  0 siblings, 1 reply; 42+ messages in thread
From: Jan Beulich @ 2020-02-03 17:02 UTC (permalink / raw)
  To: Juergen Gross
  Cc: Stefano Stabellini, Julien Grall, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, xen-devel

On 21.01.2020 09:43, Juergen Gross wrote:
> 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 <jgross@suse.com>

Reviewed-by: Jan Beulich <jbeulich@suse.com>
with on suggestion:

> @@ -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");

Please consider making all of the above __read_mostly.

Jan

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Xen-devel] [PATCH v3 4/9] xen: add basic hypervisor filesystem support
  2020-02-03 15:07   ` Jan Beulich
@ 2020-02-04  6:43     ` Jürgen Groß
  2020-02-04  8:48       ` Jan Beulich
  0 siblings, 1 reply; 42+ messages in thread
From: Jürgen Groß @ 2020-02-04  6:43 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Stefano Stabellini, Julien Grall, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, xen-devel,
	Volodymyr Babchuk, Roger Pau Monné

On 03.02.20 16:07, Jan Beulich wrote:
> On 21.01.2020 09:43, Juergen Gross wrote:
>> ---
>>   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(+)
> 
> Even if it's just two structures that you have in the public
> header, your assertion of the interface being guest bitness
> agnostic should be accompanied by actual proof, i.e. addition
> to xen/include/xlat.lst.

Okay.

> 
>> +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);
> 
> Would DIRENTRY_SIZE() perhaps better include the "+ 1"?

Good idea.

> 
>> +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;
>> +}
> 
> While this and its two siblings have no caller, the one above
> doesn't even have a declaration in the header file. What is
> this intended to be used for (from external callers)?

Oh, this seems to be a leftover from development phase. I'll remove
it.

> I also think the "nofault" aspect could do with discussing in
> the commit message - it seems quite odd to me.

I realized I was repeating the same code pattern multiple times, so
I decidied to have a common function for it. Will add something to the
commit message.

> 
>> +static int hypfs_get_path_user(char *buf, XEN_GUEST_HANDLE_PARAM(void) uaddr,
>> +                               unsigned long len)
> 
> For consistency with naming elsewhere as well as uaddr here -
> ulen?

Okay.

> 
>> +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;
> 
> Don't these two need switching around, to make sure /a/b/c/
> doesn't match a non-dir /a/b/c ?

Oh, indeed.

> 
>> +    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,
> 
> A hard tab slipped in here.

Sorry for that.

> 
>> +                                                 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;
> 
> const?

Yes.

> 
>> +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;
> 
> So you return "success" even if the operation didn't complete
> successfully. This isn't very nice, plus ...

The direntry contains the needed size. The caller should know the
size he passed to Xen.

> 
>> +    guest_handle_add_offset(uaddr, sizeof(e));
>> +
>> +    ret = entry->read(entry, uaddr);
> 
> ... how is the caller to know whether direntry was at least
> copied if this then fails?

Is this really important? Normally -EFAULT should just not happen. In
case it does I don't think the caller can make real use of the direntry.

> 
>> +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;
> 
> Silent truncation?

Hmm, true. I'll modify it to return an error in that case.

>> +    buf = xzalloc_array(char, ulen);
> 
> Why the z variant?

Okay, will use xmalloc().

> 
>> +    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;
> 
> And possible further silent truncation? And if the incoming
> buffer has no nul byte at ulen-1, you'll then ...
> 
>> +    memcpy(leaf->write_ptr, buf, ulen);
> 
> ... produce a strange concatenation of new and tail of old
> contents?

Will rework by returning an error if the size is too large or there is
no terminating nul byte.

> 
> Anyway, this and ...
> 
>> + out:
>> +    xfree(buf);
>> +    return ret;
>> +}
>> +
>> +int hypfs_write_bool(struct hypfs_entry_leaf *leaf,
>> +                     XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned long ulen)
>> +{
> 
> ... this function aren't very helpful to review without there
> being a caller. Could these be introduced at the time a first
> caller appears?

Of course. Question is where to stop. I wanted to have the basic hypfs
support in one patch. Are you fine with just those two functions being
moved to the runtime parameter patch?

> 
>> +    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;
> 
> Is this restriction really necessary? Setting e.g. a 4-byte
> field from 1-byte input is no problem at all. This being for
> booleans I anyway wonder why input might be helpful to have
> larger than a single byte. But maybe all of this is again a
> result of not seeing what a user of the function would look
> like.

I wanted to have as little functionality as possible in the hypervisor.
It is no problem for the library to pass a properly sized buffer.

Allowing larger variables for booleans is just a consequence of the
hypervisor parameters allowing that.

> 
>> +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;
> 
> EINVAL or EOPNOTSUPP please. ENOSYS should be used only for not
> implemented top level functions.

Okay, will use EOPNOTSUPP.

> 
>> --- /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
> 
> For this and the accompanying XEN_HYPFS_OP_get_version, at least
> the doc added by patch 3 could actually do with mentioning the
> intentions you have with this.

Okay.

> 
>> +/* 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
> 
> Meaning I can e.g. have a gzip-ed string or bool (or even dir)?
> If this is just for "blob", why have separate fields instead of
> e.g. BLOB_RAW and BLOB_GZIP or some such?

gzip-ed string or blob are the primary targets.

Maybe we want to have other encoding s later (Andrew asked for that
possibility when I posted the patch for retrieving the .config file
contents early last year).

> Also - why 4 digits in the constants when the fields are uint8_t?
> Since these are enum-like, I even wonder if hex is warranted
> here.

I'm fine with switching to plain integers.

> 
>> +    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];
>> +};
> 
> The interaction of the last two fields may want spelling out:
> I _assume_ name[] is nul-terminated, and off_next exists to
> potentially skip trailing padding?

Yes. Will add a comment.

> 
>> +/*
>> + * 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.
> 
> What specifically this means for a dir would be nice to be spelled
> out.

Okay.

> 
>> + * 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
> 
> This one indeed accesses only the actual data (contents) of the
> referenced entry. XEN_HYPFS_OP_read_contents hands back also
> the dir entry. Should the latter then better be named just
> XEN_HYPFS_OP_read?

Yes, this might be better.

> 
>> --- 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,
> 
> Do you anticipate this parameter to be used for other than path
> names? If not, perhaps better XEN_GUEST_HANDLE_PARAM(const_char)?

Yes, I think this can be changed.

> 
>> --- /dev/null
>> +++ b/xen/include/xen/hypfs.h
>> @@ -0,0 +1,89 @@
>> +#ifndef __XEN_HYPFS_H__
>> +#define __XEN_HYPFS_H__
>> +
>> +#include <xen/list.h>
>> +#include <xen/string.h>
>> +#include <public/hypfs.h>
>> +
>> +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,                       \
>> +    }
> 
> So you've got such helper macros for dir, string, and uint. Why
> not e.g. int and bool?

There are no users in my series yet.

> 
>> +
>> +
>> +extern struct hypfs_entry_dir hypfs_root;
> 
> No double blank lines please.

Oh, sorry.

> 
>> +struct hypfs_entry *hypfs_get_entry(const char *path);
> 
> Does the only caller really need a non-const return type? Even
> hypfs_write() doesn't look to modify what its leaf parameter
> points at.

This might change when support for dynamically allocated strings or
blobs is added (I have no plans to do this right now, but its easy
to think about the need).

> 
> And is there indeed an expectation for this to be used from
> outside of the source file it's defined in?

Yes. As soon as support for e.g. per-domain or per-cpupool nodes is
added this will be needed.


Juergen


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Xen-devel] [PATCH v3 7/9] xen: provide version information in hypfs
  2020-02-03 17:02   ` Jan Beulich
@ 2020-02-04  6:44     ` Jürgen Groß
  0 siblings, 0 replies; 42+ messages in thread
From: Jürgen Groß @ 2020-02-04  6:44 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Stefano Stabellini, Julien Grall, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, xen-devel

On 03.02.20 18:02, Jan Beulich wrote:
> On 21.01.2020 09:43, Juergen Gross wrote:
>> 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 <jgross@suse.com>
> 
> Reviewed-by: Jan Beulich <jbeulich@suse.com>
> with on suggestion:
> 
>> @@ -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");
> 
> Please consider making all of the above __read_mostly.

Okay.


Juergen

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Xen-devel] [PATCH v3 4/9] xen: add basic hypervisor filesystem support
  2020-02-04  6:43     ` Jürgen Groß
@ 2020-02-04  8:48       ` Jan Beulich
  2020-02-04  9:21         ` Jürgen Groß
  0 siblings, 1 reply; 42+ messages in thread
From: Jan Beulich @ 2020-02-04  8:48 UTC (permalink / raw)
  To: Jürgen Groß
  Cc: Stefano Stabellini, Julien Grall, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, xen-devel,
	Volodymyr Babchuk, Roger Pau Monné

On 04.02.2020 07:43, Jürgen Groß wrote:
> On 03.02.20 16:07, Jan Beulich wrote:
>> On 21.01.2020 09:43, Juergen Gross wrote:
>>> +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;
>>
>> So you return "success" even if the operation didn't complete
>> successfully. This isn't very nice, plus ...
> 
> The direntry contains the needed size. The caller should know the
> size he passed to Xen.
> 
>>
>>> +    guest_handle_add_offset(uaddr, sizeof(e));
>>> +
>>> +    ret = entry->read(entry, uaddr);
>>
>> ... how is the caller to know whether direntry was at least
>> copied if this then fails?
> 
> Is this really important? Normally -EFAULT should just not happen. In
> case it does I don't think the caller can make real use of the direntry.

"Important" has various possible meanings. The success/failure
indication to the caller should at least be rational. "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" is fine to be stated in the public header,
but I think this wants to be -ENOBUFS then, not 0 (success).

>> Anyway, this and ...
>>
>>> + out:
>>> +    xfree(buf);
>>> +    return ret;
>>> +}
>>> +
>>> +int hypfs_write_bool(struct hypfs_entry_leaf *leaf,
>>> +                     XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned long ulen)
>>> +{
>>
>> ... this function aren't very helpful to review without there
>> being a caller. Could these be introduced at the time a first
>> caller appears?
> 
> Of course. Question is where to stop. I wanted to have the basic hypfs
> support in one patch. Are you fine with just those two functions being
> moved to the runtime parameter patch?

Let me put it this way: For anything the patch adds but there's
no usage at all (i.e. not even in a macro, where at least the
usage intentions get sufficiently clarified), the description
should cover for this lack of sufficient context. Therefore I'd
also be fine with the two functions remaining here, as long as
readers (reviewers) can understand the intentions. It might
still be _easier_ for everyone to have them in a later patch.
But then the same still goes for other functions that have no
users here. (The helper macros HYPFS_*_INIT(), otoh, are clear
enough the way they are imo, and hence are fine to remain, plus
they serve as usage explanation for hypfs_read_{leaf,dir}(),
which as it looks would otherwise too be orphaned.)

>>> +    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;
>>
>> Is this restriction really necessary? Setting e.g. a 4-byte
>> field from 1-byte input is no problem at all. This being for
>> booleans I anyway wonder why input might be helpful to have
>> larger than a single byte. But maybe all of this is again a
>> result of not seeing what a user of the function would look
>> like.
> 
> I wanted to have as little functionality as possible in the hypervisor.
> It is no problem for the library to pass a properly sized buffer.
> 
> Allowing larger variables for booleans is just a consequence of the
> hypervisor parameters allowing that.

But the caller shouldn't be concerned of the hypervisor
implementation detail of what the chose width is. Over time we
e.g. convert int (along with bool_t) to bool when it's used in
a boolean way. This should not result in the caller needing to
change, despite the width change of the variable.

>>> --- /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
>>
>> For this and the accompanying XEN_HYPFS_OP_get_version, at least
>> the doc added by patch 3 could actually do with mentioning the
>> intentions you have with this.
> 
> Okay.
> 
>>
>>> +/* 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
>>
>> Meaning I can e.g. have a gzip-ed string or bool (or even dir)?
>> If this is just for "blob", why have separate fields instead of
>> e.g. BLOB_RAW and BLOB_GZIP or some such?
> 
> gzip-ed string or blob are the primary targets.
> 
> Maybe we want to have other encoding s later (Andrew asked for that
> possibility when I posted the patch for retrieving the .config file
> contents early last year).

To me it would seem preferable if the contents of a blob
identified itself as to its format. But since this leaves
room for ambiguities I accept that the format needs
specifying. However, to me a gzip-ed string is as good as a
gzip-ed blob, and hence I still think sub-dividing "blob" is
the way to go, with no separate "encoding". Otherwise at the
very least a comment here would need adding to clarify what
combinations are valid / to be expected by callers.

>>> +#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,                       \
>>> +    }
>>
>> So you've got such helper macros for dir, string, and uint. Why
>> not e.g. int and bool?
> 
> There are no users in my series yet.

Hmm, as per above strictly speaking it is this patch which
matters, not the entire series. Hence I think you either want
to supply a full set of helper macros here, or introduce the
ones actually needed in the patches where they get first used.

>>> +struct hypfs_entry *hypfs_get_entry(const char *path);
>>
>> Does the only caller really need a non-const return type? Even
>> hypfs_write() doesn't look to modify what its leaf parameter
>> points at.
> 
> This might change when support for dynamically allocated strings or
> blobs is added (I have no plans to do this right now, but its easy
> to think about the need).
> 
>>
>> And is there indeed an expectation for this to be used from
>> outside of the source file it's defined in?
> 
> Yes. As soon as support for e.g. per-domain or per-cpupool nodes is
> added this will be needed.

Until then, make the function both static and return ptr-to-const?
Such that when this changes, the need for either can actually be
seen?

Jan

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Xen-devel] [PATCH v3 4/9] xen: add basic hypervisor filesystem support
  2020-02-04  8:48       ` Jan Beulich
@ 2020-02-04  9:21         ` Jürgen Groß
  2020-02-04  9:58           ` Jan Beulich
  0 siblings, 1 reply; 42+ messages in thread
From: Jürgen Groß @ 2020-02-04  9:21 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Stefano Stabellini, Julien Grall, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, xen-devel,
	Volodymyr Babchuk, Roger Pau Monné

On 04.02.20 09:48, Jan Beulich wrote:
> On 04.02.2020 07:43, Jürgen Groß wrote:
>> On 03.02.20 16:07, Jan Beulich wrote:
>>> On 21.01.2020 09:43, Juergen Gross wrote:
>>>> +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;
>>>
>>> So you return "success" even if the operation didn't complete
>>> successfully. This isn't very nice, plus ...
>>
>> The direntry contains the needed size. The caller should know the
>> size he passed to Xen.
>>
>>>
>>>> +    guest_handle_add_offset(uaddr, sizeof(e));
>>>> +
>>>> +    ret = entry->read(entry, uaddr);
>>>
>>> ... how is the caller to know whether direntry was at least
>>> copied if this then fails?
>>
>> Is this really important? Normally -EFAULT should just not happen. In
>> case it does I don't think the caller can make real use of the direntry.
> 
> "Important" has various possible meanings. The success/failure
> indication to the caller should at least be rational. "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" is fine to be stated in the public header,
> but I think this wants to be -ENOBUFS then, not 0 (success).

I would be fine with this, but this contradicts your previous demand
not to enumerate the possible failure cases, which would be essential
for this case.

> 
>>> Anyway, this and ...
>>>
>>>> + out:
>>>> +    xfree(buf);
>>>> +    return ret;
>>>> +}
>>>> +
>>>> +int hypfs_write_bool(struct hypfs_entry_leaf *leaf,
>>>> +                     XEN_GUEST_HANDLE_PARAM(void) uaddr, unsigned long ulen)
>>>> +{
>>>
>>> ... this function aren't very helpful to review without there
>>> being a caller. Could these be introduced at the time a first
>>> caller appears?
>>
>> Of course. Question is where to stop. I wanted to have the basic hypfs
>> support in one patch. Are you fine with just those two functions being
>> moved to the runtime parameter patch?
> 
> Let me put it this way: For anything the patch adds but there's
> no usage at all (i.e. not even in a macro, where at least the
> usage intentions get sufficiently clarified), the description
> should cover for this lack of sufficient context. Therefore I'd
> also be fine with the two functions remaining here, as long as
> readers (reviewers) can understand the intentions. It might
> still be _easier_ for everyone to have them in a later patch.
> But then the same still goes for other functions that have no
> users here. (The helper macros HYPFS_*_INIT(), otoh, are clear
> enough the way they are imo, and hence are fine to remain, plus
> they serve as usage explanation for hypfs_read_{leaf,dir}(),
> which as it looks would otherwise too be orphaned.)

Fair enough.

> 
>>>> +    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;
>>>
>>> Is this restriction really necessary? Setting e.g. a 4-byte
>>> field from 1-byte input is no problem at all. This being for
>>> booleans I anyway wonder why input might be helpful to have
>>> larger than a single byte. But maybe all of this is again a
>>> result of not seeing what a user of the function would look
>>> like.
>>
>> I wanted to have as little functionality as possible in the hypervisor.
>> It is no problem for the library to pass a properly sized buffer.
>>
>> Allowing larger variables for booleans is just a consequence of the
>> hypervisor parameters allowing that.
> 
> But the caller shouldn't be concerned of the hypervisor
> implementation detail of what the chose width is. Over time we
> e.g. convert int (along with bool_t) to bool when it's used in
> a boolean way. This should not result in the caller needing to
> change, despite the width change of the variable.

This is basically a consequence of now passing binary values to and from
the hypervisor.

The normal way of handling this (as can be seen in libxenhypfs) is to
query the hypervisor for the size of the value (no matter whether its
int, uint or bool) and then to do the conversion between ASCII and the
binary value at the caller's side.

> 
>>>> --- /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
>>>
>>> For this and the accompanying XEN_HYPFS_OP_get_version, at least
>>> the doc added by patch 3 could actually do with mentioning the
>>> intentions you have with this.
>>
>> Okay.
>>
>>>
>>>> +/* 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
>>>
>>> Meaning I can e.g. have a gzip-ed string or bool (or even dir)?
>>> If this is just for "blob", why have separate fields instead of
>>> e.g. BLOB_RAW and BLOB_GZIP or some such?
>>
>> gzip-ed string or blob are the primary targets.
>>
>> Maybe we want to have other encoding s later (Andrew asked for that
>> possibility when I posted the patch for retrieving the .config file
>> contents early last year).
> 
> To me it would seem preferable if the contents of a blob
> identified itself as to its format. But since this leaves
> room for ambiguities I accept that the format needs
> specifying. However, to me a gzip-ed string is as good as a
> gzip-ed blob, and hence I still think sub-dividing "blob" is
> the way to go, with no separate "encoding". Otherwise at the
> very least a comment here would need adding to clarify what
> combinations are valid / to be expected by callers.

libxenhypfs is able to handle all possible combinations. I just don't
think some of the combinations are making sense (gzip-ing a binary
value of 4 bytes e.g. is nonsense).

OTOH in case we'll add large arrays of longs in the future it might be
beneficial to compress them in some way. So I'd like to keep type and
encoding as separate information.

> 
>>>> +#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,                       \
>>>> +    }
>>>
>>> So you've got such helper macros for dir, string, and uint. Why
>>> not e.g. int and bool?
>>
>> There are no users in my series yet.
> 
> Hmm, as per above strictly speaking it is this patch which
> matters, not the entire series. Hence I think you either want
> to supply a full set of helper macros here, or introduce the
> ones actually needed in the patches where they get first used.

Okay, I'll go with the full set of helpers.

> 
>>>> +struct hypfs_entry *hypfs_get_entry(const char *path);
>>>
>>> Does the only caller really need a non-const return type? Even
>>> hypfs_write() doesn't look to modify what its leaf parameter
>>> points at.
>>
>> This might change when support for dynamically allocated strings or
>> blobs is added (I have no plans to do this right now, but its easy
>> to think about the need).
>>
>>>
>>> And is there indeed an expectation for this to be used from
>>> outside of the source file it's defined in?
>>
>> Yes. As soon as support for e.g. per-domain or per-cpupool nodes is
>> added this will be needed.
> 
> Until then, make the function both static and return ptr-to-const?
> Such that when this changes, the need for either can actually be
> seen?

Fine with me.


Juergen

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Xen-devel] [PATCH v3 4/9] xen: add basic hypervisor filesystem support
  2020-02-04  9:21         ` Jürgen Groß
@ 2020-02-04  9:58           ` Jan Beulich
  2020-02-04 10:48             ` Jürgen Groß
  0 siblings, 1 reply; 42+ messages in thread
From: Jan Beulich @ 2020-02-04  9:58 UTC (permalink / raw)
  To: Jürgen Groß
  Cc: Stefano Stabellini, Julien Grall, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, xen-devel,
	Volodymyr Babchuk, Roger Pau Monné

On 04.02.2020 10:21, Jürgen Groß wrote:
> On 04.02.20 09:48, Jan Beulich wrote:
>> On 04.02.2020 07:43, Jürgen Groß wrote:
>>> On 03.02.20 16:07, Jan Beulich wrote:
>>>> On 21.01.2020 09:43, Juergen Gross wrote:
>>>>> +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;
>>>>
>>>> So you return "success" even if the operation didn't complete
>>>> successfully. This isn't very nice, plus ...
>>>
>>> The direntry contains the needed size. The caller should know the
>>> size he passed to Xen.
>>>
>>>>
>>>>> +    guest_handle_add_offset(uaddr, sizeof(e));
>>>>> +
>>>>> +    ret = entry->read(entry, uaddr);
>>>>
>>>> ... how is the caller to know whether direntry was at least
>>>> copied if this then fails?
>>>
>>> Is this really important? Normally -EFAULT should just not happen. In
>>> case it does I don't think the caller can make real use of the direntry.
>>
>> "Important" has various possible meanings. The success/failure
>> indication to the caller should at least be rational. "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" is fine to be stated in the public header,
>> but I think this wants to be -ENOBUFS then, not 0 (success).
> 
> I would be fine with this, but this contradicts your previous demand
> not to enumerate the possible failure cases, which would be essential
> for this case.

Slightly re-writing the part of the comment I did quote would be
all that's needed afaict: "If the data buffer was not large enough
for all the data -ENOBUFS and no entry data is returned, but the
direntry will contain the needed size for the returned data."

>>>>> +    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;
>>>>
>>>> Is this restriction really necessary? Setting e.g. a 4-byte
>>>> field from 1-byte input is no problem at all. This being for
>>>> booleans I anyway wonder why input might be helpful to have
>>>> larger than a single byte. But maybe all of this is again a
>>>> result of not seeing what a user of the function would look
>>>> like.
>>>
>>> I wanted to have as little functionality as possible in the hypervisor.
>>> It is no problem for the library to pass a properly sized buffer.
>>>
>>> Allowing larger variables for booleans is just a consequence of the
>>> hypervisor parameters allowing that.
>>
>> But the caller shouldn't be concerned of the hypervisor
>> implementation detail of what the chose width is. Over time we
>> e.g. convert int (along with bool_t) to bool when it's used in
>> a boolean way. This should not result in the caller needing to
>> change, despite the width change of the variable.
> 
> This is basically a consequence of now passing binary values to and from
> the hypervisor.
> 
> The normal way of handling this (as can be seen in libxenhypfs) is to
> query the hypervisor for the size of the value (no matter whether its
> int, uint or bool) and then to do the conversion between ASCII and the
> binary value at the caller's side.

I can see why this is needed for e.g. integer values, but I don't
see the need for booleans.

>>>>> +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
>>>>
>>>> Meaning I can e.g. have a gzip-ed string or bool (or even dir)?
>>>> If this is just for "blob", why have separate fields instead of
>>>> e.g. BLOB_RAW and BLOB_GZIP or some such?
>>>
>>> gzip-ed string or blob are the primary targets.
>>>
>>> Maybe we want to have other encoding s later (Andrew asked for that
>>> possibility when I posted the patch for retrieving the .config file
>>> contents early last year).
>>
>> To me it would seem preferable if the contents of a blob
>> identified itself as to its format. But since this leaves
>> room for ambiguities I accept that the format needs
>> specifying. However, to me a gzip-ed string is as good as a
>> gzip-ed blob, and hence I still think sub-dividing "blob" is
>> the way to go, with no separate "encoding". Otherwise at the
>> very least a comment here would need adding to clarify what
>> combinations are valid / to be expected by callers.
> 
> libxenhypfs is able to handle all possible combinations. I just don't
> think some of the combinations are making sense (gzip-ing a binary
> value of 4 bytes e.g. is nonsense).
> 
> OTOH in case we'll add large arrays of longs in the future it might be
> beneficial to compress them in some way. So I'd like to keep type and
> encoding as separate information.

Okay, I'm not entirely opposed. But I'd be curious if anyone
else has an opinion here.

Jan

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Xen-devel] [PATCH v3 4/9] xen: add basic hypervisor filesystem support
  2020-02-04  9:58           ` Jan Beulich
@ 2020-02-04 10:48             ` Jürgen Groß
  2020-02-04 11:28               ` Jan Beulich
  0 siblings, 1 reply; 42+ messages in thread
From: Jürgen Groß @ 2020-02-04 10:48 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Stefano Stabellini, Julien Grall, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, xen-devel,
	Volodymyr Babchuk, Roger Pau Monné

On 04.02.20 10:58, Jan Beulich wrote:
> On 04.02.2020 10:21, Jürgen Groß wrote:
>> On 04.02.20 09:48, Jan Beulich wrote:
>>> On 04.02.2020 07:43, Jürgen Groß wrote:
>>>> On 03.02.20 16:07, Jan Beulich wrote:
>>>>> On 21.01.2020 09:43, Juergen Gross wrote:
>>>>>> +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;
>>>>>
>>>>> So you return "success" even if the operation didn't complete
>>>>> successfully. This isn't very nice, plus ...
>>>>
>>>> The direntry contains the needed size. The caller should know the
>>>> size he passed to Xen.
>>>>
>>>>>
>>>>>> +    guest_handle_add_offset(uaddr, sizeof(e));
>>>>>> +
>>>>>> +    ret = entry->read(entry, uaddr);
>>>>>
>>>>> ... how is the caller to know whether direntry was at least
>>>>> copied if this then fails?
>>>>
>>>> Is this really important? Normally -EFAULT should just not happen. In
>>>> case it does I don't think the caller can make real use of the direntry.
>>>
>>> "Important" has various possible meanings. The success/failure
>>> indication to the caller should at least be rational. "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" is fine to be stated in the public header,
>>> but I think this wants to be -ENOBUFS then, not 0 (success).
>>
>> I would be fine with this, but this contradicts your previous demand
>> not to enumerate the possible failure cases, which would be essential
>> for this case.
> 
> Slightly re-writing the part of the comment I did quote would be
> all that's needed afaict: "If the data buffer was not large enough
> for all the data -ENOBUFS and no entry data is returned, but the
> direntry will contain the needed size for the returned data."

Okay. Fine with me.

> 
>>>>>> +    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;
>>>>>
>>>>> Is this restriction really necessary? Setting e.g. a 4-byte
>>>>> field from 1-byte input is no problem at all. This being for
>>>>> booleans I anyway wonder why input might be helpful to have
>>>>> larger than a single byte. But maybe all of this is again a
>>>>> result of not seeing what a user of the function would look
>>>>> like.
>>>>
>>>> I wanted to have as little functionality as possible in the hypervisor.
>>>> It is no problem for the library to pass a properly sized buffer.
>>>>
>>>> Allowing larger variables for booleans is just a consequence of the
>>>> hypervisor parameters allowing that.
>>>
>>> But the caller shouldn't be concerned of the hypervisor
>>> implementation detail of what the chose width is. Over time we
>>> e.g. convert int (along with bool_t) to bool when it's used in
>>> a boolean way. This should not result in the caller needing to
>>> change, despite the width change of the variable.
>>
>> This is basically a consequence of now passing binary values to and from
>> the hypervisor.
>>
>> The normal way of handling this (as can be seen in libxenhypfs) is to
>> query the hypervisor for the size of the value (no matter whether its
>> int, uint or bool) and then to do the conversion between ASCII and the
>> binary value at the caller's side.
> 
> I can see why this is needed for e.g. integer values, but I don't
> see the need for booleans.

At some level the conversion needs to be done. I'd rather do it for all
types at the same level.

> 
>>>>>> +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
>>>>>
>>>>> Meaning I can e.g. have a gzip-ed string or bool (or even dir)?
>>>>> If this is just for "blob", why have separate fields instead of
>>>>> e.g. BLOB_RAW and BLOB_GZIP or some such?
>>>>
>>>> gzip-ed string or blob are the primary targets.
>>>>
>>>> Maybe we want to have other encoding s later (Andrew asked for that
>>>> possibility when I posted the patch for retrieving the .config file
>>>> contents early last year).
>>>
>>> To me it would seem preferable if the contents of a blob
>>> identified itself as to its format. But since this leaves
>>> room for ambiguities I accept that the format needs
>>> specifying. However, to me a gzip-ed string is as good as a
>>> gzip-ed blob, and hence I still think sub-dividing "blob" is
>>> the way to go, with no separate "encoding". Otherwise at the
>>> very least a comment here would need adding to clarify what
>>> combinations are valid / to be expected by callers.
>>
>> libxenhypfs is able to handle all possible combinations. I just don't
>> think some of the combinations are making sense (gzip-ing a binary
>> value of 4 bytes e.g. is nonsense).
>>
>> OTOH in case we'll add large arrays of longs in the future it might be
>> beneficial to compress them in some way. So I'd like to keep type and
>> encoding as separate information.
> 
> Okay, I'm not entirely opposed. But I'd be curious if anyone
> else has an opinion here.

I think content type and transport encoding should not be mixed up. They
are orthogonal to each other and so they should be handled.


Juergen

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Xen-devel] [PATCH v3 4/9] xen: add basic hypervisor filesystem support
  2020-02-04 10:48             ` Jürgen Groß
@ 2020-02-04 11:28               ` Jan Beulich
  2020-02-04 11:38                 ` Jürgen Groß
  0 siblings, 1 reply; 42+ messages in thread
From: Jan Beulich @ 2020-02-04 11:28 UTC (permalink / raw)
  To: Jürgen Groß
  Cc: Stefano Stabellini, Julien Grall, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, xen-devel,
	Volodymyr Babchuk, Roger Pau Monné

On 04.02.2020 11:48, Jürgen Groß wrote:
> On 04.02.20 10:58, Jan Beulich wrote:
>> On 04.02.2020 10:21, Jürgen Groß wrote:
>>> On 04.02.20 09:48, Jan Beulich wrote:
>>>> On 04.02.2020 07:43, Jürgen Groß wrote:
>>>>> On 03.02.20 16:07, Jan Beulich wrote:
>>>>>> On 21.01.2020 09:43, Juergen Gross wrote:
>>>>>>> +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
>>>>>>
>>>>>> Meaning I can e.g. have a gzip-ed string or bool (or even dir)?
>>>>>> If this is just for "blob", why have separate fields instead of
>>>>>> e.g. BLOB_RAW and BLOB_GZIP or some such?
>>>>>
>>>>> gzip-ed string or blob are the primary targets.
>>>>>
>>>>> Maybe we want to have other encoding s later (Andrew asked for that
>>>>> possibility when I posted the patch for retrieving the .config file
>>>>> contents early last year).
>>>>
>>>> To me it would seem preferable if the contents of a blob
>>>> identified itself as to its format. But since this leaves
>>>> room for ambiguities I accept that the format needs
>>>> specifying. However, to me a gzip-ed string is as good as a
>>>> gzip-ed blob, and hence I still think sub-dividing "blob" is
>>>> the way to go, with no separate "encoding". Otherwise at the
>>>> very least a comment here would need adding to clarify what
>>>> combinations are valid / to be expected by callers.
>>>
>>> libxenhypfs is able to handle all possible combinations. I just don't
>>> think some of the combinations are making sense (gzip-ing a binary
>>> value of 4 bytes e.g. is nonsense).
>>>
>>> OTOH in case we'll add large arrays of longs in the future it might be
>>> beneficial to compress them in some way. So I'd like to keep type and
>>> encoding as separate information.
>>
>> Okay, I'm not entirely opposed. But I'd be curious if anyone
>> else has an opinion here.
> 
> I think content type and transport encoding should not be mixed up. They
> are orthogonal to each other and so they should be handled.

In principle I agree, but "blob" really covers anything or nothing
at all. Yes, if strings are meant to be possible to be gzip-ed,
then there is value in the separation. I'm not fully convinced
though that such compressed strings (Are you thinking about
.config here?) shouldn't simply be "blob" then, too.

Jan

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Xen-devel] [PATCH v3 4/9] xen: add basic hypervisor filesystem support
  2020-02-04 11:28               ` Jan Beulich
@ 2020-02-04 11:38                 ` Jürgen Groß
  0 siblings, 0 replies; 42+ messages in thread
From: Jürgen Groß @ 2020-02-04 11:38 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Stefano Stabellini, Julien Grall, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, xen-devel,
	Volodymyr Babchuk, Roger Pau Monné

On 04.02.20 12:28, Jan Beulich wrote:
> On 04.02.2020 11:48, Jürgen Groß wrote:
>> On 04.02.20 10:58, Jan Beulich wrote:
>>> On 04.02.2020 10:21, Jürgen Groß wrote:
>>>> On 04.02.20 09:48, Jan Beulich wrote:
>>>>> On 04.02.2020 07:43, Jürgen Groß wrote:
>>>>>> On 03.02.20 16:07, Jan Beulich wrote:
>>>>>>> On 21.01.2020 09:43, Juergen Gross wrote:
>>>>>>>> +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
>>>>>>>
>>>>>>> Meaning I can e.g. have a gzip-ed string or bool (or even dir)?
>>>>>>> If this is just for "blob", why have separate fields instead of
>>>>>>> e.g. BLOB_RAW and BLOB_GZIP or some such?
>>>>>>
>>>>>> gzip-ed string or blob are the primary targets.
>>>>>>
>>>>>> Maybe we want to have other encoding s later (Andrew asked for that
>>>>>> possibility when I posted the patch for retrieving the .config file
>>>>>> contents early last year).
>>>>>
>>>>> To me it would seem preferable if the contents of a blob
>>>>> identified itself as to its format. But since this leaves
>>>>> room for ambiguities I accept that the format needs
>>>>> specifying. However, to me a gzip-ed string is as good as a
>>>>> gzip-ed blob, and hence I still think sub-dividing "blob" is
>>>>> the way to go, with no separate "encoding". Otherwise at the
>>>>> very least a comment here would need adding to clarify what
>>>>> combinations are valid / to be expected by callers.
>>>>
>>>> libxenhypfs is able to handle all possible combinations. I just don't
>>>> think some of the combinations are making sense (gzip-ing a binary
>>>> value of 4 bytes e.g. is nonsense).
>>>>
>>>> OTOH in case we'll add large arrays of longs in the future it might be
>>>> beneficial to compress them in some way. So I'd like to keep type and
>>>> encoding as separate information.
>>>
>>> Okay, I'm not entirely opposed. But I'd be curious if anyone
>>> else has an opinion here.
>>
>> I think content type and transport encoding should not be mixed up. They
>> are orthogonal to each other and so they should be handled.
> 
> In principle I agree, but "blob" really covers anything or nothing
> at all. Yes, if strings are meant to be possible to be gzip-ed,
> then there is value in the separation. I'm not fully convinced
> though that such compressed strings (Are you thinking about
> .config here?) shouldn't simply be "blob" then, too.

With a library on top of the hypercall it is easy to hide the encoding
from the standard user. So even with .config being held in gzip-ed
format in the hypervisor the xenhypfs tool will still just print the
textual form of it when reading the associated node. This is different
from sysfs or procfs of the Linux kernel, where the raw data is
presented at the primary user interface. Additionally this enables us
to avoid having to specify the compression format as a stable ABI. We
could at any time switch to uncompressed format without problem.


Juergen

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Xen-devel] [PATCH v3 5/9] libs: add libxenhypfs
  2020-02-03  9:14     ` Jürgen Groß
@ 2020-06-03  6:10       ` Olaf Hering
  0 siblings, 0 replies; 42+ messages in thread
From: Olaf Hering @ 2020-06-03  6:10 UTC (permalink / raw)
  To: Jürgen Groß
  Cc: Stefano Stabellini, Julien Grall, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, xen-devel

[-- Attachment #1: Type: text/plain, Size: 390 bytes --]

On Mon, Feb 03, Jürgen Groß wrote:

> On 31.01.20 16:57, Wei Liu wrote:
> > On Tue, Jan 21, 2020 at 09:43:26AM +0100, Juergen Gross wrote:
> > > +Requires.private: xentoolcore,xentoollog,xencall
> > Need to list libz here?
> Probably, yes.

See "rpm -qf --provides /usr/include/zlib.h" for the proper value within the "pkgconfig" namespace.
It is 'zlib' instead of 'z'.

Olaf

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 42+ messages in thread

end of thread, other threads:[~2020-06-03  6:11 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-21  8:43 [Xen-devel] [PATCH v3 0/9] Add hypervisor sysfs-like support Juergen Gross
2020-01-21  8:43 ` [Xen-devel] [PATCH v3 1/9] xen: add a generic way to include binary files as variables Juergen Gross
2020-02-03 13:39   ` Jan Beulich
2020-02-03 14:02     ` Jürgen Groß
2020-02-03 15:18       ` Jan Beulich
2020-01-21  8:43 ` [Xen-devel] [PATCH v3 2/9] xen: split parameter related definitions in own header file Juergen Gross
2020-01-21 13:00   ` Julien Grall
2020-01-21 13:28     ` Jürgen Groß
2020-01-21 13:31       ` Julien Grall
2020-01-22  1:34   ` Dario Faggioli
2020-01-22 11:28   ` Durrant, Paul
2020-01-22 16:49   ` Jan Beulich
2020-02-03  5:37   ` Tian, Kevin
2020-02-03 12:13   ` Jan Beulich
2020-01-21  8:43 ` [Xen-devel] [PATCH v3 3/9] docs: add feature document for Xen hypervisor sysfs-like support Juergen Gross
2020-01-21 13:14   ` Julien Grall
2020-01-21 14:17     ` Jürgen Groß
2020-02-03 10:29       ` Julien Grall
2020-01-21  8:43 ` [Xen-devel] [PATCH v3 4/9] xen: add basic hypervisor filesystem support Juergen Gross
2020-01-31 15:50   ` Wei Liu
2020-02-03  9:12     ` Jürgen Groß
2020-02-03 15:07   ` Jan Beulich
2020-02-04  6:43     ` Jürgen Groß
2020-02-04  8:48       ` Jan Beulich
2020-02-04  9:21         ` Jürgen Groß
2020-02-04  9:58           ` Jan Beulich
2020-02-04 10:48             ` Jürgen Groß
2020-02-04 11:28               ` Jan Beulich
2020-02-04 11:38                 ` Jürgen Groß
2020-01-21  8:43 ` [Xen-devel] [PATCH v3 5/9] libs: add libxenhypfs Juergen Gross
2020-01-31 15:57   ` Wei Liu
2020-02-03  9:14     ` Jürgen Groß
2020-06-03  6:10       ` Olaf Hering
2020-01-21  8:43 ` [Xen-devel] [PATCH v3 6/9] tools: add xenfs tool Juergen Gross
2020-01-31 15:59   ` Wei Liu
2020-01-21  8:43 ` [Xen-devel] [PATCH v3 7/9] xen: provide version information in hypfs Juergen Gross
2020-02-03 17:02   ` Jan Beulich
2020-02-04  6:44     ` Jürgen Groß
2020-01-21  8:43 ` [Xen-devel] [PATCH v3 8/9] xen: add /buildinfo/config entry to hypervisor filesystem Juergen Gross
2020-01-21  8:43 ` [Xen-devel] [PATCH v3 9/9] xen: add runtime parameter access support to hypfs Juergen Gross
2020-01-26 22:05 ` [Xen-devel] [PATCH v3 0/9] Add hypervisor sysfs-like support Rich Persaud
2020-01-27  5:37   ` Jürgen Groß

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.