The PCI sysfs rom file is exposed read-only by default, but we need
to write to it to enable and disable the ROM around the read. When
running as root, the code works fine as is, but when running
de-privileged via libvirt, the fopen("r+") will fail if the file
doesn't have owner write permissions. libvirt already gives us
ownership of the file, so we can toggle this around the short
usage window ourselves.
Signed-off-by: Alex Williamson <[email protected]>
Acked-by: Chris Wright <[email protected]>
---
hw/device-assignment.c | 19 ++++++++++++-------
1 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/hw/device-assignment.c b/hw/device-assignment.c
index 8446cd4..81c77ae 100644
--- a/hw/device-assignment.c
+++ b/hw/device-assignment.c
@@ -1866,16 +1866,18 @@ static void assigned_dev_load_option_rom(AssignedDevice
*dev)
return;
}
- if (access(rom_file, F_OK)) {
- fprintf(stderr, "pci-assign: Insufficient privileges for %s\n",
- rom_file);
+ /* The ROM file is typically mode 0400, ensure that it's at least 0600
+ * for the following fopen to succeed when qemu is de-privileged. */
+ if (chmod(rom_file, (st.st_mode & ALLPERMS) | S_IRUSR | S_IWUSR)) {
+ fprintf(stderr, "pci-assign: Insufficient privileges for %s (%s)\n",
+ rom_file, strerror(errno));
return;
}
/* Write "1" to the ROM file to enable it */
fp = fopen(rom_file, "r+");
if (fp == NULL) {
- return;
+ goto restore_rom;
}
val = 1;
if (fwrite(&val, 1, 1, fp) != 1) {
@@ -1895,17 +1897,20 @@ static void assigned_dev_load_option_rom(AssignedDevice
*dev)
"or load from file with romfile=\n", rom_file);
qemu_ram_free(dev->dev.rom_offset);
dev->dev.rom_offset = 0;
- goto close_rom;
+ goto disable_rom;
}
pci_register_bar(&dev->dev, PCI_ROM_SLOT,
st.st_size, 0, pci_map_option_rom);
-close_rom:
+disable_rom:
/* Write "0" to disable ROM */
fseek(fp, 0, SEEK_SET);
val = 0;
- if (!fwrite(&val, 1, 1, fp)) {
+ if (fwrite(&val, 1, 1, fp) != 1) {
DEBUG("%s\n", "Failed to disable pci-sysfs rom file");
}
+close_rom:
fclose(fp);
+restore_rom:
+ chmod(rom_file, st.st_mode & ALLPERMS);
}
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html