@@ -1065,6 +1065,15 @@ int kvm_has_sync_mmu(kvm_context_t kvm)
return r;
}
+int kvm_has_gbpages(kvm_context_t kvm)
+{
+ int r = 0;
+#ifdef KVM_CAP_1GB_PAGES
+ r = ioctl(kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_1GB_PAGES);
+#endif
+ return r;
+}
+
int kvm_inject_nmi(kvm_context_t kvm, int vcpu)
{
#ifdef KVM_CAP_USER_NMI
@@ -558,6 +558,7 @@ int kvm_dirty_pages_log_reset(kvm_context_t kvm);
int kvm_irqchip_in_kernel(kvm_context_t kvm);
int kvm_has_sync_mmu(kvm_context_t kvm);
+int kvm_has_gbpages(kvm_context_t kvm);
#ifdef KVM_CAP_IRQCHIP
/*!
@@ -33,6 +33,7 @@ int kvm_irqchip = 1;
int kvm_pit = 1;
int kvm_pit_reinject = 1;
int kvm_nested = 0;
+int kvm_gb_pages = 0;
kvm_context_t kvm_context;
pthread_mutex_t qemu_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -1395,6 +1396,11 @@ int qemu_kvm_has_sync_mmu(void)
return kvm_has_sync_mmu(kvm_context);
}
+int qemu_kvm_has_gbpages()
+{
+ return kvm_has_gbpages(kvm_context);
+}
+
void qemu_kvm_cpu_stop(CPUState *env)
{
if (kvm_enabled())
@@ -151,6 +151,7 @@ extern int kvm_irqchip;
extern int kvm_pit;
extern int kvm_pit_reinject;
extern int kvm_nested;
+extern int kvm_gb_pages;
extern kvm_context_t kvm_context;
struct ioperm_data {
@@ -161,6 +162,7 @@ struct ioperm_data {
};
int qemu_kvm_has_sync_mmu(void);
+int qemu_kvm_has_gbpages(void);
void qemu_kvm_cpu_stop(CPUState *env);
#define kvm_enabled() (kvm_allowed)
@@ -172,6 +174,7 @@ void kvm_load_tsc(CPUState *env);
#else
#define kvm_enabled() (0)
#define kvm_nested 0
+#define kvm_gb_pages 0
#define qemu_kvm_irqchip_in_kernel() (0)
#define qemu_kvm_pit_in_kernel() (0)
#define kvm_has_sync_mmu() (0)
@@ -1585,6 +1585,10 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
*ecx &= ~4UL;
/* 3dnow */
*edx &= ~0xc0000000;
+#ifdef USE_KVM
+ if (qemu_kvm_has_gbpages() && kvm_gb_pages)
+ *edx |= CPUID_EXT2_PDPE1GB;
+#endif
}
break;
case 0x80000002:
@@ -4189,6 +4189,7 @@ static void help(int exitcode)
"-no-kvm-pit disable KVM kernel mode PIT\n"
"-no-kvm-pit-reinjection disable KVM kernel mode PIT interrupt reinjection\n"
"-enable-nesting enable support for running a VM inside the VM (AMD only)\n"
+ "-enable-gb-pages enable GB pages in the guest (if host supports it)\n"
#if defined(TARGET_I386) || defined(TARGET_X86_64) || defined(TARGET_IA64) || defined(__linux__)
"-pcidevice host=bus:dev.func[,dma=none][,name=string]\n"
" expose a PCI device to the guest OS.\n"
@@ -4339,6 +4340,7 @@ enum {
QEMU_OPTION_no_kqemu,
QEMU_OPTION_enable_kvm,
QEMU_OPTION_enable_nesting,
+ QEMU_OPTION_enable_gb_pages,
QEMU_OPTION_no_kvm,
QEMU_OPTION_no_kvm_irqchip,
QEMU_OPTION_no_kvm_pit,
@@ -4488,6 +4490,7 @@ static const QEMUOption qemu_options[] = {
{ "no-kvm-pit", 0, QEMU_OPTION_no_kvm_pit },
{ "no-kvm-pit-reinjection", 0, QEMU_OPTION_no_kvm_pit_reinjection },
{ "enable-nesting", 0, QEMU_OPTION_enable_nesting },
+ { "enable-gb-pages", 0, QEMU_OPTION_enable_gb_pages },
#if defined(TARGET_I386) || defined(TARGET_X86_64) || defined(TARGET_IA64) || defined(__linux__)
{ "pcidevice", HAS_ARG, QEMU_OPTION_pcidevice },
#endif
@@ -5456,6 +5459,10 @@ int main(int argc, char **argv, char **envp)
kvm_nested = 1;
break;
}
+ case QEMU_OPTION_enable_gb_pages: {
+ kvm_gb_pages = 1;
+ break;
+ }
#if defined(TARGET_I386) || defined(TARGET_X86_64) || defined(TARGET_IA64) || defined(__linux__)
case QEMU_OPTION_pcidevice:
if (assigned_devices_index >= MAX_DEV_ASSIGN_CMDLINE) {
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com> --- libkvm/libkvm.c | 9 +++++++++ libkvm/libkvm.h | 1 + qemu/qemu-kvm.c | 6 ++++++ qemu/qemu-kvm.h | 3 +++ qemu/target-i386/helper.c | 4 ++++ qemu/vl.c | 7 +++++++ 6 files changed, 30 insertions(+), 0 deletions(-)