anthony.perard@citrix.com
2011-Jan-14 18:10 UTC
[Xen-devel] [PATCH V2 0/3] Xen VGA dirtybit support
From: Anthony PERARD <anthony.perard@citrix.com> Hi, This three patches provides the support for sync dirty bitmap. The sync dirty bitmap is not provided for Xen 3.3. This series depends on the other series "Xen device model support". Change v1 -> v2: * Intruduce a patch to put log_start/log_stop in CPUPhysMemoryClient; * There are now only one function to get/check for old physmapping (get_physmapping); * The function xen_sync_dirty_bitmap only do a sync on range that are physmapped and only on one range; * Physmapping list and CPUPhysMemoryClient is now in XenIOState structure; * Introduce log_for_dirtybit that hold the range for dirty bit tracking. Anthony PERARD (3): Introduce log_start/log_stop in CPUPhysMemoryClient xen: Add xc_domain_add_to_physmap to xen_interface. xen: Introduce VGA sync dirty bitmap support configure | 29 ++++++- cpu-all.h | 6 + cpu-common.h | 4 + exec.c | 42 +++++++++ hw/vga.c | 31 +++--- hw/vhost.c | 16 +++ hw/xen_interfaces.c | 31 ++++++ hw/xen_interfaces.h | 5 + hw/xen_redirect.h | 1 + kvm-all.c | 8 +- kvm-stub.c | 10 -- kvm.h | 3 - xen-all.c | 253 +++++++++++++++++++++++++++++++++++++++++++++++++++ 13 files changed, 408 insertions(+), 31 deletions(-) -- Anthony PERARD _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
anthony.perard@citrix.com
2011-Jan-14 18:10 UTC
[Xen-devel] [PATCH V2 1/3] Introduce log_start/log_stop in CPUPhysMemoryClient
From: Anthony PERARD <anthony.perard@citrix.com> In order to use log_start/log_stop with Xen as well in the vga code, this two operations have been put in CPUPhysMemoryClient. The two new functions cpu_physical_log_start,cpu_physical_log_stop are used in hw/vga.c and replace the kvm_log_start/stop. With this, vga does no longer depends on kvm header. Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> --- cpu-all.h | 6 ++++++ cpu-common.h | 4 ++++ exec.c | 42 ++++++++++++++++++++++++++++++++++++++++++ hw/vga.c | 31 ++++++++++++++++--------------- hw/vhost.c | 16 ++++++++++++++++ kvm-all.c | 8 ++++++-- kvm-stub.c | 10 ---------- kvm.h | 3 --- 8 files changed, 90 insertions(+), 30 deletions(-) diff --git a/cpu-all.h b/cpu-all.h index 30ae17d..aaf5442 100644 --- a/cpu-all.h +++ b/cpu-all.h @@ -957,6 +957,12 @@ int cpu_physical_memory_get_dirty_tracking(void); int cpu_physical_sync_dirty_bitmap(target_phys_addr_t start_addr, target_phys_addr_t end_addr); +int cpu_physical_log_start(target_phys_addr_t start_addr, + ram_addr_t size); + +int cpu_physical_log_stop(target_phys_addr_t start_addr, + ram_addr_t size); + void dump_exec_info(FILE *f, fprintf_function cpu_fprintf); #endif /* !CONFIG_USER_ONLY */ diff --git a/cpu-common.h b/cpu-common.h index 8ec01f4..2344842 100644 --- a/cpu-common.h +++ b/cpu-common.h @@ -88,6 +88,10 @@ struct CPUPhysMemoryClient { target_phys_addr_t end_addr); int (*migration_log)(struct CPUPhysMemoryClient *client, int enable); + int (*log_start)(struct CPUPhysMemoryClient *client, + target_phys_addr_t phys_addr, ram_addr_t size); + int (*log_stop)(struct CPUPhysMemoryClient *client, + target_phys_addr_t phys_addr, ram_addr_t size); QLIST_ENTRY(CPUPhysMemoryClient) list; }; diff --git a/exec.c b/exec.c index c6ed96d..609ec88 100644 --- a/exec.c +++ b/exec.c @@ -1734,6 +1734,30 @@ static int cpu_notify_migration_log(int enable) return 0; } +static int cpu_notify_log_start(target_phys_addr_t start, + ram_addr_t size) +{ + CPUPhysMemoryClient *client; + QLIST_FOREACH(client, &memory_client_list, list) { + int r = client->log_start(client, start, size); + if (r < 0) + return r; + } + return 0; +} + +static int cpu_notify_log_stop(target_phys_addr_t start, + ram_addr_t size) +{ + CPUPhysMemoryClient *client; + QLIST_FOREACH(client, &memory_client_list, list) { + int r = client->log_stop(client, start, size); + if (r < 0) + return r; + } + return 0; +} + static void phys_page_for_each_1(CPUPhysMemoryClient *client, int level, void **lp) { @@ -2073,6 +2097,24 @@ int cpu_physical_sync_dirty_bitmap(target_phys_addr_t start_addr, return ret; } +int cpu_physical_log_start(target_phys_addr_t start_addr, + ram_addr_t size) +{ + int ret; + + ret = cpu_notify_log_start(start_addr, size); + return ret; +} + +int cpu_physical_log_stop(target_phys_addr_t start_addr, + ram_addr_t size) +{ + int ret; + + ret = cpu_notify_log_stop(start_addr, size); + return ret; +} + static inline void tlb_update_dirty(CPUTLBEntry *tlb_entry) { ram_addr_t ram_addr; diff --git a/hw/vga.c b/hw/vga.c index c057f4f..a9bf172 100644 --- a/hw/vga.c +++ b/hw/vga.c @@ -28,7 +28,6 @@ #include "vga_int.h" #include "pixel_ops.h" #include "qemu-timer.h" -#include "kvm.h" //#define DEBUG_VGA //#define DEBUG_VGA_MEM @@ -1597,34 +1596,36 @@ static void vga_sync_dirty_bitmap(VGACommonState *s) void vga_dirty_log_start(VGACommonState *s) { - if (kvm_enabled() && s->map_addr) - kvm_log_start(s->map_addr, s->map_end - s->map_addr); + if (s->map_addr) { + cpu_physical_log_start(s->map_addr, s->map_end - s->map_addr); + } - if (kvm_enabled() && s->lfb_vram_mapped) { - kvm_log_start(isa_mem_base + 0xa0000, 0x8000); - kvm_log_start(isa_mem_base + 0xa8000, 0x8000); + if (s->lfb_vram_mapped) { + cpu_physical_log_start(isa_mem_base + 0xa0000, 0x8000); + cpu_physical_log_start(isa_mem_base + 0xa8000, 0x8000); } #ifdef CONFIG_BOCHS_VBE - if (kvm_enabled() && s->vbe_mapped) { - kvm_log_start(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size); + if (s->vbe_mapped) { + cpu_physical_log_start(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size); } #endif } void vga_dirty_log_stop(VGACommonState *s) { - if (kvm_enabled() && s->map_addr) - kvm_log_stop(s->map_addr, s->map_end - s->map_addr); + if (s->map_addr) { + cpu_physical_log_stop(s->map_addr, s->map_end - s->map_addr); + } - if (kvm_enabled() && s->lfb_vram_mapped) { - kvm_log_stop(isa_mem_base + 0xa0000, 0x8000); - kvm_log_stop(isa_mem_base + 0xa8000, 0x8000); + if (s->lfb_vram_mapped) { + cpu_physical_log_stop(isa_mem_base + 0xa0000, 0x8000); + cpu_physical_log_stop(isa_mem_base + 0xa8000, 0x8000); } #ifdef CONFIG_BOCHS_VBE - if (kvm_enabled() && s->vbe_mapped) { - kvm_log_stop(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size); + if (s->vbe_mapped) { + cpu_physical_log_stop(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size); } #endif } diff --git a/hw/vhost.c b/hw/vhost.c index 8586f66..5335178 100644 --- a/hw/vhost.c +++ b/hw/vhost.c @@ -439,6 +439,20 @@ static int vhost_client_migration_log(CPUPhysMemoryClient *client, return 0; } +static int vhost_client_log_start(CPUPhysMemoryClient *client, + target_phys_addr_t start_addr, + ram_addr_t size) +{ + return 0; +} + +static int vhost_client_log_stop(CPUPhysMemoryClient *client, + target_phys_addr_t start_addr, + ram_addr_t size) +{ + return 0; +} + static int vhost_virtqueue_init(struct vhost_dev *dev, struct VirtIODevice *vdev, struct vhost_virtqueue *vq, @@ -606,6 +620,8 @@ int vhost_dev_init(struct vhost_dev *hdev, int devfd) hdev->client.set_memory = vhost_client_set_memory; hdev->client.sync_dirty_bitmap = vhost_client_sync_dirty_bitmap; hdev->client.migration_log = vhost_client_migration_log; + hdev->client.log_start = vhost_client_log_start; + hdev->client.log_stop = vhost_client_log_stop; hdev->mem = qemu_mallocz(offsetof(struct vhost_memory, regions)); hdev->log = NULL; hdev->log_size = 0; diff --git a/kvm-all.c b/kvm-all.c index 37b99c7..aedfe33 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -267,14 +267,16 @@ static int kvm_dirty_pages_log_change(target_phys_addr_t phys_addr, return kvm_set_user_memory_region(s, mem); } -int kvm_log_start(target_phys_addr_t phys_addr, ram_addr_t size) +static int kvm_log_start(CPUPhysMemoryClient *client, + target_phys_addr_t phys_addr, ram_addr_t size) { return kvm_dirty_pages_log_change(phys_addr, size, KVM_MEM_LOG_DIRTY_PAGES, KVM_MEM_LOG_DIRTY_PAGES); } -int kvm_log_stop(target_phys_addr_t phys_addr, ram_addr_t size) +static int kvm_log_stop(CPUPhysMemoryClient *client, + target_phys_addr_t phys_addr, ram_addr_t size) { return kvm_dirty_pages_log_change(phys_addr, size, 0, @@ -596,6 +598,8 @@ static CPUPhysMemoryClient kvm_cpu_phys_memory_client = { .set_memory = kvm_client_set_memory, .sync_dirty_bitmap = kvm_client_sync_dirty_bitmap, .migration_log = kvm_client_migration_log, + .log_start = kvm_log_start, + .log_stop = kvm_log_stop, }; int kvm_init(int smp_cpus) diff --git a/kvm-stub.c b/kvm-stub.c index 5384a4b..41324e4 100644 --- a/kvm-stub.c +++ b/kvm-stub.c @@ -33,16 +33,6 @@ int kvm_init_vcpu(CPUState *env) return -ENOSYS; } -int kvm_log_start(target_phys_addr_t phys_addr, ram_addr_t size) -{ - return -ENOSYS; -} - -int kvm_log_stop(target_phys_addr_t phys_addr, ram_addr_t size) -{ - return -ENOSYS; -} - int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size) { return -ENOSYS; diff --git a/kvm.h b/kvm.h index 60a9b42..fc77b81 100644 --- a/kvm.h +++ b/kvm.h @@ -49,9 +49,6 @@ int kvm_init_vcpu(CPUState *env); int kvm_cpu_exec(CPUState *env); #if !defined(CONFIG_USER_ONLY) -int kvm_log_start(target_phys_addr_t phys_addr, ram_addr_t size); -int kvm_log_stop(target_phys_addr_t phys_addr, ram_addr_t size); - void kvm_setup_guest_memory(void *start, size_t size); int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size); -- 1.7.1 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
anthony.perard@citrix.com
2011-Jan-14 18:10 UTC
[Xen-devel] [PATCH V2 2/3] xen: Add xc_domain_add_to_physmap to xen_interface.
From: Anthony PERARD <anthony.perard@citrix.com> This function will be used to support sync dirty bitmap. This come with a check against every Xen release, and special implementation for Xen version that doesn''t have this specific call. This function will not be usable with Xen 3.3 because the behavior is different. Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> --- configure | 29 ++++++++++++++++++++++++++++- hw/xen_interfaces.c | 31 +++++++++++++++++++++++++++++++ hw/xen_interfaces.h | 5 +++++ hw/xen_redirect.h | 1 + 4 files changed, 65 insertions(+), 1 deletions(-) diff --git a/configure b/configure index f3c524e..642d344 100755 --- a/configure +++ b/configure @@ -1154,6 +1154,7 @@ int main(void) { xs_daemon_open(); xc_interface_open(0, 0, 0); xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0); + xc_domain_add_to_physmap(0, 0, XENMAPSPACE_gmfn, 0, 0); xc_gnttab_open(xc); return 0; } @@ -1173,10 +1174,14 @@ EOF # error HVM_MAX_VCPUS not defined #endif int main(void) { + struct xen_add_to_physmap xatp = { + .domid = 0, .space = XENMAPSPACE_gmfn, .idx = 0, .gpfn = 0, + }; xs_daemon_open(); xc_interface_open(); xc_gnttab_open(); xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0); + xc_memory_op(0, XENMEM_add_to_physmap, &xatp); return 0; } EOF @@ -1185,7 +1190,29 @@ EOF xen_ctrl_version=400 xen=yes - # Xen 3.3.0, 3.4.0 + # Xen 3.4.0 + elif ( + cat > $TMPC <<EOF +#include <xenctrl.h> +#include <xs.h> +int main(void) { + struct xen_add_to_physmap xatp = { + .domid = 0, .space = XENMAPSPACE_gmfn, .idx = 0, .gpfn = 0, + }; + xs_daemon_open(); + xc_interface_open(); + xc_gnttab_open(); + xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0); + xc_memory_op(0, XENMEM_add_to_physmap, &xatp); + return 0; +} +EOF + compile_prog "" "$xen_libs" + ) ; then + xen_ctrl_version=340 + xen=yes + + # Xen 3.3.0 elif ( cat > $TMPC <<EOF #include <xenctrl.h> diff --git a/hw/xen_interfaces.c b/hw/xen_interfaces.c index 129e8b2..4d9862b 100644 --- a/hw/xen_interfaces.c +++ b/hw/xen_interfaces.c @@ -124,6 +124,20 @@ static void *map_foreign_batch(int xc_handle, uint32_t dom, int prot, return xc_map_foreign_batch(xc_handle, dom, prot, (xen_pfn_t*)arr, num); } +static int domain_add_to_physmap(qemu_xc_interface xc_handle, uint32_t domid, + unsigned int space, unsigned long idx, + xen_pfn_t gpfn) +{ + struct xen_add_to_physmap xatp = { + .domid = domid, + .space = space, + .idx = idx, + .gpfn = gpfn, + }; + + return xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp); +} + struct XenIfOps xc_xen = { .interface_open = interface_open, .interface_close = xc_interface_close, @@ -131,6 +145,7 @@ struct XenIfOps xc_xen = { .map_foreign_pages = xc_map_foreign_pages, .map_foreign_bulk = map_foreign_batch, .domain_populate_physmap_exact = xc_domain_memory_populate_physmap, + .domain_add_to_physmap = domain_add_to_physmap, }; # elif CONFIG_XEN_CTRL_INTERFACE_VERSION < 410 @@ -141,6 +156,20 @@ static qemu_xc_interface interface_open(xentoollog_logger *logger, return xc_interface_open(); } +static int domain_add_to_physmap(qemu_xc_interface xc_handle, uint32_t domid, + unsigned int space, unsigned long idx, + xen_pfn_t gpfn) +{ + struct xen_add_to_physmap xatp = { + .domid = domid, + .space = space, + .idx = idx, + .gpfn = gpfn, + }; + + return xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp); +} + struct XenIfOps xc_xen = { .interface_open = interface_open, .interface_close = xc_interface_close, @@ -148,6 +177,7 @@ struct XenIfOps xc_xen = { .map_foreign_pages = xc_map_foreign_pages, .map_foreign_bulk = xc_map_foreign_bulk, .domain_populate_physmap_exact = xc_domain_memory_populate_physmap, + .domain_add_to_physmap = domain_add_to_physmap, }; # else /* CONFIG_XEN_CTRL_INTERFACE_VERSION >= 410 */ @@ -158,6 +188,7 @@ struct XenIfOps xc_xen = { .map_foreign_pages = xc_map_foreign_pages, .map_foreign_bulk = xc_map_foreign_bulk, .domain_populate_physmap_exact = xc_domain_populate_physmap_exact, + .domain_add_to_physmap = xc_domain_add_to_physmap, }; # endif diff --git a/hw/xen_interfaces.h b/hw/xen_interfaces.h index 0f698dc..be38345 100644 --- a/hw/xen_interfaces.h +++ b/hw/xen_interfaces.h @@ -108,6 +108,11 @@ struct XenIfOps { unsigned int extent_order, unsigned int mem_flags, xen_pfn_t *extent_start); + int (*domain_add_to_physmap)(qemu_xc_interface xc_handle, + uint32_t domid, + unsigned int space, + unsigned long idx, + xen_pfn_t gpfn); }; extern struct XenIfOps xc; diff --git a/hw/xen_redirect.h b/hw/xen_redirect.h index 7cd6492..1b7c603 100644 --- a/hw/xen_redirect.h +++ b/hw/xen_redirect.h @@ -30,6 +30,7 @@ #define xc_map_foreign_bulk xc.map_foreign_bulk #define xc_domain_populate_physmap_exact \ xc.domain_populate_physmap_exact +#define xc_domain_add_to_physmap xc.domain_add_to_physmap /* xenstore interface */ #define xs_daemon_open xs.daemon_open -- 1.7.1 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
anthony.perard@citrix.com
2011-Jan-14 18:10 UTC
[Xen-devel] [PATCH V2 3/3] xen: Introduce VGA sync dirty bitmap support
From: Anthony PERARD <anthony.perard@citrix.com> This patch introduces phys memory client for Xen. Only sync dirty_bitmap and set_memory are actually implemented. migration_log will stay empty for the moment. Xen can only log one range for bit change, so only the range in the first call will be synced. Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> --- xen-all.c | 253 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 253 insertions(+), 0 deletions(-) diff --git a/xen-all.c b/xen-all.c index 939d9b7..59178ad 100644 --- a/xen-all.c +++ b/xen-all.c @@ -47,6 +47,14 @@ #define BUFFER_IO_MAX_DELAY 100 +typedef struct XenPhysmap { + target_phys_addr_t start_addr; + ram_addr_t size; + target_phys_addr_t phys_offset; + + QLIST_ENTRY(XenPhysmap) list; +} XenPhysmap; + typedef struct XenIOState { shared_iopage_t *shared_page; buffered_iopage_t *buffered_io_page; @@ -59,6 +67,9 @@ typedef struct XenIOState { int send_vcpu; struct xs_handle *xenstore; + CPUPhysMemoryClient client; + QLIST_HEAD(, XenPhysmap) physmap; + const XenPhysmap *log_for_dirtybit; Notifier exit; } XenIOState; @@ -162,6 +173,243 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size) qemu_free(pfn_list); } +static XenPhysmap *get_physmapping(XenIOState *state, + target_phys_addr_t start_addr, ram_addr_t size) +{ + XenPhysmap *physmap = NULL; + + start_addr = TARGET_PAGE_ALIGN(start_addr); + /* Search for a mapping inside another mapping */ + QLIST_FOREACH(physmap, &state->physmap, list) { + if (physmap->start_addr <= start_addr && + start_addr + size <= (physmap->start_addr + physmap->size)) { + return physmap; + } + } + return NULL; +} + +#if CONFIG_XEN_CTRL_INTERFACE_VERSION >= 340 +static int xen_add_to_physmap(XenIOState *state, + target_phys_addr_t start_addr, + ram_addr_t size, + target_phys_addr_t phys_offset) +{ + unsigned long i = 0; + int rc = 0; + XenPhysmap *physmap = NULL; + + if (get_physmapping(state, start_addr, size)) { + return 0; + } + if (size <= 0) { + return -1; + } + + DPRINTF("mapping vram to %llx - %llx, from %llx\n", start_addr, start_addr + size, phys_offset); + for (i = 0; i < size >> TARGET_PAGE_BITS; i++) { + unsigned long idx = (phys_offset >> TARGET_PAGE_BITS) + i; + + xen_pfn_t gpfn = (start_addr >> TARGET_PAGE_BITS) + i; + rc = xc_domain_add_to_physmap(xen_xc, xen_domid, XENMAPSPACE_gmfn, idx, gpfn); + if (rc) { + DPRINTF("add_to_physmap MFN %"PRI_xen_pfn" to PFN %" + PRI_xen_pfn" failed: %d\n", idx, gpfn, rc); + return -rc; + } + } + + physmap = qemu_malloc(sizeof (XenPhysmap)); + + physmap->start_addr = start_addr; + physmap->size = size; + physmap->phys_offset = phys_offset; + + QLIST_INSERT_HEAD(&state->physmap, physmap, list); + + xc_domain_pin_memory_cacheattr(xen_xc, xen_domid, + start_addr >> TARGET_PAGE_BITS, + (start_addr + size) >> TARGET_PAGE_BITS, + XEN_DOMCTL_MEM_CACHEATTR_WB); + return 0; +} + +static int xen_remove_from_physmap(XenIOState *state, + target_phys_addr_t start_addr, + ram_addr_t size) +{ + unsigned long i = 0; + int rc = 0; + XenPhysmap *physmap = NULL; + target_phys_addr_t phys_offset = 0; + + physmap = get_physmapping(state, start_addr, size); + if (physmap == NULL) { + return -1; + } + + phys_offset = physmap->phys_offset; + size = physmap->size; + + DPRINTF("unmapping vram to %llx - %llx, from %llx\n", phys_offset, phys_offset + size, start_addr); + for (i = 0; i < size >> TARGET_PAGE_BITS; i++) { + unsigned long idx = (start_addr >> TARGET_PAGE_BITS) + i; + + xen_pfn_t gpfn = (phys_offset >> TARGET_PAGE_BITS) + i; + rc = xc_domain_add_to_physmap(xen_xc, xen_domid, XENMAPSPACE_gmfn, idx, gpfn); + if (rc) { + fprintf(stderr, "add_to_physmap MFN %"PRI_xen_pfn" to PFN %" + PRI_xen_pfn" failed: %d\n", idx, gpfn, rc); + return -rc; + } + } + + QLIST_REMOVE(physmap, list); + if (state->log_for_dirtybit == physmap) { + state->log_for_dirtybit = NULL; + } + free(physmap); + + return 0; +} + +#else +static int xen_add_to_physmap(XenIOState *state, + target_phys_addr_t start_addr, + ram_addr_t size, + target_phys_addr_t phys_offset) +{ + return -ENOSYS; +} + +static int xen_remove_from_physmap(XenIOState *state, + target_phys_addr_t start_addr, + ram_addr_t size) +{ + return -ENOSYS; +} +#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) +{ + XenIOState *state = container_of(client, XenIOState, client); + ram_addr_t flags = phys_offset & ~TARGET_PAGE_MASK; + hvmmem_type_t mem_type; + + start_addr = TARGET_PAGE_ALIGN(start_addr); + size = TARGET_PAGE_ALIGN(size); + phys_offset = TARGET_PAGE_ALIGN(phys_offset); + + /* Xen does not need to know about this memory */ + if (flags > IO_MEM_UNASSIGNED) { + return; + } + + 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); + } + break; + case IO_MEM_UNASSIGNED: + if (xen_remove_from_physmap(state, start_addr, size) < 0) { + DPRINTF("physmapping does not exist at "TARGET_FMT_plx"\n", start_addr); + } + break; + } +} + +static int xen_sync_dirty_bitmap(XenIOState *state, + target_phys_addr_t start_addr, + ram_addr_t size) +{ + target_phys_addr_t npages = size >> TARGET_PAGE_BITS; + target_phys_addr_t vram_offset = 0; + const int width = sizeof(unsigned long) * 8; + unsigned long bitmap[(npages + width - 1) / width]; + int rc, i, j; + const XenPhysmap *physmap = NULL; + + physmap = get_physmapping(state, start_addr, size); + if (physmap == NULL) { + /* not handled */ + return -1; + } + + if (state->log_for_dirtybit == NULL) { + state->log_for_dirtybit = physmap; + } else if (state->log_for_dirtybit != physmap) { + return -1; + } + vram_offset = physmap->phys_offset; + + rc = xc_hvm_track_dirty_vram(xen_xc, xen_domid, + start_addr >> TARGET_PAGE_BITS, npages, + bitmap); + if (rc) { + return rc; + } + + for (i = 0; i < ARRAY_SIZE(bitmap); i++) { + unsigned long map = bitmap[i]; + while (map != 0) { + j = ffsl(map) - 1; + map &= ~(1ul << j); + cpu_physical_memory_set_dirty(vram_offset + (i * width + j) * TARGET_PAGE_SIZE); + }; + } + + return 0; +} + +static int xen_log_start(CPUPhysMemoryClient *client, target_phys_addr_t phys_addr, ram_addr_t size) +{ + XenIOState *state = container_of(client, XenIOState, client); + + return xen_sync_dirty_bitmap(state, phys_addr, size); +} + +static int xen_log_stop(CPUPhysMemoryClient *client, target_phys_addr_t phys_addr, ram_addr_t size) +{ + XenIOState *state = container_of(client, XenIOState, client); + + state->log_for_dirtybit = NULL; + /* Disable dirty bit tracking */ + return xc_hvm_track_dirty_vram(xen_xc, xen_domid, 0, 0, NULL); +} + +static int xen_client_sync_dirty_bitmap(struct CPUPhysMemoryClient *client, + target_phys_addr_t start_addr, + target_phys_addr_t end_addr) +{ + XenIOState *state = container_of(client, XenIOState, client); + + return xen_sync_dirty_bitmap(state, start_addr, end_addr - start_addr); +} + +static int xen_client_migration_log(struct CPUPhysMemoryClient *client, + int enable) +{ + 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, + .log_start = xen_log_start, + .log_stop = xen_log_stop, +}; /* VCPU Operations, MMIO, IO ring ... */ @@ -553,6 +801,11 @@ int xen_init(int smp_cpus) qemu_add_vm_change_state_handler(xen_vm_change_state_handler, state); + state->client = xen_cpu_phys_memory_client; + QLIST_INIT(&state->physmap); + cpu_register_phys_memory_client(&state->client); + state->log_for_dirtybit = NULL; + return 0; } -- 1.7.1 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Stefano Stabellini
2011-Jan-17 15:09 UTC
Re: [Xen-devel] [PATCH V2 3/3] xen: Introduce VGA sync dirty bitmap support
On Fri, 14 Jan 2011, anthony.perard@citrix.com wrote:> From: Anthony PERARD <anthony.perard@citrix.com> > > This patch introduces phys memory client for Xen. > > Only sync dirty_bitmap and set_memory are actually implemented. > migration_log will stay empty for the moment. > > Xen can only log one range for bit change, so only the range in the > first call will be synced. >I think the patch is OK now. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Jan Kiszka
2011-Jan-17 15:54 UTC
[Xen-devel] Re: [PATCH V2 1/3] Introduce log_start/log_stop in CPUPhysMemoryClient
On 2011-01-14 19:10, anthony.perard@citrix.com wrote:> From: Anthony PERARD <anthony.perard@citrix.com> > > In order to use log_start/log_stop with Xen as well in the vga code, > this two operations have been put in CPUPhysMemoryClient. > > The two new functions cpu_physical_log_start,cpu_physical_log_stop are > used in hw/vga.c and replace the kvm_log_start/stop. With this, vga does > no longer depends on kvm header.Basically, this looks good to me. Two remarks below.> > Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> > --- > cpu-all.h | 6 ++++++ > cpu-common.h | 4 ++++ > exec.c | 42 ++++++++++++++++++++++++++++++++++++++++++ > hw/vga.c | 31 ++++++++++++++++--------------- > hw/vhost.c | 16 ++++++++++++++++ > kvm-all.c | 8 ++++++-- > kvm-stub.c | 10 ---------- > kvm.h | 3 --- > 8 files changed, 90 insertions(+), 30 deletions(-) > > diff --git a/cpu-all.h b/cpu-all.h > index 30ae17d..aaf5442 100644 > --- a/cpu-all.h > +++ b/cpu-all.h > @@ -957,6 +957,12 @@ int cpu_physical_memory_get_dirty_tracking(void); > int cpu_physical_sync_dirty_bitmap(target_phys_addr_t start_addr, > target_phys_addr_t end_addr); > > +int cpu_physical_log_start(target_phys_addr_t start_addr, > + ram_addr_t size); > + > +int cpu_physical_log_stop(target_phys_addr_t start_addr, > + ram_addr_t size); > + > void dump_exec_info(FILE *f, fprintf_function cpu_fprintf); > #endif /* !CONFIG_USER_ONLY */ > > diff --git a/cpu-common.h b/cpu-common.h > index 8ec01f4..2344842 100644 > --- a/cpu-common.h > +++ b/cpu-common.h > @@ -88,6 +88,10 @@ struct CPUPhysMemoryClient { > target_phys_addr_t end_addr); > int (*migration_log)(struct CPUPhysMemoryClient *client, > int enable); > + int (*log_start)(struct CPUPhysMemoryClient *client, > + target_phys_addr_t phys_addr, ram_addr_t size); > + int (*log_stop)(struct CPUPhysMemoryClient *client, > + target_phys_addr_t phys_addr, ram_addr_t size); > QLIST_ENTRY(CPUPhysMemoryClient) list; > }; > > diff --git a/exec.c b/exec.c > index c6ed96d..609ec88 100644 > --- a/exec.c > +++ b/exec.c > @@ -1734,6 +1734,30 @@ static int cpu_notify_migration_log(int enable) > return 0; > } > > +static int cpu_notify_log_start(target_phys_addr_t start, > + ram_addr_t size) > +{ > + CPUPhysMemoryClient *client; > + QLIST_FOREACH(client, &memory_client_list, list) { > + int r = client->log_start(client, start, size); > + if (r < 0) > + return r; > + } > + return 0; > +} > + > +static int cpu_notify_log_stop(target_phys_addr_t start, > + ram_addr_t size) > +{ > + CPUPhysMemoryClient *client; > + QLIST_FOREACH(client, &memory_client_list, list) { > + int r = client->log_stop(client, start, size); > + if (r < 0) > + return r; > + } > + return 0; > +} > +I would make the new callbacks optional, i.e. only invoke them if the handler is non-NULL. Avoids stubs and branching to vhost.> static void phys_page_for_each_1(CPUPhysMemoryClient *client, > int level, void **lp) > { > @@ -2073,6 +2097,24 @@ int cpu_physical_sync_dirty_bitmap(target_phys_addr_t start_addr, > return ret; > } > > +int cpu_physical_log_start(target_phys_addr_t start_addr, > + ram_addr_t size) > +{ > + int ret; > + > + ret = cpu_notify_log_start(start_addr, size); > + return ret; > +} > + > +int cpu_physical_log_stop(target_phys_addr_t start_addr, > + ram_addr_t size) > +{ > + int ret; > + > + ret = cpu_notify_log_stop(start_addr, size); > + return ret; > +} > +I consider this split-up between API frontend and cpu_notify_* backend as unneeded. But that''s not your fault, you just follow the pre-existing pattern. Unless someone feels strong about this, you may just keep it. Jan -- Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Anthony PERARD
2011-Jan-17 18:25 UTC
[Xen-devel] Re: [PATCH V2 1/3] Introduce log_start/log_stop in CPUPhysMemoryClient
On Mon, 17 Jan 2011, Jan Kiszka wrote:> On 2011-01-14 19:10, anthony.perard@citrix.com wrote: > > From: Anthony PERARD <anthony.perard@citrix.com> > > > > In order to use log_start/log_stop with Xen as well in the vga code, > > this two operations have been put in CPUPhysMemoryClient. > > > > The two new functions cpu_physical_log_start,cpu_physical_log_stop are > > used in hw/vga.c and replace the kvm_log_start/stop. With this, vga does > > no longer depends on kvm header. > > Basically, this looks good to me. Two remarks below. > > > > > Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> > > --- > > cpu-all.h | 6 ++++++ > > cpu-common.h | 4 ++++ > > exec.c | 42 ++++++++++++++++++++++++++++++++++++++++++ > > hw/vga.c | 31 ++++++++++++++++--------------- > > hw/vhost.c | 16 ++++++++++++++++ > > kvm-all.c | 8 ++++++-- > > kvm-stub.c | 10 ---------- > > kvm.h | 3 --- > > 8 files changed, 90 insertions(+), 30 deletions(-) > > > > diff --git a/exec.c b/exec.c > > index c6ed96d..609ec88 100644 > > --- a/exec.c > > +++ b/exec.c > > @@ -1734,6 +1734,30 @@ static int cpu_notify_migration_log(int enable) > > return 0; > > } > > > > +static int cpu_notify_log_start(target_phys_addr_t start, > > + ram_addr_t size) > > +{ > > + CPUPhysMemoryClient *client; > > + QLIST_FOREACH(client, &memory_client_list, list) { > > + int r = client->log_start(client, start, size); > > + if (r < 0) > > + return r; > > + } > > + return 0; > > +} > > + > > +static int cpu_notify_log_stop(target_phys_addr_t start, > > + ram_addr_t size) > > +{ > > + CPUPhysMemoryClient *client; > > + QLIST_FOREACH(client, &memory_client_list, list) { > > + int r = client->log_stop(client, start, size); > > + if (r < 0) > > + return r; > > + } > > + return 0; > > +} > > + > > I would make the new callbacks optional, i.e. only invoke them if the > handler is non-NULL. Avoids stubs and branching to vhost.Ok, I will do that.> > static void phys_page_for_each_1(CPUPhysMemoryClient *client, > > int level, void **lp) > > { > > @@ -2073,6 +2097,24 @@ int cpu_physical_sync_dirty_bitmap(target_phys_addr_t start_addr, > > return ret; > > } > > > > +int cpu_physical_log_start(target_phys_addr_t start_addr, > > + ram_addr_t size) > > +{ > > + int ret; > > + > > + ret = cpu_notify_log_start(start_addr, size); > > + return ret; > > +} > > + > > +int cpu_physical_log_stop(target_phys_addr_t start_addr, > > + ram_addr_t size) > > +{ > > + int ret; > > + > > + ret = cpu_notify_log_stop(start_addr, size); > > + return ret; > > +} > > + > > I consider this split-up between API frontend and cpu_notify_* backend > as unneeded. But that''s not your fault, you just follow the pre-existing > pattern. Unless someone feels strong about this, you may just keep it.Actually, I will remove it, and keep only the frontend fonction. Thanks, -- Anthony PERARD _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
anthony.perard@citrix.com
2011-Jan-18 12:25 UTC
[Xen-devel] Re: [PATCH V2 1/3] Introduce log_start/log_stop in CPUPhysMemoryClient
From: Anthony PERARD <anthony.perard@citrix.com> In order to use log_start/log_stop with Xen as well in the vga code, this two operations have been put in CPUPhysMemoryClient. The two new functions cpu_physical_log_start,cpu_physical_log_stop are used in hw/vga.c and replace the kvm_log_start/stop. With this, vga does no longer depends on kvm header. Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> --- cpu-all.h | 6 ++++++ cpu-common.h | 4 ++++ exec.c | 28 ++++++++++++++++++++++++++++ hw/vga.c | 31 ++++++++++++++++--------------- hw/vhost.c | 2 ++ kvm-all.c | 8 ++++++-- kvm-stub.c | 10 ---------- kvm.h | 3 --- 8 files changed, 62 insertions(+), 30 deletions(-) diff --git a/cpu-all.h b/cpu-all.h index 30ae17d..aaf5442 100644 --- a/cpu-all.h +++ b/cpu-all.h @@ -957,6 +957,12 @@ int cpu_physical_memory_get_dirty_tracking(void); int cpu_physical_sync_dirty_bitmap(target_phys_addr_t start_addr, target_phys_addr_t end_addr); +int cpu_physical_log_start(target_phys_addr_t start_addr, + ram_addr_t size); + +int cpu_physical_log_stop(target_phys_addr_t start_addr, + ram_addr_t size); + void dump_exec_info(FILE *f, fprintf_function cpu_fprintf); #endif /* !CONFIG_USER_ONLY */ diff --git a/cpu-common.h b/cpu-common.h index 8ec01f4..2344842 100644 --- a/cpu-common.h +++ b/cpu-common.h @@ -88,6 +88,10 @@ struct CPUPhysMemoryClient { target_phys_addr_t end_addr); int (*migration_log)(struct CPUPhysMemoryClient *client, int enable); + int (*log_start)(struct CPUPhysMemoryClient *client, + target_phys_addr_t phys_addr, ram_addr_t size); + int (*log_stop)(struct CPUPhysMemoryClient *client, + target_phys_addr_t phys_addr, ram_addr_t size); QLIST_ENTRY(CPUPhysMemoryClient) list; }; diff --git a/exec.c b/exec.c index c6ed96d..59a6426 100644 --- a/exec.c +++ b/exec.c @@ -2073,6 +2073,34 @@ int cpu_physical_sync_dirty_bitmap(target_phys_addr_t start_addr, return ret; } +int cpu_physical_log_start(target_phys_addr_t start_addr, + ram_addr_t size) +{ + CPUPhysMemoryClient *client; + QLIST_FOREACH(client, &memory_client_list, list) { + if (client->log_start) { + int r = client->log_start(client, start_addr, size); + if (r < 0) + return r; + } + } + return 0; +} + +int cpu_physical_log_stop(target_phys_addr_t start_addr, + ram_addr_t size) +{ + CPUPhysMemoryClient *client; + QLIST_FOREACH(client, &memory_client_list, list) { + if (client->log_stop) { + int r = client->log_stop(client, start_addr, size); + if (r < 0) + return r; + } + } + return 0; +} + static inline void tlb_update_dirty(CPUTLBEntry *tlb_entry) { ram_addr_t ram_addr; diff --git a/hw/vga.c b/hw/vga.c index c057f4f..a9bf172 100644 --- a/hw/vga.c +++ b/hw/vga.c @@ -28,7 +28,6 @@ #include "vga_int.h" #include "pixel_ops.h" #include "qemu-timer.h" -#include "kvm.h" //#define DEBUG_VGA //#define DEBUG_VGA_MEM @@ -1597,34 +1596,36 @@ static void vga_sync_dirty_bitmap(VGACommonState *s) void vga_dirty_log_start(VGACommonState *s) { - if (kvm_enabled() && s->map_addr) - kvm_log_start(s->map_addr, s->map_end - s->map_addr); + if (s->map_addr) { + cpu_physical_log_start(s->map_addr, s->map_end - s->map_addr); + } - if (kvm_enabled() && s->lfb_vram_mapped) { - kvm_log_start(isa_mem_base + 0xa0000, 0x8000); - kvm_log_start(isa_mem_base + 0xa8000, 0x8000); + if (s->lfb_vram_mapped) { + cpu_physical_log_start(isa_mem_base + 0xa0000, 0x8000); + cpu_physical_log_start(isa_mem_base + 0xa8000, 0x8000); } #ifdef CONFIG_BOCHS_VBE - if (kvm_enabled() && s->vbe_mapped) { - kvm_log_start(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size); + if (s->vbe_mapped) { + cpu_physical_log_start(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size); } #endif } void vga_dirty_log_stop(VGACommonState *s) { - if (kvm_enabled() && s->map_addr) - kvm_log_stop(s->map_addr, s->map_end - s->map_addr); + if (s->map_addr) { + cpu_physical_log_stop(s->map_addr, s->map_end - s->map_addr); + } - if (kvm_enabled() && s->lfb_vram_mapped) { - kvm_log_stop(isa_mem_base + 0xa0000, 0x8000); - kvm_log_stop(isa_mem_base + 0xa8000, 0x8000); + if (s->lfb_vram_mapped) { + cpu_physical_log_stop(isa_mem_base + 0xa0000, 0x8000); + cpu_physical_log_stop(isa_mem_base + 0xa8000, 0x8000); } #ifdef CONFIG_BOCHS_VBE - if (kvm_enabled() && s->vbe_mapped) { - kvm_log_stop(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size); + if (s->vbe_mapped) { + cpu_physical_log_stop(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size); } #endif } diff --git a/hw/vhost.c b/hw/vhost.c index 8586f66..932b372 100644 --- a/hw/vhost.c +++ b/hw/vhost.c @@ -606,6 +606,8 @@ int vhost_dev_init(struct vhost_dev *hdev, int devfd) hdev->client.set_memory = vhost_client_set_memory; hdev->client.sync_dirty_bitmap = vhost_client_sync_dirty_bitmap; hdev->client.migration_log = vhost_client_migration_log; + hdev->client.log_start = NULL; + hdev->client.log_stop = NULL; hdev->mem = qemu_mallocz(offsetof(struct vhost_memory, regions)); hdev->log = NULL; hdev->log_size = 0; diff --git a/kvm-all.c b/kvm-all.c index 37b99c7..aedfe33 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -267,14 +267,16 @@ static int kvm_dirty_pages_log_change(target_phys_addr_t phys_addr, return kvm_set_user_memory_region(s, mem); } -int kvm_log_start(target_phys_addr_t phys_addr, ram_addr_t size) +static int kvm_log_start(CPUPhysMemoryClient *client, + target_phys_addr_t phys_addr, ram_addr_t size) { return kvm_dirty_pages_log_change(phys_addr, size, KVM_MEM_LOG_DIRTY_PAGES, KVM_MEM_LOG_DIRTY_PAGES); } -int kvm_log_stop(target_phys_addr_t phys_addr, ram_addr_t size) +static int kvm_log_stop(CPUPhysMemoryClient *client, + target_phys_addr_t phys_addr, ram_addr_t size) { return kvm_dirty_pages_log_change(phys_addr, size, 0, @@ -596,6 +598,8 @@ static CPUPhysMemoryClient kvm_cpu_phys_memory_client = { .set_memory = kvm_client_set_memory, .sync_dirty_bitmap = kvm_client_sync_dirty_bitmap, .migration_log = kvm_client_migration_log, + .log_start = kvm_log_start, + .log_stop = kvm_log_stop, }; int kvm_init(int smp_cpus) diff --git a/kvm-stub.c b/kvm-stub.c index 5384a4b..41324e4 100644 --- a/kvm-stub.c +++ b/kvm-stub.c @@ -33,16 +33,6 @@ int kvm_init_vcpu(CPUState *env) return -ENOSYS; } -int kvm_log_start(target_phys_addr_t phys_addr, ram_addr_t size) -{ - return -ENOSYS; -} - -int kvm_log_stop(target_phys_addr_t phys_addr, ram_addr_t size) -{ - return -ENOSYS; -} - int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size) { return -ENOSYS; diff --git a/kvm.h b/kvm.h index 60a9b42..fc77b81 100644 --- a/kvm.h +++ b/kvm.h @@ -49,9 +49,6 @@ int kvm_init_vcpu(CPUState *env); int kvm_cpu_exec(CPUState *env); #if !defined(CONFIG_USER_ONLY) -int kvm_log_start(target_phys_addr_t phys_addr, ram_addr_t size); -int kvm_log_stop(target_phys_addr_t phys_addr, ram_addr_t size); - void kvm_setup_guest_memory(void *start, size_t size); int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size); -- 1.7.1 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Jan Kiszka
2011-Jan-18 18:20 UTC
[Xen-devel] Re: [PATCH V2 1/3] Introduce log_start/log_stop in CPUPhysMemoryClient
Send patch updates always with proper "[PATCH]" tag, they may get lost otherwise. On 2011-01-18 13:25, anthony.perard@citrix.com wrote:> From: Anthony PERARD <anthony.perard@citrix.com> > > In order to use log_start/log_stop with Xen as well in the vga code, > this two operations have been put in CPUPhysMemoryClient. > > The two new functions cpu_physical_log_start,cpu_physical_log_stop are > used in hw/vga.c and replace the kvm_log_start/stop. With this, vga does > no longer depends on kvm header. > > Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> > --- > cpu-all.h | 6 ++++++ > cpu-common.h | 4 ++++ > exec.c | 28 ++++++++++++++++++++++++++++ > hw/vga.c | 31 ++++++++++++++++--------------- > hw/vhost.c | 2 ++ > kvm-all.c | 8 ++++++-- > kvm-stub.c | 10 ---------- > kvm.h | 3 --- > 8 files changed, 62 insertions(+), 30 deletions(-) > > diff --git a/cpu-all.h b/cpu-all.h > index 30ae17d..aaf5442 100644 > --- a/cpu-all.h > +++ b/cpu-all.h > @@ -957,6 +957,12 @@ int cpu_physical_memory_get_dirty_tracking(void); > int cpu_physical_sync_dirty_bitmap(target_phys_addr_t start_addr, > target_phys_addr_t end_addr); > > +int cpu_physical_log_start(target_phys_addr_t start_addr, > + ram_addr_t size); > + > +int cpu_physical_log_stop(target_phys_addr_t start_addr, > + ram_addr_t size); > + > void dump_exec_info(FILE *f, fprintf_function cpu_fprintf); > #endif /* !CONFIG_USER_ONLY */ > > diff --git a/cpu-common.h b/cpu-common.h > index 8ec01f4..2344842 100644 > --- a/cpu-common.h > +++ b/cpu-common.h > @@ -88,6 +88,10 @@ struct CPUPhysMemoryClient { > target_phys_addr_t end_addr); > int (*migration_log)(struct CPUPhysMemoryClient *client, > int enable); > + int (*log_start)(struct CPUPhysMemoryClient *client, > + target_phys_addr_t phys_addr, ram_addr_t size); > + int (*log_stop)(struct CPUPhysMemoryClient *client, > + target_phys_addr_t phys_addr, ram_addr_t size); > QLIST_ENTRY(CPUPhysMemoryClient) list; > }; > > diff --git a/exec.c b/exec.c > index c6ed96d..59a6426 100644 > --- a/exec.c > +++ b/exec.c > @@ -2073,6 +2073,34 @@ int cpu_physical_sync_dirty_bitmap(target_phys_addr_t start_addr, > return ret; > } > > +int cpu_physical_log_start(target_phys_addr_t start_addr, > + ram_addr_t size) > +{ > + CPUPhysMemoryClient *client; > + QLIST_FOREACH(client, &memory_client_list, list) { > + if (client->log_start) { > + int r = client->log_start(client, start_addr, size); > + if (r < 0) > + return r; > + } > + } > + return 0; > +} > + > +int cpu_physical_log_stop(target_phys_addr_t start_addr, > + ram_addr_t size) > +{ > + CPUPhysMemoryClient *client; > + QLIST_FOREACH(client, &memory_client_list, list) { > + if (client->log_stop) { > + int r = client->log_stop(client, start_addr, size); > + if (r < 0) > + return r; > + } > + } > + return 0; > +} > + > static inline void tlb_update_dirty(CPUTLBEntry *tlb_entry) > { > ram_addr_t ram_addr; > diff --git a/hw/vga.c b/hw/vga.c > index c057f4f..a9bf172 100644 > --- a/hw/vga.c > +++ b/hw/vga.c > @@ -28,7 +28,6 @@ > #include "vga_int.h" > #include "pixel_ops.h" > #include "qemu-timer.h" > -#include "kvm.h" > > //#define DEBUG_VGA > //#define DEBUG_VGA_MEM > @@ -1597,34 +1596,36 @@ static void vga_sync_dirty_bitmap(VGACommonState *s) > > void vga_dirty_log_start(VGACommonState *s) > { > - if (kvm_enabled() && s->map_addr) > - kvm_log_start(s->map_addr, s->map_end - s->map_addr); > + if (s->map_addr) { > + cpu_physical_log_start(s->map_addr, s->map_end - s->map_addr); > + } > > - if (kvm_enabled() && s->lfb_vram_mapped) { > - kvm_log_start(isa_mem_base + 0xa0000, 0x8000); > - kvm_log_start(isa_mem_base + 0xa8000, 0x8000); > + if (s->lfb_vram_mapped) { > + cpu_physical_log_start(isa_mem_base + 0xa0000, 0x8000); > + cpu_physical_log_start(isa_mem_base + 0xa8000, 0x8000); > } > > #ifdef CONFIG_BOCHS_VBE > - if (kvm_enabled() && s->vbe_mapped) { > - kvm_log_start(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size); > + if (s->vbe_mapped) { > + cpu_physical_log_start(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size); > } > #endif > } > > void vga_dirty_log_stop(VGACommonState *s) > { > - if (kvm_enabled() && s->map_addr) > - kvm_log_stop(s->map_addr, s->map_end - s->map_addr); > + if (s->map_addr) { > + cpu_physical_log_stop(s->map_addr, s->map_end - s->map_addr); > + } > > - if (kvm_enabled() && s->lfb_vram_mapped) { > - kvm_log_stop(isa_mem_base + 0xa0000, 0x8000); > - kvm_log_stop(isa_mem_base + 0xa8000, 0x8000); > + if (s->lfb_vram_mapped) { > + cpu_physical_log_stop(isa_mem_base + 0xa0000, 0x8000); > + cpu_physical_log_stop(isa_mem_base + 0xa8000, 0x8000); > } > > #ifdef CONFIG_BOCHS_VBE > - if (kvm_enabled() && s->vbe_mapped) { > - kvm_log_stop(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size); > + if (s->vbe_mapped) { > + cpu_physical_log_stop(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size); > }Sorry in case they were present earlier and I missed them, but here are tabs included that should be removed from new code. There is a check-patch script floating around on the list, I think it''s not yet merged though.> #endif > } > diff --git a/hw/vhost.c b/hw/vhost.c > index 8586f66..932b372 100644 > --- a/hw/vhost.c > +++ b/hw/vhost.c > @@ -606,6 +606,8 @@ int vhost_dev_init(struct vhost_dev *hdev, int devfd) > hdev->client.set_memory = vhost_client_set_memory; > hdev->client.sync_dirty_bitmap = vhost_client_sync_dirty_bitmap; > hdev->client.migration_log = vhost_client_migration_log; > + hdev->client.log_start = NULL; > + hdev->client.log_stop = NULL; > hdev->mem = qemu_mallocz(offsetof(struct vhost_memory, regions)); > hdev->log = NULL; > hdev->log_size = 0; > diff --git a/kvm-all.c b/kvm-all.c > index 37b99c7..aedfe33 100644 > --- a/kvm-all.c > +++ b/kvm-all.c > @@ -267,14 +267,16 @@ static int kvm_dirty_pages_log_change(target_phys_addr_t phys_addr, > return kvm_set_user_memory_region(s, mem); > } > > -int kvm_log_start(target_phys_addr_t phys_addr, ram_addr_t size) > +static int kvm_log_start(CPUPhysMemoryClient *client, > + target_phys_addr_t phys_addr, ram_addr_t size) > { > return kvm_dirty_pages_log_change(phys_addr, size, > KVM_MEM_LOG_DIRTY_PAGES, > KVM_MEM_LOG_DIRTY_PAGES); > } > > -int kvm_log_stop(target_phys_addr_t phys_addr, ram_addr_t size) > +static int kvm_log_stop(CPUPhysMemoryClient *client, > + target_phys_addr_t phys_addr, ram_addr_t size) > { > return kvm_dirty_pages_log_change(phys_addr, size, > 0, > @@ -596,6 +598,8 @@ static CPUPhysMemoryClient kvm_cpu_phys_memory_client = { > .set_memory = kvm_client_set_memory, > .sync_dirty_bitmap = kvm_client_sync_dirty_bitmap, > .migration_log = kvm_client_migration_log, > + .log_start = kvm_log_start, > + .log_stop = kvm_log_stop, > }; > > int kvm_init(int smp_cpus) > diff --git a/kvm-stub.c b/kvm-stub.c > index 5384a4b..41324e4 100644 > --- a/kvm-stub.c > +++ b/kvm-stub.c > @@ -33,16 +33,6 @@ int kvm_init_vcpu(CPUState *env) > return -ENOSYS; > } > > -int kvm_log_start(target_phys_addr_t phys_addr, ram_addr_t size) > -{ > - return -ENOSYS; > -} > - > -int kvm_log_stop(target_phys_addr_t phys_addr, ram_addr_t size) > -{ > - return -ENOSYS; > -} > - > int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size) > { > return -ENOSYS; > diff --git a/kvm.h b/kvm.h > index 60a9b42..fc77b81 100644 > --- a/kvm.h > +++ b/kvm.h > @@ -49,9 +49,6 @@ int kvm_init_vcpu(CPUState *env); > int kvm_cpu_exec(CPUState *env); > > #if !defined(CONFIG_USER_ONLY) > -int kvm_log_start(target_phys_addr_t phys_addr, ram_addr_t size); > -int kvm_log_stop(target_phys_addr_t phys_addr, ram_addr_t size); > - > void kvm_setup_guest_memory(void *start, size_t size); > > int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size);Besides the tabs, I''m fine with it: Reviewed-by: Jan Kiszka <jan.kiszka@siemens.com> Maybe this patch should be picked up by qemu-kvm''s upstream branch (it will definitely collide with my coding style patch if not more, but that''s easily resolvable there). Jan -- Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel