mirror of https://github.com/xemu-project/xemu.git
xen: convert to MemoryListener API
Signed-off-by: Avi Kivity <avi@redhat.com>
This commit is contained in:
parent
e34911c420
commit
20581d2078
|
@ -462,7 +462,7 @@ mipsnet_irq(uint32_t isr, uint32_t intctl) "set irq to %d (%02x)"
|
||||||
|
|
||||||
# xen-all.c
|
# xen-all.c
|
||||||
xen_ram_alloc(unsigned long ram_addr, unsigned long size) "requested: %#lx, size %#lx"
|
xen_ram_alloc(unsigned long ram_addr, unsigned long size) "requested: %#lx, size %#lx"
|
||||||
xen_client_set_memory(uint64_t start_addr, unsigned long size, unsigned long phys_offset, bool log_dirty) "%#"PRIx64" size %#lx, offset %#lx, log_dirty %i"
|
xen_client_set_memory(uint64_t start_addr, unsigned long size, bool log_dirty) "%#"PRIx64" size %#lx, log_dirty %i"
|
||||||
|
|
||||||
# xen-mapcache.c
|
# xen-mapcache.c
|
||||||
xen_map_cache(uint64_t phys_addr) "want %#"PRIx64
|
xen_map_cache(uint64_t phys_addr) "want %#"PRIx64
|
||||||
|
|
124
xen-all.c
124
xen-all.c
|
@ -63,6 +63,7 @@ static inline ioreq_t *xen_vcpu_ioreq(shared_iopage_t *shared_page, int vcpu)
|
||||||
typedef struct XenPhysmap {
|
typedef struct XenPhysmap {
|
||||||
target_phys_addr_t start_addr;
|
target_phys_addr_t start_addr;
|
||||||
ram_addr_t size;
|
ram_addr_t size;
|
||||||
|
MemoryRegion *mr;
|
||||||
target_phys_addr_t phys_offset;
|
target_phys_addr_t phys_offset;
|
||||||
|
|
||||||
QLIST_ENTRY(XenPhysmap) list;
|
QLIST_ENTRY(XenPhysmap) list;
|
||||||
|
@ -80,8 +81,9 @@ typedef struct XenIOState {
|
||||||
int send_vcpu;
|
int send_vcpu;
|
||||||
|
|
||||||
struct xs_handle *xenstore;
|
struct xs_handle *xenstore;
|
||||||
CPUPhysMemoryClient client;
|
MemoryListener memory_listener;
|
||||||
QLIST_HEAD(, XenPhysmap) physmap;
|
QLIST_HEAD(, XenPhysmap) physmap;
|
||||||
|
target_phys_addr_t free_phys_offset;
|
||||||
const XenPhysmap *log_for_dirtybit;
|
const XenPhysmap *log_for_dirtybit;
|
||||||
|
|
||||||
Notifier exit;
|
Notifier exit;
|
||||||
|
@ -226,13 +228,14 @@ static XenPhysmap *get_physmapping(XenIOState *state,
|
||||||
static int xen_add_to_physmap(XenIOState *state,
|
static int xen_add_to_physmap(XenIOState *state,
|
||||||
target_phys_addr_t start_addr,
|
target_phys_addr_t start_addr,
|
||||||
ram_addr_t size,
|
ram_addr_t size,
|
||||||
target_phys_addr_t phys_offset)
|
MemoryRegion *mr,
|
||||||
|
target_phys_addr_t offset_within_region)
|
||||||
{
|
{
|
||||||
unsigned long i = 0;
|
unsigned long i = 0;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
XenPhysmap *physmap = NULL;
|
XenPhysmap *physmap = NULL;
|
||||||
target_phys_addr_t pfn, start_gpfn;
|
target_phys_addr_t pfn, start_gpfn;
|
||||||
RAMBlock *block;
|
target_phys_addr_t phys_offset = memory_region_get_ram_addr(mr);
|
||||||
|
|
||||||
if (get_physmapping(state, start_addr, size)) {
|
if (get_physmapping(state, start_addr, size)) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -245,17 +248,13 @@ static int xen_add_to_physmap(XenIOState *state,
|
||||||
* the linear framebuffer to be that region.
|
* the linear framebuffer to be that region.
|
||||||
* Avoid tracking any regions that is not videoram and avoid tracking
|
* Avoid tracking any regions that is not videoram and avoid tracking
|
||||||
* the legacy vga region. */
|
* the legacy vga region. */
|
||||||
QLIST_FOREACH(block, &ram_list.blocks, next) {
|
if (mr == framebuffer && start_addr > 0xbffff) {
|
||||||
if (!strcmp(block->idstr, "vga.vram") && block->offset == phys_offset
|
|
||||||
&& start_addr > 0xbffff) {
|
|
||||||
goto go_physmap;
|
goto go_physmap;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
go_physmap:
|
go_physmap:
|
||||||
DPRINTF("mapping vram to %llx - %llx, from %llx\n",
|
DPRINTF("mapping vram to %llx - %llx\n", start_addr, start_addr + size);
|
||||||
start_addr, start_addr + size, phys_offset);
|
|
||||||
|
|
||||||
pfn = phys_offset >> TARGET_PAGE_BITS;
|
pfn = phys_offset >> TARGET_PAGE_BITS;
|
||||||
start_gpfn = start_addr >> TARGET_PAGE_BITS;
|
start_gpfn = start_addr >> TARGET_PAGE_BITS;
|
||||||
|
@ -334,7 +333,8 @@ static int xen_remove_from_physmap(XenIOState *state,
|
||||||
static int xen_add_to_physmap(XenIOState *state,
|
static int xen_add_to_physmap(XenIOState *state,
|
||||||
target_phys_addr_t start_addr,
|
target_phys_addr_t start_addr,
|
||||||
ram_addr_t size,
|
ram_addr_t size,
|
||||||
target_phys_addr_t phys_offset)
|
MemoryRegion *mr,
|
||||||
|
target_phys_addr_t offset_within_region)
|
||||||
{
|
{
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
@ -347,33 +347,35 @@ static int xen_remove_from_physmap(XenIOState *state,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void xen_client_set_memory(struct CPUPhysMemoryClient *client,
|
static void xen_set_memory(struct MemoryListener *listener,
|
||||||
target_phys_addr_t start_addr,
|
MemoryRegionSection *section,
|
||||||
ram_addr_t size,
|
bool add)
|
||||||
ram_addr_t phys_offset,
|
|
||||||
bool log_dirty)
|
|
||||||
{
|
{
|
||||||
XenIOState *state = container_of(client, XenIOState, client);
|
XenIOState *state = container_of(listener, XenIOState, memory_listener);
|
||||||
ram_addr_t flags = phys_offset & ~TARGET_PAGE_MASK;
|
target_phys_addr_t start_addr = section->offset_within_address_space;
|
||||||
|
ram_addr_t size = section->size;
|
||||||
|
bool log_dirty = memory_region_is_logging(section->mr);
|
||||||
hvmmem_type_t mem_type;
|
hvmmem_type_t mem_type;
|
||||||
|
|
||||||
if (!(start_addr != phys_offset
|
if (!memory_region_is_ram(section->mr)) {
|
||||||
&& ( (log_dirty && flags < IO_MEM_UNASSIGNED)
|
|
||||||
|| (!log_dirty && flags == IO_MEM_UNASSIGNED)))) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_xen_client_set_memory(start_addr, size, phys_offset, log_dirty);
|
if (!(section->mr != &ram_memory
|
||||||
|
&& ( (log_dirty && add) || (!log_dirty && !add)))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
trace_xen_client_set_memory(start_addr, size, log_dirty);
|
||||||
|
|
||||||
start_addr &= TARGET_PAGE_MASK;
|
start_addr &= TARGET_PAGE_MASK;
|
||||||
size = TARGET_PAGE_ALIGN(size);
|
size = TARGET_PAGE_ALIGN(size);
|
||||||
phys_offset &= TARGET_PAGE_MASK;
|
|
||||||
|
|
||||||
switch (flags) {
|
if (add) {
|
||||||
case IO_MEM_RAM:
|
if (!memory_region_is_rom(section->mr)) {
|
||||||
xen_add_to_physmap(state, start_addr, size, phys_offset);
|
xen_add_to_physmap(state, start_addr, size,
|
||||||
break;
|
section->mr, section->offset_within_region);
|
||||||
case IO_MEM_ROM:
|
} else {
|
||||||
mem_type = HVMMEM_ram_ro;
|
mem_type = HVMMEM_ram_ro;
|
||||||
if (xc_hvm_set_mem_type(xen_xc, xen_domid, mem_type,
|
if (xc_hvm_set_mem_type(xen_xc, xen_domid, mem_type,
|
||||||
start_addr >> TARGET_PAGE_BITS,
|
start_addr >> TARGET_PAGE_BITS,
|
||||||
|
@ -381,15 +383,26 @@ static void xen_client_set_memory(struct CPUPhysMemoryClient *client,
|
||||||
DPRINTF("xc_hvm_set_mem_type error, addr: "TARGET_FMT_plx"\n",
|
DPRINTF("xc_hvm_set_mem_type error, addr: "TARGET_FMT_plx"\n",
|
||||||
start_addr);
|
start_addr);
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case IO_MEM_UNASSIGNED:
|
} else {
|
||||||
if (xen_remove_from_physmap(state, start_addr, size) < 0) {
|
if (xen_remove_from_physmap(state, start_addr, size) < 0) {
|
||||||
DPRINTF("physmapping does not exist at "TARGET_FMT_plx"\n", start_addr);
|
DPRINTF("physmapping does not exist at "TARGET_FMT_plx"\n", start_addr);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void xen_region_add(MemoryListener *listener,
|
||||||
|
MemoryRegionSection *section)
|
||||||
|
{
|
||||||
|
xen_set_memory(listener, section, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void xen_region_del(MemoryListener *listener,
|
||||||
|
MemoryRegionSection *section)
|
||||||
|
{
|
||||||
|
xen_set_memory(listener, section, false);
|
||||||
|
}
|
||||||
|
|
||||||
static int xen_sync_dirty_bitmap(XenIOState *state,
|
static int xen_sync_dirty_bitmap(XenIOState *state,
|
||||||
target_phys_addr_t start_addr,
|
target_phys_addr_t start_addr,
|
||||||
ram_addr_t size)
|
ram_addr_t size)
|
||||||
|
@ -433,43 +446,54 @@ static int xen_sync_dirty_bitmap(XenIOState *state,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xen_log_start(CPUPhysMemoryClient *client, target_phys_addr_t phys_addr, ram_addr_t size)
|
static void xen_log_start(MemoryListener *listener,
|
||||||
|
MemoryRegionSection *section)
|
||||||
{
|
{
|
||||||
XenIOState *state = container_of(client, XenIOState, client);
|
XenIOState *state = container_of(listener, XenIOState, memory_listener);
|
||||||
|
int r;
|
||||||
|
|
||||||
return xen_sync_dirty_bitmap(state, phys_addr, size);
|
r = xen_sync_dirty_bitmap(state, section->offset_within_address_space,
|
||||||
|
section->size);
|
||||||
|
assert(r >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xen_log_stop(CPUPhysMemoryClient *client, target_phys_addr_t phys_addr, ram_addr_t size)
|
static void xen_log_stop(MemoryListener *listener, MemoryRegionSection *section)
|
||||||
{
|
{
|
||||||
XenIOState *state = container_of(client, XenIOState, client);
|
XenIOState *state = container_of(listener, XenIOState, memory_listener);
|
||||||
|
int r;
|
||||||
|
|
||||||
state->log_for_dirtybit = NULL;
|
state->log_for_dirtybit = NULL;
|
||||||
/* Disable dirty bit tracking */
|
/* Disable dirty bit tracking */
|
||||||
return xc_hvm_track_dirty_vram(xen_xc, xen_domid, 0, 0, NULL);
|
r = xc_hvm_track_dirty_vram(xen_xc, xen_domid, 0, 0, NULL);
|
||||||
|
assert(r >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xen_client_sync_dirty_bitmap(struct CPUPhysMemoryClient *client,
|
static void xen_log_sync(MemoryListener *listener, MemoryRegionSection *section)
|
||||||
target_phys_addr_t start_addr,
|
|
||||||
target_phys_addr_t end_addr)
|
|
||||||
{
|
{
|
||||||
XenIOState *state = container_of(client, XenIOState, client);
|
XenIOState *state = container_of(listener, XenIOState, memory_listener);
|
||||||
|
int r;
|
||||||
|
|
||||||
return xen_sync_dirty_bitmap(state, start_addr, end_addr - start_addr);
|
r = xen_sync_dirty_bitmap(state, section->offset_within_address_space,
|
||||||
|
section->size);
|
||||||
|
assert(r >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xen_client_migration_log(struct CPUPhysMemoryClient *client,
|
static void xen_log_global_start(MemoryListener *listener)
|
||||||
int enable)
|
|
||||||
{
|
{
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static CPUPhysMemoryClient xen_cpu_phys_memory_client = {
|
static void xen_log_global_stop(MemoryListener *listener)
|
||||||
.set_memory = xen_client_set_memory,
|
{
|
||||||
.sync_dirty_bitmap = xen_client_sync_dirty_bitmap,
|
}
|
||||||
.migration_log = xen_client_migration_log,
|
|
||||||
|
static MemoryListener xen_memory_listener = {
|
||||||
|
.region_add = xen_region_add,
|
||||||
|
.region_del = xen_region_del,
|
||||||
.log_start = xen_log_start,
|
.log_start = xen_log_start,
|
||||||
.log_stop = xen_log_stop,
|
.log_stop = xen_log_stop,
|
||||||
|
.log_sync = xen_log_sync,
|
||||||
|
.log_global_start = xen_log_global_start,
|
||||||
|
.log_global_stop = xen_log_global_stop,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* VCPU Operations, MMIO, IO ring ... */
|
/* VCPU Operations, MMIO, IO ring ... */
|
||||||
|
@ -947,9 +971,9 @@ int xen_hvm_init(void)
|
||||||
|
|
||||||
qemu_add_vm_change_state_handler(xen_hvm_change_state_handler, state);
|
qemu_add_vm_change_state_handler(xen_hvm_change_state_handler, state);
|
||||||
|
|
||||||
state->client = xen_cpu_phys_memory_client;
|
state->memory_listener = xen_memory_listener;
|
||||||
QLIST_INIT(&state->physmap);
|
QLIST_INIT(&state->physmap);
|
||||||
cpu_register_phys_memory_client(&state->client);
|
memory_listener_register(&state->memory_listener);
|
||||||
state->log_for_dirtybit = NULL;
|
state->log_for_dirtybit = NULL;
|
||||||
|
|
||||||
/* Initialize backend core & drivers */
|
/* Initialize backend core & drivers */
|
||||||
|
|
Loading…
Reference in New Issue