From: "Gabriel Somlo" <somlo@xxxxxxx> 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 _______________________________________________ Kernelnewbies mailing list Kernelnewbies@xxxxxxxxxxxxxxxxx http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies