Skip to contentSkip to conversation

qemu-kvm: require 4K aligned resource size for memory

PATCH Applied Michael S. Tsirkin 3 participants 4 messages Oct 20, 2009 – Oct 22, 2009 KVM

lore
Share & tools
lore
#0 lore raw

KVM does not virtualize low address bits for memory accesses, so we must require that PCI BAR size is a multiple of 4K for passthrough to work (this also guarantees that address is 4K aligned).

Users of recent linux kernels can force resource size up to 4K using:

	commit 32a9a682bef2f6fce7026bd94d1ce20028b0e52d
	Author: Yuji Shimada <[email protected]>
	Date:   Mon Mar 16 17:13:39 2009 +0900
	PCI: allow assignment of memory resources with a specified alignment

---

hw/device-assignment.c +8 -0
index 237060f..c2ef31f 100644
@@ -381,6 +381,14 @@ static int assigned_dev_register_regions(PCIRegion *io_regions,
             int t = cur_region->type & IORESOURCE_PREFETCH
                 ? PCI_ADDRESS_SPACE_MEM_PREFETCH
                 : PCI_ADDRESS_SPACE_MEM;
+            if (cur_region->size & 0xFFF) {
+                fprintf(stderr, "Unable to assign device: PCI region %d "
+                        "at address 0x%llx has size 0x%x, "
+                        " which is not a multiple of 4K\n",
+                        i, (unsigned long long)cur_region->base_addr,
+                        cur_region->size);
+                return -1;
+            }
 
             /* map physical memory */
             pci_dev->v_addrs[i].e_physbase = cur_region->base_addr;
#1 lore raw
Quoted 22 lines · * Michael S. Tsirkin ([email protected]) wrote:

KVM does not virtualize low address bits for memory accesses, so we must require that PCI BAR size is a multiple of 4K for passthrough to work (this also guarantees that address is 4K aligned).

Users of recent linux kernels can force resource size up to 4K using:

	commit 32a9a682bef2f6fce7026bd94d1ce20028b0e52d
	Author: Yuji Shimada <[email protected]>
	Date:   Mon Mar 16 17:13:39 2009 +0900
	PCI: allow assignment of memory resources with a specified alignment

---

hw/device-assignment.c +0 -0
index 237060f..c2ef31f 100644
@@ -381,6 +381,14 @@ static int assigned_dev_register_regions(PCIRegion *io_regions,
             int t = cur_region->type & IORESOURCE_PREFETCH

hw/device-assignment.c static int assigned_dev_register_regions(PCIRegion *io_regions, · line 391

Quoted 10 lines
hw/device-assignment.c +8 -0
                 ? PCI_ADDRESS_SPACE_MEM_PREFETCH
                 : PCI_ADDRESS_SPACE_MEM;
+            if (cur_region->size & 0xFFF) {
+                fprintf(stderr, "Unable to assign device: PCI region %d "
+                        "at address 0x%llx has size 0x%x, "
+                        " which is not a multiple of 4K\n",
+                        i, (unsigned long long)cur_region->base_addr,
+                        cur_region->size);
+                return -1;
+            }

should render this useless now shouldn't it?

           /* add offset */
            pci_dev->v_addrs[i].u.r_virtbase +=
                (cur_region->base_addr & 0xFFF);

thanks,
-chris

#2 lore raw
Quoted 36 lines · Chris Wright
Quoted 22 lines · * Michael S. Tsirkin ([email protected]) wrote:

KVM does not virtualize low address bits for memory accesses, so we must require that PCI BAR size is a multiple of 4K for passthrough to work (this also guarantees that address is 4K aligned).

Users of recent linux kernels can force resource size up to 4K using:

	commit 32a9a682bef2f6fce7026bd94d1ce20028b0e52d
	Author: Yuji Shimada <[email protected]>
	Date:   Mon Mar 16 17:13:39 2009 +0900
	PCI: allow assignment of memory resources with a specified alignment

---

hw/device-assignment.c +0 -0
index 237060f..c2ef31f 100644
@@ -381,6 +381,14 @@ static int assigned_dev_register_regions(PCIRegion *io_regions,
             int t = cur_region->type & IORESOURCE_PREFETCH

hw/device-assignment.c static int assigned_dev_register_regions(PCIRegion *io_regions, · line 391

Quoted 10 lines
hw/device-assignment.c +8 -0
                 ? PCI_ADDRESS_SPACE_MEM_PREFETCH
                 : PCI_ADDRESS_SPACE_MEM;
+            if (cur_region->size & 0xFFF) {
+                fprintf(stderr, "Unable to assign device: PCI region %d "
+                        "at address 0x%llx has size 0x%x, "
+                        " which is not a multiple of 4K\n",
+                        i, (unsigned long long)cur_region->base_addr,
+                        cur_region->size);
+                return -1;
+            }

should render this useless now shouldn't it?

Quoted 3 lines
           /* add offset */
            pci_dev->v_addrs[i].u.r_virtbase +=
                (cur_region->base_addr & 0xFFF);

Yes, we could go over the code and remove all alignment. But I'd rather not in case we decide on another approach in the future. And for upstream, all this code will have to be rewritten anyway.

Quoted 2 lines

thanks,
-chris

#3 lore raw
In reply to Michael S. Tsirkin
Quoted 7 lines · Michael S. Tsirkin

KVM does not virtualize low address bits for memory accesses, so we must require that PCI BAR size is a multiple of 4K for passthrough to work (this also guarantees that address is 4K aligned).

Users of recent linux kernels can force resource size up to 4K using:

Quoted 6 lines
	commit 32a9a682bef2f6fce7026bd94d1ce20028b0e52d
	Author: Yuji Shimada <[email protected]>
	Date:   Mon Mar 16 17:13:39 2009 +0900
	PCI: allow assignment of memory resources with a specified alignment

Applied, thanks.