xen_pt: use separate MemoryListeners for memory and I/O
Using an unfiltered memory listener will cause regions to be reported fails multiple times if we have more than two address spaces. Use a separate listener for memory and I/O, and utilize MemoryListener's address space filtering to fix this. Signed-off-by: Avi Kivity <avi@redhat.com>
This commit is contained in:
parent
d22b096ef6
commit
12b40e471f
38
hw/xen_pt.c
38
hw/xen_pt.c
|
@ -59,6 +59,7 @@
|
||||||
#include "xen_backend.h"
|
#include "xen_backend.h"
|
||||||
#include "xen_pt.h"
|
#include "xen_pt.h"
|
||||||
#include "range.h"
|
#include "range.h"
|
||||||
|
#include "exec-memory.h"
|
||||||
|
|
||||||
#define XEN_PT_NR_IRQS (256)
|
#define XEN_PT_NR_IRQS (256)
|
||||||
static uint8_t xen_pt_mapped_machine_irq[XEN_PT_NR_IRQS] = {0};
|
static uint8_t xen_pt_mapped_machine_irq[XEN_PT_NR_IRQS] = {0};
|
||||||
|
@ -624,6 +625,22 @@ static void xen_pt_region_del(MemoryListener *l, MemoryRegionSection *sec)
|
||||||
xen_pt_region_update(s, sec, false);
|
xen_pt_region_update(s, sec, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void xen_pt_io_region_add(MemoryListener *l, MemoryRegionSection *sec)
|
||||||
|
{
|
||||||
|
XenPCIPassthroughState *s = container_of(l, XenPCIPassthroughState,
|
||||||
|
io_listener);
|
||||||
|
|
||||||
|
xen_pt_region_update(s, sec, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void xen_pt_io_region_del(MemoryListener *l, MemoryRegionSection *sec)
|
||||||
|
{
|
||||||
|
XenPCIPassthroughState *s = container_of(l, XenPCIPassthroughState,
|
||||||
|
io_listener);
|
||||||
|
|
||||||
|
xen_pt_region_update(s, sec, false);
|
||||||
|
}
|
||||||
|
|
||||||
static void xen_pt_region_nop(MemoryListener *l, MemoryRegionSection *s)
|
static void xen_pt_region_nop(MemoryListener *l, MemoryRegionSection *s)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -657,6 +674,22 @@ static const MemoryListener xen_pt_memory_listener = {
|
||||||
.priority = 10,
|
.priority = 10,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const MemoryListener xen_pt_io_listener = {
|
||||||
|
.begin = xen_pt_begin,
|
||||||
|
.commit = xen_pt_commit,
|
||||||
|
.region_add = xen_pt_io_region_add,
|
||||||
|
.region_nop = xen_pt_region_nop,
|
||||||
|
.region_del = xen_pt_io_region_del,
|
||||||
|
.log_start = xen_pt_log_fns,
|
||||||
|
.log_stop = xen_pt_log_fns,
|
||||||
|
.log_sync = xen_pt_log_fns,
|
||||||
|
.log_global_start = xen_pt_log_global_fns,
|
||||||
|
.log_global_stop = xen_pt_log_global_fns,
|
||||||
|
.eventfd_add = xen_pt_eventfd_fns,
|
||||||
|
.eventfd_del = xen_pt_eventfd_fns,
|
||||||
|
.priority = 10,
|
||||||
|
};
|
||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
|
|
||||||
static int xen_pt_initfn(PCIDevice *d)
|
static int xen_pt_initfn(PCIDevice *d)
|
||||||
|
@ -694,6 +727,7 @@ static int xen_pt_initfn(PCIDevice *d)
|
||||||
}
|
}
|
||||||
|
|
||||||
s->memory_listener = xen_pt_memory_listener;
|
s->memory_listener = xen_pt_memory_listener;
|
||||||
|
s->io_listener = xen_pt_io_listener;
|
||||||
|
|
||||||
/* Handle real device's MMIO/PIO BARs */
|
/* Handle real device's MMIO/PIO BARs */
|
||||||
xen_pt_register_regions(s);
|
xen_pt_register_regions(s);
|
||||||
|
@ -760,7 +794,8 @@ static int xen_pt_initfn(PCIDevice *d)
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
memory_listener_register(&s->memory_listener, NULL);
|
memory_listener_register(&s->memory_listener, get_system_memory());
|
||||||
|
memory_listener_register(&s->io_listener, get_system_io());
|
||||||
XEN_PT_LOG(d, "Real physical device %02x:%02x.%d registered successfuly!\n",
|
XEN_PT_LOG(d, "Real physical device %02x:%02x.%d registered successfuly!\n",
|
||||||
bus, slot, func);
|
bus, slot, func);
|
||||||
|
|
||||||
|
@ -815,6 +850,7 @@ static void xen_pt_unregister_device(PCIDevice *d)
|
||||||
|
|
||||||
xen_pt_unregister_regions(s);
|
xen_pt_unregister_regions(s);
|
||||||
memory_listener_unregister(&s->memory_listener);
|
memory_listener_unregister(&s->memory_listener);
|
||||||
|
memory_listener_unregister(&s->io_listener);
|
||||||
|
|
||||||
xen_host_pci_device_put(&s->real_device);
|
xen_host_pci_device_put(&s->real_device);
|
||||||
}
|
}
|
||||||
|
|
|
@ -209,6 +209,7 @@ struct XenPCIPassthroughState {
|
||||||
MemoryRegion rom;
|
MemoryRegion rom;
|
||||||
|
|
||||||
MemoryListener memory_listener;
|
MemoryListener memory_listener;
|
||||||
|
MemoryListener io_listener;
|
||||||
};
|
};
|
||||||
|
|
||||||
int xen_pt_config_init(XenPCIPassthroughState *s);
|
int xen_pt_config_init(XenPCIPassthroughState *s);
|
||||||
|
|
Loading…
Reference in a new issue