From: Andrea Arcangeli <aarca...@redhat.com> This will allow proper alignment so NPT/EPT can take advantage of linux host backing the guest memory with hugepages (only relevant for KVM and not for QEMU that has no NPT/EPT support). To complete it, it will also notify the kernel that this memory is important to be backed by hugepages with madvise (needed for both KVM and QEMU).
Signed-off-by: Andrea Arcangeli <aarca...@redhat.com> --- diff --git a/exec.c b/exec.c index 891e0ee..aedd133 100644 --- a/exec.c +++ b/exec.c @@ -2628,11 +2628,25 @@ ram_addr_t qemu_ram_alloc(ram_addr_t size) PROT_EXEC|PROT_READ|PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); #else - new_block->host = qemu_vmalloc(size); -#endif +#if defined(__linux__) && defined(TARGET_HPAGE_BITS) + if (!kvm_enabled()) +#endif + new_block->host = qemu_vmalloc(size); +#if defined(__linux__) && defined(TARGET_HPAGE_BITS) + else + /* + * Align on HPAGE_SIZE so "(gfn ^ pfn) & + * (HPAGE_SIZE-1) == 0" to allow KVM to take advantage + * of hugepages with NPT/EPT. + */ + new_block->host = qemu_memalign(1 << TARGET_HPAGE_BITS, size); +#endif #ifdef MADV_MERGEABLE madvise(new_block->host, size, MADV_MERGEABLE); #endif +#ifdef MADV_HUGEPAGE + madvise(new_block->host, size, MADV_HUGEPAGE); +#endif } new_block->offset = last_ram_offset; new_block->length = size; diff --git a/target-i386/cpu.h b/target-i386/cpu.h index ef7d951..26044eb 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -873,6 +873,7 @@ uint64_t cpu_get_tsc(CPUX86State *env); #define X86_DUMP_CCOP 0x0002 /* dump qemu flag cache */ #define TARGET_PAGE_BITS 12 +#define TARGET_HPAGE_BITS (TARGET_PAGE_BITS+9) #define cpu_init cpu_x86_init #define cpu_exec cpu_x86_exec