* [PATCH 01/11] KVM: SVM: Don't use kmap_atomic in nested_svm_map
2010-02-19 15:22 [PATCH 0/11] Nested SVM fixes v2 Joerg Roedel
@ 2010-02-19 15:23 ` Joerg Roedel
2010-02-19 15:23 ` [PATCH 02/11] KVM: SVM: Fix wrong interrupt injection in enable_irq_windows Joerg Roedel
` (10 subsequent siblings)
11 siblings, 0 replies; 19+ messages in thread
From: Joerg Roedel @ 2010-02-19 15:23 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, linux-kernel, Joerg Roedel, stable
Use of kmap_atomic disables preemption but if we run in
shadow-shadow mode the vmrun emulation executes kvm_set_cr3
which might sleep or fault. So use kmap instead for
nested_svm_map.
Cc: stable@kernel.org
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
arch/x86/kvm/svm.c | 47 ++++++++++++++++++++++++-----------------------
1 files changed, 24 insertions(+), 23 deletions(-)
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 2e1e8d6..63ecd4d 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -1417,7 +1417,7 @@ static inline int nested_svm_intr(struct vcpu_svm *svm)
return 0;
}
-static void *nested_svm_map(struct vcpu_svm *svm, u64 gpa, enum km_type idx)
+static void *nested_svm_map(struct vcpu_svm *svm, u64 gpa, struct page **_page)
{
struct page *page;
@@ -1425,7 +1425,9 @@ static void *nested_svm_map(struct vcpu_svm *svm, u64 gpa, enum km_type idx)
if (is_error_page(page))
goto error;
- return kmap_atomic(page, idx);
+ *_page = page;
+
+ return kmap(page);
error:
kvm_release_page_clean(page);
@@ -1434,16 +1436,9 @@ error:
return NULL;
}
-static void nested_svm_unmap(void *addr, enum km_type idx)
+static void nested_svm_unmap(struct page *page)
{
- struct page *page;
-
- if (!addr)
- return;
-
- page = kmap_atomic_to_page(addr);
-
- kunmap_atomic(addr, idx);
+ kunmap(page);
kvm_release_page_dirty(page);
}
@@ -1451,6 +1446,7 @@ static bool nested_svm_exit_handled_msr(struct vcpu_svm *svm)
{
u32 param = svm->vmcb->control.exit_info_1 & 1;
u32 msr = svm->vcpu.arch.regs[VCPU_REGS_RCX];
+ struct page *page;
bool ret = false;
u32 t0, t1;
u8 *msrpm;
@@ -1458,7 +1454,7 @@ static bool nested_svm_exit_handled_msr(struct vcpu_svm *svm)
if (!(svm->nested.intercept & (1ULL << INTERCEPT_MSR_PROT)))
return false;
- msrpm = nested_svm_map(svm, svm->nested.vmcb_msrpm, KM_USER0);
+ msrpm = nested_svm_map(svm, svm->nested.vmcb_msrpm, &page);
if (!msrpm)
goto out;
@@ -1486,7 +1482,7 @@ static bool nested_svm_exit_handled_msr(struct vcpu_svm *svm)
ret = msrpm[t1] & ((1 << param) << t0);
out:
- nested_svm_unmap(msrpm, KM_USER0);
+ nested_svm_unmap(page);
return ret;
}
@@ -1609,6 +1605,7 @@ static int nested_svm_vmexit(struct vcpu_svm *svm)
struct vmcb *nested_vmcb;
struct vmcb *hsave = svm->nested.hsave;
struct vmcb *vmcb = svm->vmcb;
+ struct page *page;
trace_kvm_nested_vmexit_inject(vmcb->control.exit_code,
vmcb->control.exit_info_1,
@@ -1616,7 +1613,7 @@ static int nested_svm_vmexit(struct vcpu_svm *svm)
vmcb->control.exit_int_info,
vmcb->control.exit_int_info_err);
- nested_vmcb = nested_svm_map(svm, svm->nested.vmcb, KM_USER0);
+ nested_vmcb = nested_svm_map(svm, svm->nested.vmcb, &page);
if (!nested_vmcb)
return 1;
@@ -1706,7 +1703,7 @@ static int nested_svm_vmexit(struct vcpu_svm *svm)
/* Exit nested SVM mode */
svm->nested.vmcb = 0;
- nested_svm_unmap(nested_vmcb, KM_USER0);
+ nested_svm_unmap(page);
kvm_mmu_reset_context(&svm->vcpu);
kvm_mmu_load(&svm->vcpu);
@@ -1717,9 +1714,10 @@ static int nested_svm_vmexit(struct vcpu_svm *svm)
static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm)
{
u32 *nested_msrpm;
+ struct page *page;
int i;
- nested_msrpm = nested_svm_map(svm, svm->nested.vmcb_msrpm, KM_USER0);
+ nested_msrpm = nested_svm_map(svm, svm->nested.vmcb_msrpm, &page);
if (!nested_msrpm)
return false;
@@ -1728,7 +1726,7 @@ static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm)
svm->vmcb->control.msrpm_base_pa = __pa(svm->nested.msrpm);
- nested_svm_unmap(nested_msrpm, KM_USER0);
+ nested_svm_unmap(page);
return true;
}
@@ -1738,8 +1736,9 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm)
struct vmcb *nested_vmcb;
struct vmcb *hsave = svm->nested.hsave;
struct vmcb *vmcb = svm->vmcb;
+ struct page *page;
- nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, KM_USER0);
+ nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, &page);
if (!nested_vmcb)
return false;
@@ -1851,7 +1850,7 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm)
svm->vmcb->control.event_inj = nested_vmcb->control.event_inj;
svm->vmcb->control.event_inj_err = nested_vmcb->control.event_inj_err;
- nested_svm_unmap(nested_vmcb, KM_USER0);
+ nested_svm_unmap(page);
enable_gif(svm);
@@ -1877,6 +1876,7 @@ static void nested_svm_vmloadsave(struct vmcb *from_vmcb, struct vmcb *to_vmcb)
static int vmload_interception(struct vcpu_svm *svm)
{
struct vmcb *nested_vmcb;
+ struct page *page;
if (nested_svm_check_permissions(svm))
return 1;
@@ -1884,12 +1884,12 @@ static int vmload_interception(struct vcpu_svm *svm)
svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
skip_emulated_instruction(&svm->vcpu);
- nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, KM_USER0);
+ nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, &page);
if (!nested_vmcb)
return 1;
nested_svm_vmloadsave(nested_vmcb, svm->vmcb);
- nested_svm_unmap(nested_vmcb, KM_USER0);
+ nested_svm_unmap(page);
return 1;
}
@@ -1897,6 +1897,7 @@ static int vmload_interception(struct vcpu_svm *svm)
static int vmsave_interception(struct vcpu_svm *svm)
{
struct vmcb *nested_vmcb;
+ struct page *page;
if (nested_svm_check_permissions(svm))
return 1;
@@ -1904,12 +1905,12 @@ static int vmsave_interception(struct vcpu_svm *svm)
svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
skip_emulated_instruction(&svm->vcpu);
- nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, KM_USER0);
+ nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, &page);
if (!nested_vmcb)
return 1;
nested_svm_vmloadsave(svm->vmcb, nested_vmcb);
- nested_svm_unmap(nested_vmcb, KM_USER0);
+ nested_svm_unmap(page);
return 1;
}
--
1.6.6
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 02/11] KVM: SVM: Fix wrong interrupt injection in enable_irq_windows
2010-02-19 15:22 [PATCH 0/11] Nested SVM fixes v2 Joerg Roedel
2010-02-19 15:23 ` [PATCH 01/11] KVM: SVM: Don't use kmap_atomic in nested_svm_map Joerg Roedel
@ 2010-02-19 15:23 ` Joerg Roedel
2010-02-22 10:29 ` Joerg Roedel
2010-02-19 15:23 ` [PATCH 03/11] KVM: SVM: Fix schedule-while-atomic on nested exception handling Joerg Roedel
` (9 subsequent siblings)
11 siblings, 1 reply; 19+ messages in thread
From: Joerg Roedel @ 2010-02-19 15:23 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, linux-kernel, Joerg Roedel, stable
The nested_svm_intr() function does not execute the vmexit
anymore. Therefore we may still be in the nested state after
that function ran. This patch changes the nested_svm_intr()
function to return wether the irq window could be enabled.
Cc: stable@kernel.org
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
arch/x86/kvm/svm.c | 17 ++++++++---------
1 files changed, 8 insertions(+), 9 deletions(-)
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 63ecd4d..f87fc98 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -1389,16 +1389,17 @@ static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
return nested_svm_exit_handled(svm);
}
-static inline int nested_svm_intr(struct vcpu_svm *svm)
+/* This function returns true if it is save to enable the irq window */
+static inline bool nested_svm_intr(struct vcpu_svm *svm)
{
if (!is_nested(svm))
- return 0;
+ return true;
if (!(svm->vcpu.arch.hflags & HF_VINTR_MASK))
- return 0;
+ return true;
if (!(svm->vcpu.arch.hflags & HF_HIF_MASK))
- return 0;
+ return false;
svm->vmcb->control.exit_code = SVM_EXIT_INTR;
@@ -1411,10 +1412,10 @@ static inline int nested_svm_intr(struct vcpu_svm *svm)
*/
svm->nested.exit_required = true;
trace_kvm_nested_intr_vmexit(svm->vmcb->save.rip);
- return 1;
+ return false;
}
- return 0;
+ return true;
}
static void *nested_svm_map(struct vcpu_svm *svm, u64 gpa, struct page **_page)
@@ -2563,13 +2564,11 @@ static void enable_irq_window(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
- nested_svm_intr(svm);
-
/* In case GIF=0 we can't rely on the CPU to tell us when
* GIF becomes 1, because that's a separate STGI/VMRUN intercept.
* The next time we get that intercept, this function will be
* called again though and we'll get the vintr intercept. */
- if (gif_set(svm)) {
+ if (gif_set(svm) && nested_svm_intr(svm)) {
svm_set_vintr(svm);
svm_inject_irq(svm, 0x0);
}
--
1.6.6
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH 02/11] KVM: SVM: Fix wrong interrupt injection in enable_irq_windows
2010-02-19 15:23 ` [PATCH 02/11] KVM: SVM: Fix wrong interrupt injection in enable_irq_windows Joerg Roedel
@ 2010-02-22 10:29 ` Joerg Roedel
2010-02-22 11:05 ` Avi Kivity
0 siblings, 1 reply; 19+ messages in thread
From: Joerg Roedel @ 2010-02-22 10:29 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, linux-kernel, stable
Hi Avi,
forgot this one? I did not find it in your tree.
Joerg
On Fri, Feb 19, 2010 at 04:23:01PM +0100, Joerg Roedel wrote:
> The nested_svm_intr() function does not execute the vmexit
> anymore. Therefore we may still be in the nested state after
> that function ran. This patch changes the nested_svm_intr()
> function to return wether the irq window could be enabled.
>
> Cc: stable@kernel.org
> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
> ---
> arch/x86/kvm/svm.c | 17 ++++++++---------
> 1 files changed, 8 insertions(+), 9 deletions(-)
>
> diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
> index 63ecd4d..f87fc98 100644
> --- a/arch/x86/kvm/svm.c
> +++ b/arch/x86/kvm/svm.c
> @@ -1389,16 +1389,17 @@ static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
> return nested_svm_exit_handled(svm);
> }
>
> -static inline int nested_svm_intr(struct vcpu_svm *svm)
> +/* This function returns true if it is save to enable the irq window */
> +static inline bool nested_svm_intr(struct vcpu_svm *svm)
> {
> if (!is_nested(svm))
> - return 0;
> + return true;
>
> if (!(svm->vcpu.arch.hflags & HF_VINTR_MASK))
> - return 0;
> + return true;
>
> if (!(svm->vcpu.arch.hflags & HF_HIF_MASK))
> - return 0;
> + return false;
>
> svm->vmcb->control.exit_code = SVM_EXIT_INTR;
>
> @@ -1411,10 +1412,10 @@ static inline int nested_svm_intr(struct vcpu_svm *svm)
> */
> svm->nested.exit_required = true;
> trace_kvm_nested_intr_vmexit(svm->vmcb->save.rip);
> - return 1;
> + return false;
> }
>
> - return 0;
> + return true;
> }
>
> static void *nested_svm_map(struct vcpu_svm *svm, u64 gpa, struct page **_page)
> @@ -2563,13 +2564,11 @@ static void enable_irq_window(struct kvm_vcpu *vcpu)
> {
> struct vcpu_svm *svm = to_svm(vcpu);
>
> - nested_svm_intr(svm);
> -
> /* In case GIF=0 we can't rely on the CPU to tell us when
> * GIF becomes 1, because that's a separate STGI/VMRUN intercept.
> * The next time we get that intercept, this function will be
> * called again though and we'll get the vintr intercept. */
> - if (gif_set(svm)) {
> + if (gif_set(svm) && nested_svm_intr(svm)) {
> svm_set_vintr(svm);
> svm_inject_irq(svm, 0x0);
> }
> --
> 1.6.6
>
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH 02/11] KVM: SVM: Fix wrong interrupt injection in enable_irq_windows
2010-02-22 10:29 ` Joerg Roedel
@ 2010-02-22 11:05 ` Avi Kivity
0 siblings, 0 replies; 19+ messages in thread
From: Avi Kivity @ 2010-02-22 11:05 UTC (permalink / raw)
To: Joerg Roedel; +Cc: Marcelo Tosatti, kvm, linux-kernel, stable
On 02/22/2010 12:29 PM, Joerg Roedel wrote:
> Hi Avi,
>
> forgot this one? I did not find it in your tree.
>
Whoops, dropped it accidentally. Thanks for checking. Applied now.
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 03/11] KVM: SVM: Fix schedule-while-atomic on nested exception handling
2010-02-19 15:22 [PATCH 0/11] Nested SVM fixes v2 Joerg Roedel
2010-02-19 15:23 ` [PATCH 01/11] KVM: SVM: Don't use kmap_atomic in nested_svm_map Joerg Roedel
2010-02-19 15:23 ` [PATCH 02/11] KVM: SVM: Fix wrong interrupt injection in enable_irq_windows Joerg Roedel
@ 2010-02-19 15:23 ` Joerg Roedel
2010-02-19 15:23 ` [PATCH 04/11] KVM: SVM: Sync all control registers on nested vmexit Joerg Roedel
` (8 subsequent siblings)
11 siblings, 0 replies; 19+ messages in thread
From: Joerg Roedel @ 2010-02-19 15:23 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, linux-kernel, Joerg Roedel, stable
Move the actual vmexit routine out of code that runs with
irqs and preemption disabled.
Cc: stable@kernel.org
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
arch/x86/kvm/svm.c | 23 +++++++++++++++++++----
1 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index f87fc98..6dc7a41 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -128,6 +128,7 @@ static void svm_flush_tlb(struct kvm_vcpu *vcpu);
static void svm_complete_interrupts(struct vcpu_svm *svm);
static int nested_svm_exit_handled(struct vcpu_svm *svm);
+static int nested_svm_intercept(struct vcpu_svm *svm);
static int nested_svm_vmexit(struct vcpu_svm *svm);
static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
bool has_error_code, u32 error_code);
@@ -1378,6 +1379,8 @@ static int nested_svm_check_permissions(struct vcpu_svm *svm)
static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
bool has_error_code, u32 error_code)
{
+ int vmexit;
+
if (!is_nested(svm))
return 0;
@@ -1386,7 +1389,11 @@ static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
svm->vmcb->control.exit_info_1 = error_code;
svm->vmcb->control.exit_info_2 = svm->vcpu.arch.cr2;
- return nested_svm_exit_handled(svm);
+ vmexit = nested_svm_intercept(svm);
+ if (vmexit == NESTED_EXIT_DONE)
+ svm->nested.exit_required = true;
+
+ return vmexit;
}
/* This function returns true if it is save to enable the irq window */
@@ -1516,7 +1523,7 @@ static int nested_svm_exit_special(struct vcpu_svm *svm)
/*
* If this function returns true, this #vmexit was already handled
*/
-static int nested_svm_exit_handled(struct vcpu_svm *svm)
+static int nested_svm_intercept(struct vcpu_svm *svm)
{
u32 exit_code = svm->vmcb->control.exit_code;
int vmexit = NESTED_EXIT_HOST;
@@ -1562,9 +1569,17 @@ static int nested_svm_exit_handled(struct vcpu_svm *svm)
}
}
- if (vmexit == NESTED_EXIT_DONE) {
+ return vmexit;
+}
+
+static int nested_svm_exit_handled(struct vcpu_svm *svm)
+{
+ int vmexit;
+
+ vmexit = nested_svm_intercept(svm);
+
+ if (vmexit == NESTED_EXIT_DONE)
nested_svm_vmexit(svm);
- }
return vmexit;
}
--
1.6.6
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 04/11] KVM: SVM: Sync all control registers on nested vmexit
2010-02-19 15:22 [PATCH 0/11] Nested SVM fixes v2 Joerg Roedel
` (2 preceding siblings ...)
2010-02-19 15:23 ` [PATCH 03/11] KVM: SVM: Fix schedule-while-atomic on nested exception handling Joerg Roedel
@ 2010-02-19 15:23 ` Joerg Roedel
2010-02-19 15:23 ` [PATCH 05/11] KVM: SVM: Annotate nested_svm_map with might_sleep() Joerg Roedel
` (7 subsequent siblings)
11 siblings, 0 replies; 19+ messages in thread
From: Joerg Roedel @ 2010-02-19 15:23 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, linux-kernel, Joerg Roedel, stable
Currently the vmexit emulation does not sync control
registers were the access is typically intercepted by the
nested hypervisor. But we can not count on that intercepts
to sync these registers too and make the code
architecturally more correct.
Cc: stable@kernel.org
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
arch/x86/kvm/svm.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 6dc7a41..c9d359a 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -1642,9 +1642,13 @@ static int nested_svm_vmexit(struct vcpu_svm *svm)
nested_vmcb->save.ds = vmcb->save.ds;
nested_vmcb->save.gdtr = vmcb->save.gdtr;
nested_vmcb->save.idtr = vmcb->save.idtr;
+ nested_vmcb->save.cr0 = kvm_read_cr0(&svm->vcpu);
if (npt_enabled)
nested_vmcb->save.cr3 = vmcb->save.cr3;
+ else
+ nested_vmcb->save.cr3 = svm->vcpu.arch.cr3;
nested_vmcb->save.cr2 = vmcb->save.cr2;
+ nested_vmcb->save.cr4 = svm->vcpu.arch.cr4;
nested_vmcb->save.rflags = vmcb->save.rflags;
nested_vmcb->save.rip = vmcb->save.rip;
nested_vmcb->save.rsp = vmcb->save.rsp;
--
1.6.6
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 05/11] KVM: SVM: Annotate nested_svm_map with might_sleep()
2010-02-19 15:22 [PATCH 0/11] Nested SVM fixes v2 Joerg Roedel
` (3 preceding siblings ...)
2010-02-19 15:23 ` [PATCH 04/11] KVM: SVM: Sync all control registers on nested vmexit Joerg Roedel
@ 2010-02-19 15:23 ` Joerg Roedel
2010-02-19 15:23 ` [PATCH 06/11] KVM: SVM: Fix nested msr intercept handling Joerg Roedel
` (6 subsequent siblings)
11 siblings, 0 replies; 19+ messages in thread
From: Joerg Roedel @ 2010-02-19 15:23 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, linux-kernel, Joerg Roedel
The nested_svm_map() function can sleep and must not be
called from atomic context. So annotate that function.
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
arch/x86/kvm/svm.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index c9d359a..4becefd 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -1429,6 +1429,8 @@ static void *nested_svm_map(struct vcpu_svm *svm, u64 gpa, struct page **_page)
{
struct page *page;
+ might_sleep();
+
page = gfn_to_page(svm->vcpu.kvm, gpa >> PAGE_SHIFT);
if (is_error_page(page))
goto error;
--
1.6.6
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 06/11] KVM: SVM: Fix nested msr intercept handling
2010-02-19 15:22 [PATCH 0/11] Nested SVM fixes v2 Joerg Roedel
` (4 preceding siblings ...)
2010-02-19 15:23 ` [PATCH 05/11] KVM: SVM: Annotate nested_svm_map with might_sleep() Joerg Roedel
@ 2010-02-19 15:23 ` Joerg Roedel
2010-02-19 15:23 ` [PATCH 07/11] KVM: SVM: Don't sync nested cr8 to lapic and back Joerg Roedel
` (5 subsequent siblings)
11 siblings, 0 replies; 19+ messages in thread
From: Joerg Roedel @ 2010-02-19 15:23 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, linux-kernel, Joerg Roedel, stable
The nested_svm_exit_handled_msr() function maps only one
page of the guests msr permission bitmap. This patch changes
the code to use kvm_read_guest to fix the bug.
Cc: stable@kernel.org
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
arch/x86/kvm/svm.c | 13 +++----------
1 files changed, 3 insertions(+), 10 deletions(-)
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 4becefd..f22ced1 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -1456,19 +1456,13 @@ static bool nested_svm_exit_handled_msr(struct vcpu_svm *svm)
{
u32 param = svm->vmcb->control.exit_info_1 & 1;
u32 msr = svm->vcpu.arch.regs[VCPU_REGS_RCX];
- struct page *page;
bool ret = false;
u32 t0, t1;
- u8 *msrpm;
+ u8 val;
if (!(svm->nested.intercept & (1ULL << INTERCEPT_MSR_PROT)))
return false;
- msrpm = nested_svm_map(svm, svm->nested.vmcb_msrpm, &page);
-
- if (!msrpm)
- goto out;
-
switch (msr) {
case 0 ... 0x1fff:
t0 = (msr * 2) % 8;
@@ -1489,11 +1483,10 @@ static bool nested_svm_exit_handled_msr(struct vcpu_svm *svm)
goto out;
}
- ret = msrpm[t1] & ((1 << param) << t0);
+ if (!kvm_read_guest(svm->vcpu.kvm, svm->nested.vmcb_msrpm + t1, &val, 1))
+ ret = val & ((1 << param) << t0);
out:
- nested_svm_unmap(page);
-
return ret;
}
--
1.6.6
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 07/11] KVM: SVM: Don't sync nested cr8 to lapic and back
2010-02-19 15:22 [PATCH 0/11] Nested SVM fixes v2 Joerg Roedel
` (5 preceding siblings ...)
2010-02-19 15:23 ` [PATCH 06/11] KVM: SVM: Fix nested msr intercept handling Joerg Roedel
@ 2010-02-19 15:23 ` Joerg Roedel
2010-02-19 15:23 ` [PATCH 08/11] KVM: SVM: Activate nested state only when guest state is complete Joerg Roedel
` (4 subsequent siblings)
11 siblings, 0 replies; 19+ messages in thread
From: Joerg Roedel @ 2010-02-19 15:23 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, linux-kernel, Joerg Roedel, stable
This patch makes syncing of the guest tpr to the lapic
conditional on !nested. Otherwise a nested guest using the
TPR could freeze the guest.
Another important change this patch introduces is that the
cr8 intercept bits are no longer ORed at vmrun emulation if
the guest sets VINTR_MASKING in its VMCB. The reason is that
nested cr8 accesses need alway be handled by the nested
hypervisor because they change the shadow version of the
tpr.
Cc: stable@kernel.org
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
arch/x86/kvm/svm.c | 46 +++++++++++++++++++++++++++++++---------------
1 files changed, 31 insertions(+), 15 deletions(-)
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index f22ced1..d7b75fb 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -1827,21 +1827,6 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm)
svm->vmcb->save.dr6 = nested_vmcb->save.dr6;
svm->vmcb->save.cpl = nested_vmcb->save.cpl;
- /* We don't want a nested guest to be more powerful than the guest,
- so all intercepts are ORed */
- svm->vmcb->control.intercept_cr_read |=
- nested_vmcb->control.intercept_cr_read;
- svm->vmcb->control.intercept_cr_write |=
- nested_vmcb->control.intercept_cr_write;
- svm->vmcb->control.intercept_dr_read |=
- nested_vmcb->control.intercept_dr_read;
- svm->vmcb->control.intercept_dr_write |=
- nested_vmcb->control.intercept_dr_write;
- svm->vmcb->control.intercept_exceptions |=
- nested_vmcb->control.intercept_exceptions;
-
- svm->vmcb->control.intercept |= nested_vmcb->control.intercept;
-
svm->nested.vmcb_msrpm = nested_vmcb->control.msrpm_base_pa;
/* cache intercepts */
@@ -1859,6 +1844,28 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm)
else
svm->vcpu.arch.hflags &= ~HF_VINTR_MASK;
+ if (svm->vcpu.arch.hflags & HF_VINTR_MASK) {
+ /* We only want the cr8 intercept bits of the guest */
+ svm->vmcb->control.intercept_cr_read &= ~INTERCEPT_CR8_MASK;
+ svm->vmcb->control.intercept_cr_write &= ~INTERCEPT_CR8_MASK;
+ }
+
+ /* We don't want a nested guest to be more powerful than the guest,
+ so all intercepts are ORed */
+ svm->vmcb->control.intercept_cr_read |=
+ nested_vmcb->control.intercept_cr_read;
+ svm->vmcb->control.intercept_cr_write |=
+ nested_vmcb->control.intercept_cr_write;
+ svm->vmcb->control.intercept_dr_read |=
+ nested_vmcb->control.intercept_dr_read;
+ svm->vmcb->control.intercept_dr_write |=
+ nested_vmcb->control.intercept_dr_write;
+ svm->vmcb->control.intercept_exceptions |=
+ nested_vmcb->control.intercept_exceptions;
+
+ svm->vmcb->control.intercept |= nested_vmcb->control.intercept;
+
+ svm->vmcb->control.lbr_ctl = nested_vmcb->control.lbr_ctl;
svm->vmcb->control.int_vector = nested_vmcb->control.int_vector;
svm->vmcb->control.int_state = nested_vmcb->control.int_state;
svm->vmcb->control.tsc_offset += nested_vmcb->control.tsc_offset;
@@ -2521,6 +2528,9 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr)
{
struct vcpu_svm *svm = to_svm(vcpu);
+ if (is_nested(svm) && (vcpu->arch.hflags & HF_VINTR_MASK))
+ return;
+
if (irr == -1)
return;
@@ -2622,6 +2632,9 @@ static inline void sync_cr8_to_lapic(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
+ if (is_nested(svm) && (vcpu->arch.hflags & HF_VINTR_MASK))
+ return;
+
if (!(svm->vmcb->control.intercept_cr_write & INTERCEPT_CR8_MASK)) {
int cr8 = svm->vmcb->control.int_ctl & V_TPR_MASK;
kvm_set_cr8(vcpu, cr8);
@@ -2633,6 +2646,9 @@ static inline void sync_lapic_to_cr8(struct kvm_vcpu *vcpu)
struct vcpu_svm *svm = to_svm(vcpu);
u64 cr8;
+ if (is_nested(svm) && (vcpu->arch.hflags & HF_VINTR_MASK))
+ return;
+
cr8 = kvm_get_cr8(vcpu);
svm->vmcb->control.int_ctl &= ~V_TPR_MASK;
svm->vmcb->control.int_ctl |= cr8 & V_TPR_MASK;
--
1.6.6
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 08/11] KVM: SVM: Activate nested state only when guest state is complete
2010-02-19 15:22 [PATCH 0/11] Nested SVM fixes v2 Joerg Roedel
` (6 preceding siblings ...)
2010-02-19 15:23 ` [PATCH 07/11] KVM: SVM: Don't sync nested cr8 to lapic and back Joerg Roedel
@ 2010-02-19 15:23 ` Joerg Roedel
2010-02-19 15:23 ` [PATCH 09/11] KVM: SVM: Make lazy FPU switching work with nested svm Joerg Roedel
` (3 subsequent siblings)
11 siblings, 0 replies; 19+ messages in thread
From: Joerg Roedel @ 2010-02-19 15:23 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, linux-kernel, Joerg Roedel
Certain functions called during the emulated world switch
behave differently when the vcpu is running nested. This is
not the expected behavior during a world switch emulation.
This patch ensures that the nested state is activated only
if the vcpu is completly in nested state.
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
arch/x86/kvm/svm.c | 15 +++++++++------
1 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index d7b75fb..4e8d42b 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -1628,6 +1628,9 @@ static int nested_svm_vmexit(struct vcpu_svm *svm)
if (!nested_vmcb)
return 1;
+ /* Exit nested SVM mode */
+ svm->nested.vmcb = 0;
+
/* Give the current vmcb to the guest */
disable_gif(svm);
@@ -1715,9 +1718,6 @@ static int nested_svm_vmexit(struct vcpu_svm *svm)
svm->vmcb->save.cpl = 0;
svm->vmcb->control.exit_int_info = 0;
- /* Exit nested SVM mode */
- svm->nested.vmcb = 0;
-
nested_svm_unmap(page);
kvm_mmu_reset_context(&svm->vcpu);
@@ -1752,14 +1752,14 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm)
struct vmcb *hsave = svm->nested.hsave;
struct vmcb *vmcb = svm->vmcb;
struct page *page;
+ u64 vmcb_gpa;
+
+ vmcb_gpa = svm->vmcb->save.rax;
nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, &page);
if (!nested_vmcb)
return false;
- /* nested_vmcb is our indicator if nested SVM is activated */
- svm->nested.vmcb = svm->vmcb->save.rax;
-
trace_kvm_nested_vmrun(svm->vmcb->save.rip - 3, svm->nested.vmcb,
nested_vmcb->save.rip,
nested_vmcb->control.int_ctl,
@@ -1874,6 +1874,9 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm)
nested_svm_unmap(page);
+ /* nested_vmcb is our indicator if nested SVM is activated */
+ svm->nested.vmcb = vmcb_gpa;
+
enable_gif(svm);
return true;
--
1.6.6
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 09/11] KVM: SVM: Make lazy FPU switching work with nested svm
2010-02-19 15:22 [PATCH 0/11] Nested SVM fixes v2 Joerg Roedel
` (7 preceding siblings ...)
2010-02-19 15:23 ` [PATCH 08/11] KVM: SVM: Activate nested state only when guest state is complete Joerg Roedel
@ 2010-02-19 15:23 ` Joerg Roedel
2010-02-19 15:23 ` [PATCH 10/11] KVM: SVM: Remove newlines from nested trace points Joerg Roedel
` (2 subsequent siblings)
11 siblings, 0 replies; 19+ messages in thread
From: Joerg Roedel @ 2010-02-19 15:23 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, linux-kernel, Joerg Roedel
The new lazy fpu switching code may disable cr0 intercepts
when running nested. This is a bug because the nested
hypervisor may still want to intercept cr0 which will break
in this situation. This patch fixes this issue and makes
lazy fpu switching working with nested svm.
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
arch/x86/kvm/svm.c | 43 +++++++++++++++++++++++++++++++++++++++----
1 files changed, 39 insertions(+), 4 deletions(-)
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 4e8d42b..8119355 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -973,6 +973,7 @@ static void svm_decache_cr4_guest_bits(struct kvm_vcpu *vcpu)
static void update_cr0_intercept(struct vcpu_svm *svm)
{
+ struct vmcb *vmcb = svm->vmcb;
ulong gcr0 = svm->vcpu.arch.cr0;
u64 *hcr0 = &svm->vmcb->save.cr0;
@@ -984,11 +985,25 @@ static void update_cr0_intercept(struct vcpu_svm *svm)
if (gcr0 == *hcr0 && svm->vcpu.fpu_active) {
- svm->vmcb->control.intercept_cr_read &= ~INTERCEPT_CR0_MASK;
- svm->vmcb->control.intercept_cr_write &= ~INTERCEPT_CR0_MASK;
+ vmcb->control.intercept_cr_read &= ~INTERCEPT_CR0_MASK;
+ vmcb->control.intercept_cr_write &= ~INTERCEPT_CR0_MASK;
+ if (is_nested(svm)) {
+ struct vmcb *hsave = svm->nested.hsave;
+
+ hsave->control.intercept_cr_read &= ~INTERCEPT_CR0_MASK;
+ hsave->control.intercept_cr_write &= ~INTERCEPT_CR0_MASK;
+ vmcb->control.intercept_cr_read |= svm->nested.intercept_cr_read;
+ vmcb->control.intercept_cr_write |= svm->nested.intercept_cr_write;
+ }
} else {
svm->vmcb->control.intercept_cr_read |= INTERCEPT_CR0_MASK;
svm->vmcb->control.intercept_cr_write |= INTERCEPT_CR0_MASK;
+ if (is_nested(svm)) {
+ struct vmcb *hsave = svm->nested.hsave;
+
+ hsave->control.intercept_cr_read |= INTERCEPT_CR0_MASK;
+ hsave->control.intercept_cr_write |= INTERCEPT_CR0_MASK;
+ }
}
}
@@ -1263,7 +1278,22 @@ static int ud_interception(struct vcpu_svm *svm)
static void svm_fpu_activate(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
- svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR);
+ u32 excp;
+
+ if (is_nested(svm)) {
+ u32 h_excp, n_excp;
+
+ h_excp = svm->nested.hsave->control.intercept_exceptions;
+ n_excp = svm->nested.intercept_exceptions;
+ h_excp &= ~(1 << NM_VECTOR);
+ excp = h_excp | n_excp;
+ } else {
+ excp = svm->vmcb->control.intercept_exceptions;
+ excp &= ~(1 << NM_VECTOR);
+ }
+
+ svm->vmcb->control.intercept_exceptions = excp;
+
svm->vcpu.fpu_active = 1;
update_cr0_intercept(svm);
}
@@ -1508,6 +1538,9 @@ static int nested_svm_exit_special(struct vcpu_svm *svm)
if (!npt_enabled)
return NESTED_EXIT_HOST;
break;
+ case SVM_EXIT_EXCP_BASE + NM_VECTOR:
+ nm_interception(svm);
+ break;
default:
break;
}
@@ -2973,8 +3006,10 @@ static void svm_fpu_deactivate(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
- update_cr0_intercept(svm);
svm->vmcb->control.intercept_exceptions |= 1 << NM_VECTOR;
+ if (is_nested(svm))
+ svm->nested.hsave->control.intercept_exceptions |= 1 << NM_VECTOR;
+ update_cr0_intercept(svm);
}
static struct kvm_x86_ops svm_x86_ops = {
--
1.6.6
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 10/11] KVM: SVM: Remove newlines from nested trace points
2010-02-19 15:22 [PATCH 0/11] Nested SVM fixes v2 Joerg Roedel
` (8 preceding siblings ...)
2010-02-19 15:23 ` [PATCH 09/11] KVM: SVM: Make lazy FPU switching work with nested svm Joerg Roedel
@ 2010-02-19 15:23 ` Joerg Roedel
2010-02-19 15:23 ` [PATCH 11/11] KVM: SVM: Don't call instruction emulator for invd and wbinvd Joerg Roedel
2010-02-21 9:56 ` [PATCH 0/11] Nested SVM fixes v2 Avi Kivity
11 siblings, 0 replies; 19+ messages in thread
From: Joerg Roedel @ 2010-02-19 15:23 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, linux-kernel, Joerg Roedel
The tracing infrastructure adds its own newlines. Remove
them from the trace point printk format strings.
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
arch/x86/kvm/trace.h | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h
index 6ad30a2..12f8d2d 100644
--- a/arch/x86/kvm/trace.h
+++ b/arch/x86/kvm/trace.h
@@ -413,7 +413,7 @@ TRACE_EVENT(kvm_nested_vmrun,
),
TP_printk("rip: 0x%016llx vmcb: 0x%016llx nrip: 0x%016llx int_ctl: 0x%08x "
- "event_inj: 0x%08x npt: %s\n",
+ "event_inj: 0x%08x npt: %s",
__entry->rip, __entry->vmcb, __entry->nested_rip,
__entry->int_ctl, __entry->event_inj,
__entry->npt ? "on" : "off")
@@ -447,7 +447,7 @@ TRACE_EVENT(kvm_nested_vmexit,
__entry->exit_int_info_err = exit_int_info_err;
),
TP_printk("rip: 0x%016llx reason: %s ext_inf1: 0x%016llx "
- "ext_inf2: 0x%016llx ext_int: 0x%08x ext_int_err: 0x%08x\n",
+ "ext_inf2: 0x%016llx ext_int: 0x%08x ext_int_err: 0x%08x",
__entry->rip,
ftrace_print_symbols_seq(p, __entry->exit_code,
kvm_x86_ops->exit_reasons_str),
@@ -482,7 +482,7 @@ TRACE_EVENT(kvm_nested_vmexit_inject,
),
TP_printk("reason: %s ext_inf1: 0x%016llx "
- "ext_inf2: 0x%016llx ext_int: 0x%08x ext_int_err: 0x%08x\n",
+ "ext_inf2: 0x%016llx ext_int: 0x%08x ext_int_err: 0x%08x",
ftrace_print_symbols_seq(p, __entry->exit_code,
kvm_x86_ops->exit_reasons_str),
__entry->exit_info1, __entry->exit_info2,
@@ -504,7 +504,7 @@ TRACE_EVENT(kvm_nested_intr_vmexit,
__entry->rip = rip
),
- TP_printk("rip: 0x%016llx\n", __entry->rip)
+ TP_printk("rip: 0x%016llx", __entry->rip)
);
/*
@@ -526,7 +526,7 @@ TRACE_EVENT(kvm_invlpga,
__entry->address = address;
),
- TP_printk("rip: 0x%016llx asid: %d address: 0x%016llx\n",
+ TP_printk("rip: 0x%016llx asid: %d address: 0x%016llx",
__entry->rip, __entry->asid, __entry->address)
);
@@ -547,7 +547,7 @@ TRACE_EVENT(kvm_skinit,
__entry->slb = slb;
),
- TP_printk("rip: 0x%016llx slb: 0x%08x\n",
+ TP_printk("rip: 0x%016llx slb: 0x%08x",
__entry->rip, __entry->slb)
);
--
1.6.6
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 11/11] KVM: SVM: Don't call instruction emulator for invd and wbinvd
2010-02-19 15:22 [PATCH 0/11] Nested SVM fixes v2 Joerg Roedel
` (9 preceding siblings ...)
2010-02-19 15:23 ` [PATCH 10/11] KVM: SVM: Remove newlines from nested trace points Joerg Roedel
@ 2010-02-19 15:23 ` Joerg Roedel
2010-02-21 9:53 ` Avi Kivity
2010-02-21 9:56 ` [PATCH 0/11] Nested SVM fixes v2 Avi Kivity
11 siblings, 1 reply; 19+ messages in thread
From: Joerg Roedel @ 2010-02-19 15:23 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, linux-kernel, Joerg Roedel
There is an intercept for WBINVD and INVD in SVM so we don't
need the instruction emulator. The primary reason is that
the current instruction emulator fails to emulate these
instructions and the rip is not advanced.
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
arch/x86/kvm/emulate.c | 4 ++++
arch/x86/kvm/svm.c | 14 ++++++++++++--
2 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 9beda8e..0180cb1 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -1029,6 +1029,10 @@ done_prefixes:
/* Unrecognised? */
if (c->d == 0) {
+ /* Don't fail for invd and wbinvd*/
+ if (c->twobyte && (c->b == 0x08 || c->b == 0x09))
+ return 0;
+
DPRINTF("Cannot emulate %02x\n", c->b);
return -1;
}
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 8119355..5fd00e8 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -2117,6 +2117,16 @@ static int cpuid_interception(struct vcpu_svm *svm)
return 1;
}
+static int invd_interception(struct vcpu_svm *svm)
+{
+ svm->next_rip = kvm_rip_read(&svm->vcpu) + 2;
+ skip_emulated_instruction(&svm->vcpu);
+
+ /* Nop */
+
+ return 1;
+}
+
static int iret_interception(struct vcpu_svm *svm)
{
++svm->vcpu.stat.nmi_window_exits;
@@ -2418,7 +2428,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = {
/* [SVM_EXIT_CR0_SEL_WRITE] = emulate_on_interception, */
[SVM_EXIT_CPUID] = cpuid_interception,
[SVM_EXIT_IRET] = iret_interception,
- [SVM_EXIT_INVD] = emulate_on_interception,
+ [SVM_EXIT_INVD] = invd_interception,
[SVM_EXIT_PAUSE] = pause_interception,
[SVM_EXIT_HLT] = halt_interception,
[SVM_EXIT_INVLPG] = invlpg_interception,
@@ -2434,7 +2444,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = {
[SVM_EXIT_STGI] = stgi_interception,
[SVM_EXIT_CLGI] = clgi_interception,
[SVM_EXIT_SKINIT] = skinit_interception,
- [SVM_EXIT_WBINVD] = emulate_on_interception,
+ [SVM_EXIT_WBINVD] = invd_interception,
[SVM_EXIT_MONITOR] = invalid_op_interception,
[SVM_EXIT_MWAIT] = invalid_op_interception,
[SVM_EXIT_NPF] = pf_interception,
--
1.6.6
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH 11/11] KVM: SVM: Don't call instruction emulator for invd and wbinvd
2010-02-19 15:23 ` [PATCH 11/11] KVM: SVM: Don't call instruction emulator for invd and wbinvd Joerg Roedel
@ 2010-02-21 9:53 ` Avi Kivity
2010-02-21 11:37 ` Joerg Roedel
0 siblings, 1 reply; 19+ messages in thread
From: Avi Kivity @ 2010-02-21 9:53 UTC (permalink / raw)
To: Joerg Roedel; +Cc: Marcelo Tosatti, kvm, linux-kernel
On 02/19/2010 05:23 PM, Joerg Roedel wrote:
> There is an intercept for WBINVD and INVD in SVM so we don't
> need the instruction emulator. The primary reason is that
> the current instruction emulator fails to emulate these
> instructions and the rip is not advanced.
>
The bios (at least bochs bios) does have wbinvd, so this ought to work.
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 11/11] KVM: SVM: Don't call instruction emulator for invd and wbinvd
2010-02-21 9:53 ` Avi Kivity
@ 2010-02-21 11:37 ` Joerg Roedel
2010-02-21 12:00 ` Avi Kivity
0 siblings, 1 reply; 19+ messages in thread
From: Joerg Roedel @ 2010-02-21 11:37 UTC (permalink / raw)
To: Avi Kivity; +Cc: Joerg Roedel, Marcelo Tosatti, kvm, linux-kernel
On Sun, Feb 21, 2010 at 11:53:14AM +0200, Avi Kivity wrote:
> On 02/19/2010 05:23 PM, Joerg Roedel wrote:
>> There is an intercept for WBINVD and INVD in SVM so we don't
>> need the instruction emulator. The primary reason is that
>> the current instruction emulator fails to emulate these
>> instructions and the rip is not advanced.
>>
>
> The bios (at least bochs bios) does have wbinvd, so this ought to work.
Weird. For some reason the Windows 7 XP emulation was executing wbinvd
which caused an nested intercept for the host level and the rip was not
advanced. So the nested guest did not advance and just produces wbinvd
intercepts all the time.
Joerg
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 11/11] KVM: SVM: Don't call instruction emulator for invd and wbinvd
2010-02-21 11:37 ` Joerg Roedel
@ 2010-02-21 12:00 ` Avi Kivity
2010-02-21 12:12 ` Joerg Roedel
0 siblings, 1 reply; 19+ messages in thread
From: Avi Kivity @ 2010-02-21 12:00 UTC (permalink / raw)
To: Joerg Roedel; +Cc: Joerg Roedel, Marcelo Tosatti, kvm, linux-kernel
On 02/21/2010 01:37 PM, Joerg Roedel wrote:
> On Sun, Feb 21, 2010 at 11:53:14AM +0200, Avi Kivity wrote:
>
>> On 02/19/2010 05:23 PM, Joerg Roedel wrote:
>>
>>> There is an intercept for WBINVD and INVD in SVM so we don't
>>> need the instruction emulator. The primary reason is that
>>> the current instruction emulator fails to emulate these
>>> instructions and the rip is not advanced.
>>>
>>>
>> The bios (at least bochs bios) does have wbinvd, so this ought to work.
>>
> Weird. For some reason the Windows 7 XP emulation was executing wbinvd
> which caused an nested intercept for the host level and the rip was not
> advanced. So the nested guest did not advance and just produces wbinvd
> intercepts all the time.
>
Has the guest enabled wbinvd interception? Perhaps not, so kvm has to
emulate wbinvd in the nested guest context, which is likely the only
case that we're called to do this. So the problem might be in emulating
within the nested guest.
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 11/11] KVM: SVM: Don't call instruction emulator for invd and wbinvd
2010-02-21 12:00 ` Avi Kivity
@ 2010-02-21 12:12 ` Joerg Roedel
0 siblings, 0 replies; 19+ messages in thread
From: Joerg Roedel @ 2010-02-21 12:12 UTC (permalink / raw)
To: Avi Kivity; +Cc: Joerg Roedel, Marcelo Tosatti, kvm, linux-kernel
On Sun, Feb 21, 2010 at 02:00:29PM +0200, Avi Kivity wrote:
> On 02/21/2010 01:37 PM, Joerg Roedel wrote:
>> Weird. For some reason the Windows 7 XP emulation was executing wbinvd
>> which caused an nested intercept for the host level and the rip was not
>> advanced. So the nested guest did not advance and just produces wbinvd
>> intercepts all the time.
>>
>
> Has the guest enabled wbinvd interception? Perhaps not, so kvm has to
> emulate wbinvd in the nested guest context, which is likely the only
> case that we're called to do this. So the problem might be in emulating
> within the nested guest.
Probably, but this was running on nested-shadow where gva_to_gpa is
expected to work even when the vcpu is running in nested mode. I'll
check this again.
Joerg
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 0/11] Nested SVM fixes v2
2010-02-19 15:22 [PATCH 0/11] Nested SVM fixes v2 Joerg Roedel
` (10 preceding siblings ...)
2010-02-19 15:23 ` [PATCH 11/11] KVM: SVM: Don't call instruction emulator for invd and wbinvd Joerg Roedel
@ 2010-02-21 9:56 ` Avi Kivity
11 siblings, 0 replies; 19+ messages in thread
From: Avi Kivity @ 2010-02-21 9:56 UTC (permalink / raw)
To: Joerg Roedel; +Cc: Marcelo Tosatti, kvm, linux-kernel
On 02/19/2010 05:22 PM, Joerg Roedel wrote:
> Hi,
>
> this is the second version of the KVM fixes queued up while testing
> nested svm with Windows 7 64 bit. Changes to the previous version:
>
> * Fixed kunmap bug
> * Introduced nested_svm_intercept insteat of
> nested_svm_exit_handled_atomic()
> * Added missing patch description
> * Added wbinvd/invd skip functions because the instruction
> emulator fails on these instructions (found during Windows 7
> XP mode bringup)
>
> Please review and comment (or apply ;-) these patches.
>
Applied 1-10, thanks. 11 got a comment.
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 19+ messages in thread