Commit f46f15bca78946f3debc9eaa6dbf3a9a9e57872d

Authored by aliguori
1 parent 6e02c38d

Remove TARGET_PAGE_SIZE from virtio interface (Hollis Blanchard)

TARGET_PAGE_SIZE should only be used internal to qemu, not in guest/host
interfaces. The virtio frontend code in Linux uses two constants (PFN shift
and vring alignment) for the interface, so update qemu to match.

I've tested this with PowerPC KVM and confirmed that it fixes virtio problems
when using non-TARGET_PAGE_SIZE pages in the guest.

Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5871 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 2 changed files with 19 additions and 3 deletions
hw/virtio.c
@@ -52,6 +52,14 @@ @@ -52,6 +52,14 @@
52 /* Virtio ABI version, if we increment this, we break the guest driver. */ 52 /* Virtio ABI version, if we increment this, we break the guest driver. */
53 #define VIRTIO_PCI_ABI_VERSION 0 53 #define VIRTIO_PCI_ABI_VERSION 0
54 54
  55 +/* How many bits to shift physical queue address written to QUEUE_PFN.
  56 + * 12 is historical, and due to x86 page size. */
  57 +#define VIRTIO_PCI_QUEUE_ADDR_SHIFT 12
  58 +
  59 +/* The alignment to use between consumer and producer parts of vring.
  60 + * x86 pagesize again. */
  61 +#define VIRTIO_PCI_VRING_ALIGN 4096
  62 +
55 /* QEMU doesn't strictly need write barriers since everything runs in 63 /* QEMU doesn't strictly need write barriers since everything runs in
56 * lock-step. We'll leave the calls to wmb() in though to make it obvious for 64 * lock-step. We'll leave the calls to wmb() in though to make it obvious for
57 * KVM or if kqemu gets SMP support. 65 * KVM or if kqemu gets SMP support.
@@ -147,7 +155,9 @@ static void virtqueue_init(VirtQueue *vq, target_phys_addr_t pa) @@ -147,7 +155,9 @@ static void virtqueue_init(VirtQueue *vq, target_phys_addr_t pa)
147 { 155 {
148 vq->vring.desc = pa; 156 vq->vring.desc = pa;
149 vq->vring.avail = pa + vq->vring.num * sizeof(VRingDesc); 157 vq->vring.avail = pa + vq->vring.num * sizeof(VRingDesc);
150 - vq->vring.used = TARGET_PAGE_ALIGN(vq->vring.avail + offsetof(VRingAvail, ring[vq->vring.num])); 158 + vq->vring.used = vring_align(vq->vring.avail +
  159 + offsetof(VRingAvail, ring[vq->vring.num]),
  160 + VIRTIO_PCI_VRING_ALIGN);
151 } 161 }
152 162
153 static inline uint64_t vring_desc_addr(VirtQueue *vq, int i) 163 static inline uint64_t vring_desc_addr(VirtQueue *vq, int i)
@@ -501,7 +511,7 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val) @@ -501,7 +511,7 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
501 vdev->features = val; 511 vdev->features = val;
502 break; 512 break;
503 case VIRTIO_PCI_QUEUE_PFN: 513 case VIRTIO_PCI_QUEUE_PFN:
504 - pa = (ram_addr_t)val << TARGET_PAGE_BITS; 514 + pa = (ram_addr_t)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT;
505 vdev->vq[vdev->queue_sel].pfn = val; 515 vdev->vq[vdev->queue_sel].pfn = val;
506 if (pa == 0) { 516 if (pa == 0) {
507 virtio_reset(vdev); 517 virtio_reset(vdev);
@@ -776,7 +786,7 @@ void virtio_load(VirtIODevice *vdev, QEMUFile *f) @@ -776,7 +786,7 @@ void virtio_load(VirtIODevice *vdev, QEMUFile *f)
776 if (vdev->vq[i].pfn) { 786 if (vdev->vq[i].pfn) {
777 target_phys_addr_t pa; 787 target_phys_addr_t pa;
778 788
779 - pa = (ram_addr_t)vdev->vq[i].pfn << TARGET_PAGE_BITS; 789 + pa = (ram_addr_t)vdev->vq[i].pfn << VIRTIO_PCI_QUEUE_ADDR_SHIFT;
780 virtqueue_init(&vdev->vq[i], pa); 790 virtqueue_init(&vdev->vq[i], pa);
781 } 791 }
782 } 792 }
hw/virtio.h
@@ -48,6 +48,12 @@ @@ -48,6 +48,12 @@
48 48
49 struct VirtQueue; 49 struct VirtQueue;
50 50
  51 +static inline target_phys_addr_t vring_align(target_phys_addr_t addr,
  52 + unsigned long align)
  53 +{
  54 + return (addr + align - 1) & ~(align - 1);
  55 +}
  56 +
51 typedef struct VirtQueue VirtQueue; 57 typedef struct VirtQueue VirtQueue;
52 typedef struct VirtIODevice VirtIODevice; 58 typedef struct VirtIODevice VirtIODevice;
53 59