Revision f46f15bc
b/hw/virtio.c | ||
---|---|---|
52 | 52 |
/* Virtio ABI version, if we increment this, we break the guest driver. */ |
53 | 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 | 63 |
/* QEMU doesn't strictly need write barriers since everything runs in |
56 | 64 |
* lock-step. We'll leave the calls to wmb() in though to make it obvious for |
57 | 65 |
* KVM or if kqemu gets SMP support. |
... | ... | |
147 | 155 |
{ |
148 | 156 |
vq->vring.desc = pa; |
149 | 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 | 163 |
static inline uint64_t vring_desc_addr(VirtQueue *vq, int i) |
... | ... | |
501 | 511 |
vdev->features = val; |
502 | 512 |
break; |
503 | 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 | 515 |
vdev->vq[vdev->queue_sel].pfn = val; |
506 | 516 |
if (pa == 0) { |
507 | 517 |
virtio_reset(vdev); |
... | ... | |
776 | 786 |
if (vdev->vq[i].pfn) { |
777 | 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 | 790 |
virtqueue_init(&vdev->vq[i], pa); |
781 | 791 |
} |
782 | 792 |
} |
b/hw/virtio.h | ||
---|---|---|
48 | 48 |
|
49 | 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 | 57 |
typedef struct VirtQueue VirtQueue; |
52 | 58 |
typedef struct VirtIODevice VirtIODevice; |
53 | 59 |
|
Also available in: Unified diff