From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1L5P1g-0007pe-BB for qemu-devel@nongnu.org; Wed, 26 Nov 2008 13:22:12 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1L5P1e-0007o0-Ot for qemu-devel@nongnu.org; Wed, 26 Nov 2008 13:22:12 -0500 Received: from [199.232.76.173] (port=57213 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1L5P1e-0007nj-HI for qemu-devel@nongnu.org; Wed, 26 Nov 2008 13:22:10 -0500 Received: from e34.co.us.ibm.com ([32.97.110.152]:51384) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1L5P1c-0006bE-PQ for qemu-devel@nongnu.org; Wed, 26 Nov 2008 13:22:09 -0500 Received: from d03relay04.boulder.ibm.com (d03relay04.boulder.ibm.com [9.17.195.106]) by e34.co.us.ibm.com (8.13.1/8.13.1) with ESMTP id mAQILUmc000766 for ; Wed, 26 Nov 2008 11:21:30 -0700 Received: from d03av04.boulder.ibm.com (d03av04.boulder.ibm.com [9.17.195.170]) by d03relay04.boulder.ibm.com (8.13.8/8.13.8/NCO v9.1) with ESMTP id mAQIM7LQ131936 for ; Wed, 26 Nov 2008 11:22:07 -0700 Received: from d03av04.boulder.ibm.com (loopback [127.0.0.1]) by d03av04.boulder.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id mAQIM637009828 for ; Wed, 26 Nov 2008 11:22:06 -0700 From: Hollis Blanchard Date: Wed, 26 Nov 2008 12:22:06 -0600 Message-Id: <1227723726-15662-1-git-send-email-hollisb@us.ibm.com> In-Reply-To: <1227650239-14162-1-git-send-email-aliguori@us.ibm.com> References: <1227650239-14162-1-git-send-email-aliguori@us.ibm.com> Subject: [Qemu-devel] [PATCH] Remove TARGET_PAGE_SIZE from virtio interface Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Anthony Liguori Cc: Hollis Blanchard , qemu-devel@nongnu.org, kvm@vger.kernel.org, Avi Kivity 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 --- hw/virtio.c | 16 +++++++++++++--- hw/virtio.h | 5 +++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/hw/virtio.c b/hw/virtio.c index e4224ab..0134b0b 100644 --- a/hw/virtio.c +++ b/hw/virtio.c @@ -51,6 +51,14 @@ /* Virtio ABI version, if we increment this, we break the guest driver. */ #define VIRTIO_PCI_ABI_VERSION 0 +/* How many bits to shift physical queue address written to QUEUE_PFN. + * 12 is historical, and due to x86 page size. */ +#define VIRTIO_PCI_QUEUE_ADDR_SHIFT 12 + +/* The alignment to use between consumer and producer parts of vring. + * x86 pagesize again. */ +#define VIRTIO_PCI_VRING_ALIGN 4096 + /* QEMU doesn't strictly need write barriers since everything runs in * lock-step. We'll leave the calls to wmb() in though to make it obvious for * KVM or if kqemu gets SMP support. @@ -110,7 +118,9 @@ static void virtqueue_init(VirtQueue *vq, target_phys_addr_t pa) { vq->vring.desc = pa; vq->vring.avail = pa + vq->vring.num * sizeof(VRingDesc); - vq->vring.used = TARGET_PAGE_ALIGN(vq->vring.avail + offsetof(VRingAvail, ring[vq->vring.num])); + vq->vring.used = vring_align(vq->vring.avail + + offsetof(VRingAvail, ring[vq->vring.num]), + VIRTIO_PCI_VRING_ALIGN); } static inline uint64_t vring_desc_addr(VirtQueue *vq, int i) @@ -386,7 +396,7 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val) vdev->features = val; break; case VIRTIO_PCI_QUEUE_PFN: - pa = (ram_addr_t)val << TARGET_PAGE_BITS; + pa = (ram_addr_t)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT; vdev->vq[vdev->queue_sel].pfn = val; if (pa == 0) virtio_reset(vdev); @@ -660,7 +670,7 @@ void virtio_load(VirtIODevice *vdev, QEMUFile *f) if (vdev->vq[i].pfn) { target_phys_addr_t pa; - pa = (ram_addr_t)vdev->vq[i].pfn << TARGET_PAGE_BITS; + pa = (ram_addr_t)vdev->vq[i].pfn << VIRTIO_PCI_QUEUE_ADDR_SHIFT; virtqueue_init(&vdev->vq[i], pa); } } diff --git a/hw/virtio.h b/hw/virtio.h index 1df8f83..c23f38c 100644 --- a/hw/virtio.h +++ b/hw/virtio.h @@ -47,6 +47,11 @@ /* This means don't interrupt guest when buffer consumed. */ #define VRING_AVAIL_F_NO_INTERRUPT 1 +static inline vring_align(unsigned long addr, unsigned long align) +{ + return (addr + align - 1) & ~(align - 1); +} + typedef struct VirtQueue VirtQueue; typedef struct VirtIODevice VirtIODevice; -- 1.5.6.5