* [PATCH 1/3] KVM: x86: Rename gb_page_enable() to get_lpage_level() in kvm_x86_ops
2010-01-05 10:12 [PATCH 0/3] EPT 1GB page support Sheng Yang
@ 2010-01-05 10:12 ` Sheng Yang
2010-01-05 10:12 ` [PATCH 2/3] KVM: x86: Fix host_mapping_level() Sheng Yang
2010-01-05 10:12 ` [PATCH 3/3] KVM: VMX: Enable EPT 1GB page support Sheng Yang
2 siblings, 0 replies; 6+ messages in thread
From: Sheng Yang @ 2010-01-05 10:12 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, Sheng Yang
Then the callback can provide the maximum supported large page level, which
is more flexible.
Also move the gb page support into x86_64 specific.
Signed-off-by: Sheng Yang <sheng@linux.intel.com>
---
arch/x86/include/asm/kvm_host.h | 2 +-
arch/x86/kvm/svm.c | 6 +++---
arch/x86/kvm/vmx.c | 6 +++---
arch/x86/kvm/x86.c | 5 ++++-
4 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index fe4df46..31b986f 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -520,7 +520,7 @@ struct kvm_x86_ops {
int (*set_tss_addr)(struct kvm *kvm, unsigned int addr);
int (*get_tdp_level)(void);
u64 (*get_mt_mask)(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio);
- bool (*gb_page_enable)(void);
+ int (*get_lpage_level)(void);
bool (*rdtscp_supported)(void);
const struct trace_print_flags *exit_reasons_str;
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index b373ae6..c0153de 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -2911,9 +2911,9 @@ static const struct trace_print_flags svm_exit_reasons_str[] = {
{ -1, NULL }
};
-static bool svm_gb_page_enable(void)
+static int svm_get_lpage_level(void)
{
- return true;
+ return 3; /* PT_PDPE_LEVEL */
}
static bool svm_rdtscp_supported(void)
@@ -2986,7 +2986,7 @@ static struct kvm_x86_ops svm_x86_ops = {
.get_mt_mask = svm_get_mt_mask,
.exit_reasons_str = svm_exit_reasons_str,
- .gb_page_enable = svm_gb_page_enable,
+ .get_lpage_level = svm_get_lpage_level,
.cpuid_update = svm_cpuid_update,
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 2cc9b7e..c5b5ff6 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -4011,9 +4011,9 @@ static const struct trace_print_flags vmx_exit_reasons_str[] = {
{ -1, NULL }
};
-static bool vmx_gb_page_enable(void)
+static int vmx_get_lpage_level(void)
{
- return false;
+ return 2; /* PT_DIRECTORY_LEVEL */
}
static inline u32 bit(int bitno)
@@ -4106,7 +4106,7 @@ static struct kvm_x86_ops vmx_x86_ops = {
.get_mt_mask = vmx_get_mt_mask,
.exit_reasons_str = vmx_exit_reasons_str,
- .gb_page_enable = vmx_gb_page_enable,
+ .get_lpage_level = vmx_get_lpage_level,
.cpuid_update = vmx_cpuid_update,
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index fd6e1a5..2968dd0 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1641,10 +1641,13 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
u32 index, int *nent, int maxnent)
{
unsigned f_nx = is_efer_nx() ? F(NX) : 0;
- unsigned f_gbpages = kvm_x86_ops->gb_page_enable() ? F(GBPAGES) : 0;
#ifdef CONFIG_X86_64
+ /* PT_PDPE_LEVEL (mapping 1GB page) is 3 */
+ unsigned f_gbpages = (kvm_x86_ops->get_lpage_level() == 3) ?
+ F(GBPAGES) : 0;
unsigned f_lm = F(LM);
#else
+ unsigned f_gbpages = 0;
unsigned f_lm = 0;
#endif
unsigned f_rdtscp = kvm_x86_ops->rdtscp_supported() ? F(RDTSCP) : 0;
--
1.5.4.5
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 2/3] KVM: x86: Fix host_mapping_level()
2010-01-05 10:12 [PATCH 0/3] EPT 1GB page support Sheng Yang
2010-01-05 10:12 ` [PATCH 1/3] KVM: x86: Rename gb_page_enable() to get_lpage_level() in kvm_x86_ops Sheng Yang
@ 2010-01-05 10:12 ` Sheng Yang
2010-01-05 10:12 ` [PATCH 3/3] KVM: VMX: Enable EPT 1GB page support Sheng Yang
2 siblings, 0 replies; 6+ messages in thread
From: Sheng Yang @ 2010-01-05 10:12 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, Sheng Yang
When found a error hva, should not return PAGE_SIZE but the level...
Also clean up the coding style of the following loop.
Signed-off-by: Sheng Yang <sheng@linux.intel.com>
---
arch/x86/kvm/mmu.c | 6 ++----
1 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index c43c2ab..4f499d7 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -477,7 +477,7 @@ static int host_mapping_level(struct kvm *kvm, gfn_t gfn)
addr = gfn_to_hva(kvm, gfn);
if (kvm_is_error_hva(addr))
- return page_size;
+ return PT_PAGE_TABLE_LEVEL;
down_read(¤t->mm->mmap_sem);
vma = find_vma(current->mm, addr);
@@ -515,11 +515,9 @@ static int mapping_level(struct kvm_vcpu *vcpu, gfn_t large_gfn)
if (host_level == PT_PAGE_TABLE_LEVEL)
return host_level;
- for (level = PT_DIRECTORY_LEVEL; level <= host_level; ++level) {
-
+ for (level = PT_DIRECTORY_LEVEL; level <= host_level; ++level)
if (has_wrprotected_page(vcpu->kvm, large_gfn, level))
break;
- }
return level - 1;
}
--
1.5.4.5
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 3/3] KVM: VMX: Enable EPT 1GB page support
2010-01-05 10:12 [PATCH 0/3] EPT 1GB page support Sheng Yang
2010-01-05 10:12 ` [PATCH 1/3] KVM: x86: Rename gb_page_enable() to get_lpage_level() in kvm_x86_ops Sheng Yang
2010-01-05 10:12 ` [PATCH 2/3] KVM: x86: Fix host_mapping_level() Sheng Yang
@ 2010-01-05 10:12 ` Sheng Yang
2010-01-05 10:43 ` Avi Kivity
2 siblings, 1 reply; 6+ messages in thread
From: Sheng Yang @ 2010-01-05 10:12 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, Sheng Yang
Signed-off-by: Sheng Yang <sheng@linux.intel.com>
---
arch/x86/include/asm/vmx.h | 1 +
arch/x86/kvm/mmu.c | 8 +++++---
arch/x86/kvm/vmx.c | 11 ++++++++++-
3 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h
index 713ed9a..43f1e9b 100644
--- a/arch/x86/include/asm/vmx.h
+++ b/arch/x86/include/asm/vmx.h
@@ -364,6 +364,7 @@ enum vmcs_field {
#define VMX_EPTP_UC_BIT (1ull << 8)
#define VMX_EPTP_WB_BIT (1ull << 14)
#define VMX_EPT_2MB_PAGE_BIT (1ull << 16)
+#define VMX_EPT_1GB_PAGE_BIT (1ull << 17)
#define VMX_EPT_EXTENT_INDIVIDUAL_BIT (1ull << 24)
#define VMX_EPT_EXTENT_CONTEXT_BIT (1ull << 25)
#define VMX_EPT_EXTENT_GLOBAL_BIT (1ull << 26)
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 4f499d7..3cfd204 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -503,8 +503,7 @@ out:
static int mapping_level(struct kvm_vcpu *vcpu, gfn_t large_gfn)
{
struct kvm_memory_slot *slot;
- int host_level;
- int level = PT_PAGE_TABLE_LEVEL;
+ int host_level, level, max_level;
slot = gfn_to_memslot(vcpu->kvm, large_gfn);
if (slot && slot->dirty_bitmap)
@@ -515,7 +514,10 @@ static int mapping_level(struct kvm_vcpu *vcpu, gfn_t large_gfn)
if (host_level == PT_PAGE_TABLE_LEVEL)
return host_level;
- for (level = PT_DIRECTORY_LEVEL; level <= host_level; ++level)
+ max_level = kvm_x86_ops->get_lpage_level() < host_level ?
+ kvm_x86_ops->get_lpage_level() : host_level;
+
+ for (level = PT_DIRECTORY_LEVEL; level <= max_level; ++level)
if (has_wrprotected_page(vcpu->kvm, large_gfn, level))
break;
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index c5b5ff6..a6f72b5 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -318,6 +318,11 @@ static inline bool cpu_has_vmx_ept_2m_page(void)
return !!(vmx_capability.ept & VMX_EPT_2MB_PAGE_BIT);
}
+static inline bool cpu_has_vmx_ept_1g_page(void)
+{
+ return !!(vmx_capability.ept & VMX_EPT_1GB_PAGE_BIT);
+}
+
static inline int cpu_has_vmx_invept_individual_addr(void)
{
return !!(vmx_capability.ept & VMX_EPT_EXTENT_INDIVIDUAL_BIT);
@@ -4013,7 +4018,11 @@ static const struct trace_print_flags vmx_exit_reasons_str[] = {
static int vmx_get_lpage_level(void)
{
- return 2; /* PT_DIRECTORY_LEVEL */
+ if (enable_ept && !cpu_has_vmx_ept_1g_page())
+ return 2; /* PT_DIRECTORY_LEVEL */
+ else
+ /* For shadow and EPT supported 1GB page */
+ return 3; /* PT_PDPE_LEVEL */
}
static inline u32 bit(int bitno)
--
1.5.4.5
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH 3/3] KVM: VMX: Enable EPT 1GB page support
2010-01-05 10:12 ` [PATCH 3/3] KVM: VMX: Enable EPT 1GB page support Sheng Yang
@ 2010-01-05 10:43 ` Avi Kivity
2010-01-05 10:51 ` Sheng Yang
0 siblings, 1 reply; 6+ messages in thread
From: Avi Kivity @ 2010-01-05 10:43 UTC (permalink / raw)
To: Sheng Yang; +Cc: Marcelo Tosatti, kvm
On 01/05/2010 12:12 PM, Sheng Yang wrote:
> Signed-off-by: Sheng Yang<sheng@linux.intel.com>
> ---
> arch/x86/include/asm/vmx.h | 1 +
> arch/x86/kvm/mmu.c | 8 +++++---
> arch/x86/kvm/vmx.c | 11 ++++++++++-
> 3 files changed, 16 insertions(+), 4 deletions(-)
>
> diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h
> index 713ed9a..43f1e9b 100644
> --- a/arch/x86/include/asm/vmx.h
> +++ b/arch/x86/include/asm/vmx.h
> @@ -364,6 +364,7 @@ enum vmcs_field {
> #define VMX_EPTP_UC_BIT (1ull<< 8)
> #define VMX_EPTP_WB_BIT (1ull<< 14)
> #define VMX_EPT_2MB_PAGE_BIT (1ull<< 16)
> +#define VMX_EPT_1GB_PAGE_BIT (1ull<< 17)
>
Can you share when this feature will be available in hardware?
> static int vmx_get_lpage_level(void)
> {
> - return 2; /* PT_DIRECTORY_LEVEL */
> + if (enable_ept&& !cpu_has_vmx_ept_1g_page())
> + return 2; /* PT_DIRECTORY_LEVEL */
> + else
> + /* For shadow and EPT supported 1GB page */
> + return 3; /* PT_PDPE_LEVEL */
> }
>
>
Why not use the defines instead of numbers? It will reduce change when
we change PT_*_LEVEL to be zero based instead of one based.
Patchset looks good; second patch should go into .33 and stable, no?
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH 3/3] KVM: VMX: Enable EPT 1GB page support
2010-01-05 10:43 ` Avi Kivity
@ 2010-01-05 10:51 ` Sheng Yang
0 siblings, 0 replies; 6+ messages in thread
From: Sheng Yang @ 2010-01-05 10:51 UTC (permalink / raw)
To: Avi Kivity; +Cc: Marcelo Tosatti, kvm
On Tuesday 05 January 2010 18:43:21 Avi Kivity wrote:
> On 01/05/2010 12:12 PM, Sheng Yang wrote:
> > Signed-off-by: Sheng Yang<sheng@linux.intel.com>
> > ---
> > arch/x86/include/asm/vmx.h | 1 +
> > arch/x86/kvm/mmu.c | 8 +++++---
> > arch/x86/kvm/vmx.c | 11 ++++++++++-
> > 3 files changed, 16 insertions(+), 4 deletions(-)
> >
> > diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h
> > index 713ed9a..43f1e9b 100644
> > --- a/arch/x86/include/asm/vmx.h
> > +++ b/arch/x86/include/asm/vmx.h
> > @@ -364,6 +364,7 @@ enum vmcs_field {
> > #define VMX_EPTP_UC_BIT (1ull<< 8)
> > #define VMX_EPTP_WB_BIT (1ull<< 14)
> > #define VMX_EPT_2MB_PAGE_BIT (1ull<< 16)
> > +#define VMX_EPT_1GB_PAGE_BIT (1ull<< 17)
>
> Can you share when this feature will be available in hardware?
I think it should be with the 32nm Core i7 (at least highend server edition),
slated for early 2010 release.
>
> > static int vmx_get_lpage_level(void)
> > {
> > - return 2; /* PT_DIRECTORY_LEVEL */
> > + if (enable_ept&& !cpu_has_vmx_ept_1g_page())
> > + return 2; /* PT_DIRECTORY_LEVEL */
> > + else
> > + /* For shadow and EPT supported 1GB page */
> > + return 3; /* PT_PDPE_LEVEL */
> > }
>
> Why not use the defines instead of numbers? It will reduce change when
> we change PT_*_LEVEL to be zero based instead of one based.
Oh, sure (caused by a little chaos in mind...). Patch 1 is also
affected(cpuid). Would resent the patchset soon.
>
> Patchset looks good; second patch should go into .33 and stable, no?
>
Sure. I would cc stable later.
--
regards
Yang, Sheng
^ permalink raw reply [flat|nested] 6+ messages in thread