block/nvme: Fix use of write-only doorbells page on Aarch64 arch
qemu_vfio_pci_map_bar() calls mmap(), and mmap(2) states: 'offset' must be a multiple of the page size as returned by sysconf(_SC_PAGE_SIZE). In commitf68453237b
we started to use an offset of 4K which broke this contract on Aarch64 arch. Fix by mapping at offset 0, and and accessing doorbells at offset=4K. Fixes:f68453237b
("block/nvme: Map doorbells pages write-only") Reported-by: Eric Auger <eric.auger@redhat.com> Reviewed-by: Eric Auger <eric.auger@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Tested-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com> Message-id: 20201029093306.1063879-24-philmd@redhat.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Tested-by: Eric Auger <eric.auger@redhat.com>
This commit is contained in:
parent
9e13d59884
commit
4b19e9b815
11
block/nvme.c
11
block/nvme.c
@ -94,6 +94,7 @@ typedef struct {
|
|||||||
struct BDRVNVMeState {
|
struct BDRVNVMeState {
|
||||||
AioContext *aio_context;
|
AioContext *aio_context;
|
||||||
QEMUVFIOState *vfio;
|
QEMUVFIOState *vfio;
|
||||||
|
void *bar0_wo_map;
|
||||||
/* Memory mapped registers */
|
/* Memory mapped registers */
|
||||||
volatile struct {
|
volatile struct {
|
||||||
uint32_t sq_tail;
|
uint32_t sq_tail;
|
||||||
@ -777,8 +778,10 @@ static int nvme_init(BlockDriverState *bs, const char *device, int namespace,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s->doorbells = qemu_vfio_pci_map_bar(s->vfio, 0, sizeof(NvmeBar),
|
s->bar0_wo_map = qemu_vfio_pci_map_bar(s->vfio, 0, 0,
|
||||||
NVME_DOORBELL_SIZE, PROT_WRITE, errp);
|
sizeof(NvmeBar) + NVME_DOORBELL_SIZE,
|
||||||
|
PROT_WRITE, errp);
|
||||||
|
s->doorbells = (void *)((uintptr_t)s->bar0_wo_map + sizeof(NvmeBar));
|
||||||
if (!s->doorbells) {
|
if (!s->doorbells) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
@ -910,8 +913,8 @@ static void nvme_close(BlockDriverState *bs)
|
|||||||
&s->irq_notifier[MSIX_SHARED_IRQ_IDX],
|
&s->irq_notifier[MSIX_SHARED_IRQ_IDX],
|
||||||
false, NULL, NULL);
|
false, NULL, NULL);
|
||||||
event_notifier_cleanup(&s->irq_notifier[MSIX_SHARED_IRQ_IDX]);
|
event_notifier_cleanup(&s->irq_notifier[MSIX_SHARED_IRQ_IDX]);
|
||||||
qemu_vfio_pci_unmap_bar(s->vfio, 0, (void *)s->doorbells,
|
qemu_vfio_pci_unmap_bar(s->vfio, 0, s->bar0_wo_map,
|
||||||
sizeof(NvmeBar), NVME_DOORBELL_SIZE);
|
0, sizeof(NvmeBar) + NVME_DOORBELL_SIZE);
|
||||||
qemu_vfio_close(s->vfio);
|
qemu_vfio_close(s->vfio);
|
||||||
|
|
||||||
g_free(s->device);
|
g_free(s->device);
|
||||||
|
Loading…
Reference in New Issue
Block a user