* [PATCH 0/2] device-assignment: option ROM support
@ 2009-05-06 15:48 Alex Williamson
2009-05-06 15:48 ` [PATCH 1/2] kvm: bios: Use a different mask to size the option ROM BAR Alex Williamson
2009-05-06 15:49 ` [PATCH 2/2] kvm: device-assignment: Add PCI option ROM support Alex Williamson
0 siblings, 2 replies; 4+ messages in thread
From: Alex Williamson @ 2009-05-06 15:48 UTC (permalink / raw)
To: kvm, sheng; +Cc: alex.williamson
This short series adds support for exposing PCI option ROMs on
pass-through devices. I'm hoping that someone with more BIOS-foo
can make use of this to dynamically load option ROMs from within
the BIOS such that we might be able to boot from a pass-through
device. I guess it's theoretically possible today, but the chance
of finding a server class device with a ROM small enough to
pre-load into the necessary address space is pretty slim.
---
Alex Williamson (2):
kvm: device-assignment: Add PCI option ROM support
kvm: bios: Use a different mask to size the option ROM BAR
hw/device-assignment.c | 59 ++++++++++++++++++++++++++++++++++++------------
hw/device-assignment.h | 5 +---
kvm/bios/rombios32.c | 8 ++++---
3 files changed, 50 insertions(+), 22 deletions(-)
--
Alex
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/2] kvm: bios: Use a different mask to size the option ROM BAR
2009-05-06 15:48 [PATCH 0/2] device-assignment: option ROM support Alex Williamson
@ 2009-05-06 15:48 ` Alex Williamson
2009-05-07 12:10 ` Avi Kivity
2009-05-06 15:49 ` [PATCH 2/2] kvm: device-assignment: Add PCI option ROM support Alex Williamson
1 sibling, 1 reply; 4+ messages in thread
From: Alex Williamson @ 2009-05-06 15:48 UTC (permalink / raw)
To: kvm, sheng; +Cc: alex.williamson
Bit 0 is the enable bit, which we not only don't want to set, but
it will stick and make us think it's an I/O port resource.
Signed-off-by: Alex Williamson <alex.williamson@hp.com>
---
kvm/bios/rombios32.c | 8 +++++---
1 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/kvm/bios/rombios32.c b/kvm/bios/rombios32.c
index 8684987..6502e63 100755
--- a/kvm/bios/rombios32.c
+++ b/kvm/bios/rombios32.c
@@ -958,11 +958,13 @@ static void pci_bios_init_device(PCIDevice *d)
int ofs;
uint32_t val, size ;
- if (i == PCI_ROM_SLOT)
+ if (i == PCI_ROM_SLOT) {
ofs = 0x30;
- else
+ pci_config_writel(d, ofs, 0xfffffffe);
+ } else {
ofs = 0x10 + i * 4;
- pci_config_writel(d, ofs, 0xffffffff);
+ pci_config_writel(d, ofs, 0xffffffff);
+ }
val = pci_config_readl(d, ofs);
if (val != 0) {
size = (~(val & ~0xf)) + 1;
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/2] kvm: device-assignment: Add PCI option ROM support
2009-05-06 15:48 [PATCH 0/2] device-assignment: option ROM support Alex Williamson
2009-05-06 15:48 ` [PATCH 1/2] kvm: bios: Use a different mask to size the option ROM BAR Alex Williamson
@ 2009-05-06 15:49 ` Alex Williamson
1 sibling, 0 replies; 4+ messages in thread
From: Alex Williamson @ 2009-05-06 15:49 UTC (permalink / raw)
To: kvm, sheng; +Cc: alex.williamson
The PCI code already knows about option ROMs, so we just need to
mmap some space for it, load it with a copy of the contents, and
complete the plubming to the generic code.
Signed-off-by: Alex Williamson <alex.williamson@hp.com>
---
hw/device-assignment.c | 59 ++++++++++++++++++++++++++++++++++++------------
hw/device-assignment.h | 5 +---
2 files changed, 45 insertions(+), 19 deletions(-)
diff --git a/hw/device-assignment.c b/hw/device-assignment.c
index 0a5f850..a7365c8 100644
--- a/hw/device-assignment.c
+++ b/hw/device-assignment.c
@@ -286,8 +286,8 @@ static void assigned_dev_pci_write_config(PCIDevice *d, uint32_t address,
/* Continue to program the card */
}
- if ((address >= 0x10 && address <= 0x24) || address == 0x34 ||
- address == 0x3c || address == 0x3d ||
+ if ((address >= 0x10 && address <= 0x24) || address == 0x30 ||
+ address == 0x34 || address == 0x3c || address == 0x3d ||
pci_access_cap_config(d, address, len)) {
/* used for update-mappings (BAR emulation) */
pci_default_write_config(d, address, val, len);
@@ -322,8 +322,8 @@ static uint32_t assigned_dev_pci_read_config(PCIDevice *d, uint32_t address,
AssignedDevice *pci_dev = container_of(d, AssignedDevice, dev);
if (address < 0x4 || (pci_dev->need_emulate_cmd && address == 0x4) ||
- (address >= 0x10 && address <= 0x24) || address == 0x34 ||
- address == 0x3c || address == 0x3d ||
+ (address >= 0x10 && address <= 0x24) || address == 0x30 ||
+ address == 0x34 || address == 0x3c || address == 0x3d ||
pci_access_cap_config(d, address, len)) {
val = pci_default_read_config(d, address, len);
DEBUG("(%x.%x): address=%04x val=0x%08x len=%d\n",
@@ -384,11 +384,20 @@ static int assigned_dev_register_regions(PCIRegion *io_regions,
/* map physical memory */
pci_dev->v_addrs[i].e_physbase = cur_region->base_addr;
- pci_dev->v_addrs[i].u.r_virtbase =
- mmap(NULL,
- (cur_region->size + 0xFFF) & 0xFFFFF000,
- PROT_WRITE | PROT_READ, MAP_SHARED,
- cur_region->resource_fd, (off_t) 0);
+ if (i == PCI_ROM_SLOT) {
+ pci_dev->v_addrs[i].u.r_virtbase =
+ mmap(NULL,
+ (cur_region->size + 0xFFF) & 0xFFFFF000,
+ PROT_WRITE | PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE,
+ 0, (off_t) 0);
+
+ } else {
+ pci_dev->v_addrs[i].u.r_virtbase =
+ mmap(NULL,
+ (cur_region->size + 0xFFF) & 0xFFFFF000,
+ PROT_WRITE | PROT_READ, MAP_SHARED,
+ cur_region->resource_fd, (off_t) 0);
+ }
if (pci_dev->v_addrs[i].u.r_virtbase == MAP_FAILED) {
pci_dev->v_addrs[i].u.r_virtbase = NULL;
@@ -397,6 +406,14 @@ static int assigned_dev_register_regions(PCIRegion *io_regions,
(uint32_t) (cur_region->base_addr));
return -1;
}
+
+ if (i == PCI_ROM_SLOT) {
+ memset(pci_dev->v_addrs[i].u.r_virtbase, 0,
+ (cur_region->size + 0xFFF) & 0xFFFFF000);
+ mprotect(pci_dev->v_addrs[PCI_ROM_SLOT].u.r_virtbase,
+ (cur_region->size + 0xFFF) & 0xFFFFF000, PROT_READ);
+ }
+
pci_dev->v_addrs[i].r_size = cur_region->size;
pci_dev->v_addrs[i].e_size = 0;
@@ -468,7 +485,7 @@ again:
return 1;
}
- for (r = 0; r < MAX_IO_REGIONS; r++) {
+ for (r = 0; r < PCI_NUM_REGIONS; r++) {
if (fscanf(f, "%lli %lli %lli\n", &start, &end, &flags) != 3)
break;
@@ -480,11 +497,13 @@ again:
continue;
if (flags & IORESOURCE_MEM) {
flags &= ~IORESOURCE_IO;
- snprintf(name, sizeof(name), "%sresource%d", dir, r);
- fd = open(name, O_RDWR);
- if (fd == -1)
- continue; /* probably ROM */
- rp->resource_fd = fd;
+ if (r != PCI_ROM_SLOT) {
+ snprintf(name, sizeof(name), "%sresource%d", dir, r);
+ fd = open(name, O_RDWR);
+ if (fd == -1)
+ continue;
+ rp->resource_fd = fd;
+ }
} else
flags &= ~IORESOURCE_PREFETCH;
@@ -1391,6 +1410,16 @@ ram_addr_t assigned_dev_load_option_roms(ram_addr_t rom_base_offset)
continue;
}
+ if (adev->assigned_dev->v_addrs[PCI_ROM_SLOT].r_size >= size &&
+ adev->assigned_dev->v_addrs[PCI_ROM_SLOT].u.r_virtbase) {
+ mprotect(adev->assigned_dev->v_addrs[PCI_ROM_SLOT].u.r_virtbase,
+ size, PROT_READ | PROT_WRITE);
+ memcpy(adev->assigned_dev->v_addrs[PCI_ROM_SLOT].u.r_virtbase,
+ buf, size);
+ mprotect(adev->assigned_dev->v_addrs[PCI_ROM_SLOT].u.r_virtbase,
+ size, PROT_READ);
+ }
+
/* Scan the buffer for suitable ROMs and increase the offset */
offset += scan_option_rom(adev->assigned_dev->dev.devfn, buf, offset);
diff --git a/hw/device-assignment.h b/hw/device-assignment.h
index c691e11..713f9b7 100644
--- a/hw/device-assignment.h
+++ b/hw/device-assignment.h
@@ -36,9 +36,6 @@
/* From include/linux/pci.h in the kernel sources */
#define PCI_DEVFN(slot, func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))
-/* The number of BARs in the config space header */
-#define MAX_IO_REGIONS (6)
-
typedef struct {
int type; /* Memory or port I/O */
int valid;
@@ -53,7 +50,7 @@ typedef struct {
uint16_t region_number; /* number of active regions */
/* Port I/O or MMIO Regions */
- PCIRegion regions[MAX_IO_REGIONS];
+ PCIRegion regions[PCI_NUM_REGIONS];
int config_fd;
} PCIDevRegions;
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 1/2] kvm: bios: Use a different mask to size the option ROM BAR
2009-05-06 15:48 ` [PATCH 1/2] kvm: bios: Use a different mask to size the option ROM BAR Alex Williamson
@ 2009-05-07 12:10 ` Avi Kivity
0 siblings, 0 replies; 4+ messages in thread
From: Avi Kivity @ 2009-05-07 12:10 UTC (permalink / raw)
To: Alex Williamson; +Cc: kvm, sheng
Alex Williamson wrote:
> Bit 0 is the enable bit, which we not only don't want to set, but
> it will stick and make us think it's an I/O port resource.
>
> Signed-off-by: Alex Williamson <alex.williamson@hp.com>
> ---
>
> kvm/bios/rombios32.c | 8 +++++---
> 1 files changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/kvm/bios/rombios32.c b/kvm/bios/rombios32.c
> index 8684987..6502e63 100755
> --- a/kvm/bios/rombios32.c
> +++ b/kvm/bios/rombios32.c
> @@ -958,11 +958,13 @@ static void pci_bios_init_device(PCIDevice *d)
> int ofs;
> uint32_t val, size ;
>
> - if (i == PCI_ROM_SLOT)
> + if (i == PCI_ROM_SLOT) {
> ofs = 0x30;
> - else
> + pci_config_writel(d, ofs, 0xfffffffe);
> + } else {
> ofs = 0x10 + i * 4;
> - pci_config_writel(d, ofs, 0xffffffff);
> + pci_config_writel(d, ofs, 0xffffffff);
> + }
> val = pci_config_readl(d, ofs);
> if (val != 0) {
> size = (~(val & ~0xf)) + 1;
>
Looks good. I think it applies upstream (or even upstream's upstream)
though, in which case please send it qemu-devel.
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2009-05-07 12:10 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-05-06 15:48 [PATCH 0/2] device-assignment: option ROM support Alex Williamson
2009-05-06 15:48 ` [PATCH 1/2] kvm: bios: Use a different mask to size the option ROM BAR Alex Williamson
2009-05-07 12:10 ` Avi Kivity
2009-05-06 15:49 ` [PATCH 2/2] kvm: device-assignment: Add PCI option ROM support Alex Williamson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox