[PATCH v3 0/4] SysFS driver for QEMU fw_cfg device

Gabriel L. Somlo somlo at cmu.edu
Sat Oct 3 19:28:05 EDT 2015


From: "Gabriel Somlo" <somlo at cmu.edu>

Allow access to QEMU firmware blobs, passed into the guest VM via
the fw_cfg device, through SysFS entries. Blob meta-data (e.g. name,
size, and fw_cfg key), as well as the raw binary blob data may be
accessed.

The SysFS access location is /sys/firmware/qemu_fw_cfg/... and was
selected based on overall similarity to the type of information
exposed under /sys/firmware/dmi/entries/...


NEW (since v2): Using ACPI to detect the presence and details of the
fw_cfg virtual hardware device.

    Device Tree has been suggested by Ard as a comment on v2 of this
    patch, but after some deliberation I decided to go with ACPI,
    since it's supported on both x86 and some (uefi-enabled) versions
    of aarch64. I really don't see how I'd reasonably use *both* DT (on
    ARM) *and* ACPI (on x86), and after all I'm mostly concerned with
    x86, but originally wanted to maximize portability (which is where
    the register probing in earlier versions came from).

    A patch set generating an ACPI device node for qemu's fw_cfg is
    currently under review on the qemu-devel list:

    http://lists.nongnu.org/archive/html/qemu-devel/2015-09/msg06946.html
    (sorry, gmane appears down at the moment...)

In consequence:

	- Patch 1/4 is mostly the same as in v2;
	- Patch 2/4 switches device initialization from register
	  probing to using ACPI; this is a separate patch only to
	  illustrate the transition from probing to ACPI, and I'm
	  assuming it will end up squashed on top of patch 1/4 in
	  the final version.

	- Patches 3/4 and 4/4 add a "human-readable" directory
	  hierarchy built from tokenizing fw_cfg blob names into
	  '/'-separated components, with symlinks to each 'by_key'
	  blob folder (same as in earlier versions). At Greg's
	  suggestion I tried to build this folder hierarchy and
	  leaf symlinks using udev rules, but so far I haven't been
	  successful in figuring that out. If udev turns out to 
	  be applicable after all, these two patches can be dropped
	  from this series.

In other words, patches 1 and 2 give us the following "by_key" listing
of blobs contained in the qemu fw_cfg device (example pulled from a PC
qemu guest running Fedora 22), with the value of each "name" attribute
shown on the right:

$ tree /sys/firmware/qemu_fw_cfg/
/sys/firmware/qemu_fw_cfg/
|-- by_key
|   |-- 32
|   |   |-- key
|   |   |-- name			("etc/boot-fail-wait")
|   |   |-- raw
|   |   `-- size
|   |-- 33
|   |   |-- key
|   |   |-- name			("etc/smbios/smbios-tables")
|   |   |-- raw
|   |   `-- size
|   |-- 34
|   |   |-- key
|   |   |-- name			("etc/smbios/smbios-anchor")
|   |   |-- raw
|   |   `-- size
|   |-- 35
|   |   |-- key
|   |   |-- name			("etc/e820")
|   |   |-- raw
|   |   `-- size
|   |-- 36
|   |   |-- key
|   |   |-- name			("genroms/kvmvapic.bin")
|   |   |-- raw
|   |   `-- size
|   |-- 37
|   |   |-- key
|   |   |-- name			("etc/system-states")
|   |   |-- raw
|   |   `-- size
|   |-- 38
|   |   |-- key
|   |   |-- name			("etc/acpi/tables")
|   |   |-- raw
|   |   `-- size
|   |-- 39
|   |   |-- key
|   |   |-- name			("etc/table-loader")
|   |   |-- raw
|   |   `-- size
|   |-- 40
|   |   |-- key
|   |   |-- name			("etc/tpm/log")
|   |   |-- raw
|   |   `-- size
|   |-- 41
|   |   |-- key
|   |   |-- name			("etc/acpi/rsdp")
|   |   |-- raw
|   |   `-- size
|   `-- 42
|       |-- key
|       |-- name			("bootorder")
|       |-- raw
|       `-- size
|
...

Additionally, patches 3 and 4 (mostly 4) give us the following
"user friendly" directory hierarchy as a complement to the above,
based on tokenizing each blob name into symlink-tipped (sub)directories:

...
|-- by_name
|   |-- bootorder -> ../by_key/42
|   |-- etc
|   |   |-- acpi
|   |   |   |-- rsdp -> ../../../by_key/41
|   |   |   `-- tables -> ../../../by_key/38
|   |   |-- boot-fail-wait -> ../../by_key/32
|   |   |-- e820 -> ../../by_key/35
|   |   |-- smbios
|   |   |   |-- smbios-anchor -> ../../../by_key/34
|   |   |   `-- smbios-tables -> ../../../by_key/33
|   |   |-- system-states -> ../../by_key/37
|   |   |-- table-loader -> ../../by_key/39
|   |   `-- tpm
|   |       `-- log -> ../../../by_key/40
|   `-- genroms
|       `-- kvmvapic.bin -> ../../by_key/36
`-- rev

The trick is to figure out how to replace patches 3 and 4 with a
udev rule that would read the contents of each "name" attribute,
and build the "by_name" hierarchy and symlinks in userspace.

I tried:

$ udevadm info -a -p /sys/firmware/qemu_fw_cfg/by_key/33

  looking at device '/firmware/qemu_fw_cfg/by_key/33':
    KERNEL=="33"
    SUBSYSTEM==""
    DRIVER==""
    ATTR{key}=="33"
    ATTR{name}=="etc/smbios/smbios-tables"
    ATTR{size}=="388"

  looking at parent device '/firmware/qemu_fw_cfg/by_key':
    KERNELS=="by_key"
    SUBSYSTEMS==""
    DRIVERS==""

  looking at parent device '/firmware/qemu_fw_cfg':
    KERNELS=="qemu_fw_cfg"
    SUBSYSTEMS==""
    DRIVERS==""
    ATTRS{rev}=="1"

Then I tried creating a file, /usr/lib/udev/rules.d/99-qemu-fw-cfg.rules
containing the following line:

KERNELS=="qemu_fw_cfg", ATTRS{rev}=="1", SYMLINK="%p/%s{name}"

but NOTHING happens when I insert/remove qemu_fw_cfg.ko.  I also tried:

KERNELS=="qemu_fw_cfg", ATTRS{rev}=="1", PROGRAM="/foo %k"

where "/foo" basically did "echo $* > /tmp/bar", but no /tmp/bar file ever
showed up as a consequence of inserting/removing the qemu_fw_cfg.ko module.

At this point, I need help figuring out whether udev is really what would
get the second, user-friendly, "by_name" /sysfs directory tree created,
and how I'd go about that...

Thanks much,
  --Gabriel

Gabriel Somlo (4):
  firmware: introduce sysfs driver for QEMU's fw_cfg device
  firmware: use acpi to detect QEMU fw_cfg device for sysfs fw_cfg
    driver
  kobject: export kset_find_obj() for module use
  firmware: create directory hierarchy for sysfs fw_cfg entries

 .../ABI/testing/sysfs-firmware-qemu_fw_cfg         | 213 ++++++++
 drivers/firmware/Kconfig                           |  10 +
 drivers/firmware/Makefile                          |   1 +
 drivers/firmware/qemu_fw_cfg.c                     | 575 +++++++++++++++++++++
 lib/kobject.c                                      |   1 +
 5 files changed, 800 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-firmware-qemu_fw_cfg
 create mode 100644 drivers/firmware/qemu_fw_cfg.c

-- 
2.4.3




More information about the Kernelnewbies mailing list