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_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_map_cache(uint64_t phys_addr) "want %#"PRIx64
|
||||
|
138
xen-all.c
138
xen-all.c
@ -63,6 +63,7 @@ static inline ioreq_t *xen_vcpu_ioreq(shared_iopage_t *shared_page, int vcpu)
|
||||
typedef struct XenPhysmap {
|
||||
target_phys_addr_t start_addr;
|
||||
ram_addr_t size;
|
||||
MemoryRegion *mr;
|
||||
target_phys_addr_t phys_offset;
|
||||
|
||||
QLIST_ENTRY(XenPhysmap) list;
|
||||
@ -80,8 +81,9 @@ typedef struct XenIOState {
|
||||
int send_vcpu;
|
||||
|
||||
struct xs_handle *xenstore;
|
||||
CPUPhysMemoryClient client;
|
||||
MemoryListener memory_listener;
|
||||
QLIST_HEAD(, XenPhysmap) physmap;
|
||||
target_phys_addr_t free_phys_offset;
|
||||
const XenPhysmap *log_for_dirtybit;
|
||||
|
||||
Notifier exit;
|
||||
@ -226,13 +228,14 @@ static XenPhysmap *get_physmapping(XenIOState *state,
|
||||
static int xen_add_to_physmap(XenIOState *state,
|
||||
target_phys_addr_t start_addr,
|
||||
ram_addr_t size,
|
||||
target_phys_addr_t phys_offset)
|
||||
MemoryRegion *mr,
|
||||
target_phys_addr_t offset_within_region)
|
||||
{
|
||||
unsigned long i = 0;
|
||||
int rc = 0;
|
||||
XenPhysmap *physmap = NULL;
|
||||
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)) {
|
||||
return 0;
|
||||
@ -245,17 +248,13 @@ static int xen_add_to_physmap(XenIOState *state,
|
||||
* the linear framebuffer to be that region.
|
||||
* Avoid tracking any regions that is not videoram and avoid tracking
|
||||
* the legacy vga region. */
|
||||
QLIST_FOREACH(block, &ram_list.blocks, next) {
|
||||
if (!strcmp(block->idstr, "vga.vram") && block->offset == phys_offset
|
||||
&& start_addr > 0xbffff) {
|
||||
goto go_physmap;
|
||||
}
|
||||
if (mr == framebuffer && start_addr > 0xbffff) {
|
||||
goto go_physmap;
|
||||
}
|
||||
return -1;
|
||||
|
||||
go_physmap:
|
||||
DPRINTF("mapping vram to %llx - %llx, from %llx\n",
|
||||
start_addr, start_addr + size, phys_offset);
|
||||
DPRINTF("mapping vram to %llx - %llx\n", start_addr, start_addr + size);
|
||||
|
||||
pfn = phys_offset >> 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,
|
||||
target_phys_addr_t start_addr,
|
||||
ram_addr_t size,
|
||||
target_phys_addr_t phys_offset)
|
||||
MemoryRegion *mr,
|
||||
target_phys_addr_t offset_within_region)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
@ -347,49 +347,62 @@ static int xen_remove_from_physmap(XenIOState *state,
|
||||
}
|
||||
#endif
|
||||
|
||||
static void xen_client_set_memory(struct CPUPhysMemoryClient *client,
|
||||
target_phys_addr_t start_addr,
|
||||
ram_addr_t size,
|
||||
ram_addr_t phys_offset,
|
||||
bool log_dirty)
|
||||
static void xen_set_memory(struct MemoryListener *listener,
|
||||
MemoryRegionSection *section,
|
||||
bool add)
|
||||
{
|
||||
XenIOState *state = container_of(client, XenIOState, client);
|
||||
ram_addr_t flags = phys_offset & ~TARGET_PAGE_MASK;
|
||||
XenIOState *state = container_of(listener, XenIOState, memory_listener);
|
||||
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;
|
||||
|
||||
if (!(start_addr != phys_offset
|
||||
&& ( (log_dirty && flags < IO_MEM_UNASSIGNED)
|
||||
|| (!log_dirty && flags == IO_MEM_UNASSIGNED)))) {
|
||||
if (!memory_region_is_ram(section->mr)) {
|
||||
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;
|
||||
size = TARGET_PAGE_ALIGN(size);
|
||||
phys_offset &= TARGET_PAGE_MASK;
|
||||
|
||||
switch (flags) {
|
||||
case IO_MEM_RAM:
|
||||
xen_add_to_physmap(state, start_addr, size, phys_offset);
|
||||
break;
|
||||
case IO_MEM_ROM:
|
||||
mem_type = HVMMEM_ram_ro;
|
||||
if (xc_hvm_set_mem_type(xen_xc, xen_domid, mem_type,
|
||||
start_addr >> TARGET_PAGE_BITS,
|
||||
size >> TARGET_PAGE_BITS)) {
|
||||
DPRINTF("xc_hvm_set_mem_type error, addr: "TARGET_FMT_plx"\n",
|
||||
start_addr);
|
||||
if (add) {
|
||||
if (!memory_region_is_rom(section->mr)) {
|
||||
xen_add_to_physmap(state, start_addr, size,
|
||||
section->mr, section->offset_within_region);
|
||||
} else {
|
||||
mem_type = HVMMEM_ram_ro;
|
||||
if (xc_hvm_set_mem_type(xen_xc, xen_domid, mem_type,
|
||||
start_addr >> TARGET_PAGE_BITS,
|
||||
size >> TARGET_PAGE_BITS)) {
|
||||
DPRINTF("xc_hvm_set_mem_type error, addr: "TARGET_FMT_plx"\n",
|
||||
start_addr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IO_MEM_UNASSIGNED:
|
||||
} else {
|
||||
if (xen_remove_from_physmap(state, start_addr, size) < 0) {
|
||||
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,
|
||||
target_phys_addr_t start_addr,
|
||||
ram_addr_t size)
|
||||
@ -433,43 +446,54 @@ static int xen_sync_dirty_bitmap(XenIOState *state,
|
||||
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;
|
||||
/* 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,
|
||||
target_phys_addr_t start_addr,
|
||||
target_phys_addr_t end_addr)
|
||||
static void xen_log_sync(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, 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,
|
||||
int enable)
|
||||
static void xen_log_global_start(MemoryListener *listener)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static CPUPhysMemoryClient xen_cpu_phys_memory_client = {
|
||||
.set_memory = xen_client_set_memory,
|
||||
.sync_dirty_bitmap = xen_client_sync_dirty_bitmap,
|
||||
.migration_log = xen_client_migration_log,
|
||||
static void xen_log_global_stop(MemoryListener *listener)
|
||||
{
|
||||
}
|
||||
|
||||
static MemoryListener xen_memory_listener = {
|
||||
.region_add = xen_region_add,
|
||||
.region_del = xen_region_del,
|
||||
.log_start = xen_log_start,
|
||||
.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 ... */
|
||||
@ -947,9 +971,9 @@ int xen_hvm_init(void)
|
||||
|
||||
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);
|
||||
cpu_register_phys_memory_client(&state->client);
|
||||
memory_listener_register(&state->memory_listener);
|
||||
state->log_for_dirtybit = NULL;
|
||||
|
||||
/* Initialize backend core & drivers */
|
||||
|
Loading…
Reference in New Issue
Block a user