[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] Re: [Qemu-devel] [PATCH V6 09/15] xen: Introduce the Xen mapcache
On 21.10.2010, at 19:36, Anthony.Perard@xxxxxxxxxx wrote: > From: Jun Nakajima <jun.nakajima@xxxxxxxxx> > > On IA32 host or IA32 PAE host, at present, generally, we can't create > an HVM guest with more than 2G memory, because generally it's almost > impossible for Qemu to find a large enough and consecutive virtual > address space to map an HVM guest's whole physical address space. > The attached patch fixes this issue using dynamic mapping based on > little blocks of memory. > > Each call to qemu_get_ram_ptr makes a call to qemu_map_cache with the > lock option, so mapcache will not unmap these ram_ptr. > > Signed-off-by: Jun Nakajima <jun.nakajima@xxxxxxxxx> > Signed-off-by: Anthony PERARD <anthony.perard@xxxxxxxxxx> > Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> > --- > Makefile.target | 3 + > configure | 3 + > exec.c | 40 ++++++- > hw/xen.h | 10 ++ > hw/xen_common.h | 2 + > xen-all.c | 64 +++++++++++ > xen-mapcache-stub.c | 33 ++++++ > xen-mapcache.c | 301 +++++++++++++++++++++++++++++++++++++++++++++++++++ > xen-mapcache.h | 14 +++ > xen-stub.c | 4 + > 10 files changed, 470 insertions(+), 4 deletions(-) > create mode 100644 xen-mapcache-stub.c > create mode 100644 xen-mapcache.c > create mode 100644 xen-mapcache.h > > diff --git a/Makefile.target b/Makefile.target > index db84edb..5646582 100644 > --- a/Makefile.target > +++ b/Makefile.target > @@ -187,8 +187,11 @@ QEMU_CFLAGS += $(VNC_PNG_CFLAGS) > obj-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o > > # xen support > +CONFIG_NO_XEN_MAPCACHE = $(if $(subst n,,$(CONFIG_XEN_MAPCACHE)),n,y) > obj-$(CONFIG_XEN) += xen-all.o > obj-$(CONFIG_NO_XEN) += xen-stub.o > +obj-$(CONFIG_XEN_MAPCACHE) += xen-mapcache.o > +obj-$(CONFIG_NO_XEN_MAPCACHE) += xen-mapcache-stub.o > > # xen full virtualized machine > obj-i386-$(CONFIG_XEN) += xen_machine_fv.o > diff --git a/configure b/configure > index f6a7073..d5a8553 100755 > --- a/configure > +++ b/configure > @@ -2943,6 +2943,9 @@ case "$target_arch2" in > i386|x86_64) > if test "$xen" = "yes" -a "$target_softmmu" = "yes" ; then > echo "CONFIG_XEN=y" >> $config_target_mak > + if test "$cpu" = "i386" -o "$cpu" = "x86_64"; then > + echo "CONFIG_XEN_MAPCACHE=y" >> $config_target_mak > + fi > fi > esac > case "$target_arch2" in > diff --git a/exec.c b/exec.c > index 631d8c5..d2cded6 100644 > --- a/exec.c > +++ b/exec.c > @@ -39,6 +39,7 @@ > #include "hw/qdev.h" > #include "osdep.h" > #include "kvm.h" > +#include "hw/xen.h" > #include "qemu-timer.h" > #if defined(CONFIG_USER_ONLY) > #include <qemu.h> > @@ -58,6 +59,8 @@ > #include <libutil.h> > #endif > #endif > +#else /* !CONFIG_USER_ONLY */ > +#include "xen-mapcache.h" > #endif > > //#define DEBUG_TB_INVALIDATE > @@ -2834,6 +2837,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, > const char *name, > } > } > > + new_block->offset = find_ram_offset(size); > if (host) { > new_block->host = host; > } else { > @@ -2855,13 +2859,15 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, > const char *name, > PROT_EXEC|PROT_READ|PROT_WRITE, > MAP_SHARED | MAP_ANONYMOUS, -1, 0); > #else > - new_block->host = qemu_vmalloc(size); > + if (xen_mapcache_enabled()) { > + xen_ram_alloc(new_block->offset, size); > + } else { > + new_block->host = qemu_vmalloc(size); > + } > #endif > qemu_madvise(new_block->host, size, QEMU_MADV_MERGEABLE); > } > } > - > - new_block->offset = find_ram_offset(size); > new_block->length = size; > > QLIST_INSERT_HEAD(&ram_list.blocks, new_block, next); > @@ -2902,7 +2908,11 @@ void qemu_ram_free(ram_addr_t addr) > #if defined(TARGET_S390X) && defined(CONFIG_KVM) > munmap(block->host, block->length); > #else > - qemu_vfree(block->host); > + if (xen_mapcache_enabled()) { > + qemu_invalidate_entry(block->host); > + } else { > + qemu_vfree(block->host); > + } > #endif > } > qemu_free(block); > @@ -2928,6 +2938,15 @@ void *qemu_get_ram_ptr(ram_addr_t addr) > if (addr - block->offset < block->length) { > QLIST_REMOVE(block, next); > QLIST_INSERT_HEAD(&ram_list.blocks, block, next); > + if (xen_mapcache_enabled()) { > + /* We need to check if the requested address is in the RAM > + * because we don't want to map the entire memory in QEMU. > + */ > + if (block->offset == 0) { > + return qemu_map_cache(addr, 0, 1); > + } > + block->host = qemu_map_cache(block->offset, block->length, > 1); > + } > return block->host + (addr - block->offset); > } > } > @@ -2944,11 +2963,21 @@ int qemu_ram_addr_from_host(void *ptr, ram_addr_t > *ram_addr) > uint8_t *host = ptr; > > QLIST_FOREACH(block, &ram_list.blocks, next) { > + /* This case append when the block is not mapped. */ > + if (block->host == NULL) { > + continue; > + } > if (host - block->host < block->length) { > *ram_addr = block->offset + (host - block->host); > return 0; > } > } > + > + if (xen_mapcache_enabled()) { > + *ram_addr = qemu_ram_addr_from_mapcache(ptr); > + return 0; > + } > + > return -1; > } > > @@ -3733,6 +3762,9 @@ void cpu_physical_memory_unmap(void *buffer, > target_phys_addr_t len, > if (is_write) { > cpu_physical_memory_write(bounce.addr, bounce.buffer, access_len); > } > + if (xen_enabled()) { > + qemu_invalidate_entry(buffer); > + } > qemu_vfree(bounce.buffer); > bounce.buffer = NULL; > cpu_notify_map_clients(); > diff --git a/hw/xen.h b/hw/xen.h > index c5189b1..0261ae6 100644 > --- a/hw/xen.h > +++ b/hw/xen.h > @@ -28,10 +28,20 @@ extern int xen_allowed; > #define xen_enabled() (0) > #endif > > +#if defined CONFIG_XEN_MAPCACHE > +# define xen_mapcache_enabled() (xen_enabled()) static inline int xen_mapcache_enabled(void) { #ifdef CONFIG_XEN_MAPCACHE return xen_enabled(); #else return 0; #endif } > +#else > +# define xen_mapcache_enabled() (0) > +#endif > + > int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num); > void xen_piix3_set_irq(void *opaque, int irq_num, int level); > void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int > len); > > int xen_init(int smp_cpus); > > +#if defined(NEED_CPU_H) && !defined(CONFIG_USER_ONLY) > +void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size); > +#endif > + > #endif /* QEMU_HW_XEN_H */ > diff --git a/hw/xen_common.h b/hw/xen_common.h > index a24bcb3..2773b45 100644 > --- a/hw/xen_common.h > +++ b/hw/xen_common.h > @@ -36,6 +36,8 @@ typedef int qemu_xc_interface; > xc_gnttab_map_grant_refs(gnt, count, domids, refs, flags) > # define xc_gnttab_munmap(xc, gnt, pages, niov) xc_gnttab_munmap(gnt, pages, > niov) > # define xc_gnttab_close(xc, dev) xc_gnttab_close(dev) > +# define xc_map_foreign_bulk(xc, domid, opts, pfns, err, size) \ > + xc_map_foreign_batch(xc, domid, opts, pfns, size) See my comment on the introduction of these defines. Alex _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |