public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* [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