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
|