public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] Fix vmx real-mode state leakage
@ 2011-01-03 12:28 Avi Kivity
  2011-01-03 12:28 ` [PATCH 1/2] KVM: VMX: Save and restore tr selector across mode switches Avi Kivity
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Avi Kivity @ 2011-01-03 12:28 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

When emulating real mode, we fake some segment state to conform with vm86
mode.  Unfortunately, we allow the guest to see this fake state if we live
migrate when this state is in effect.  This patchset corrects the problem.

Avi Kivity (2):
  KVM: VMX: Save and restore tr selector across mode switches
  KVM: VMX: Avoid leaking fake realmode state to userspace

 arch/x86/kvm/vmx.c |   45 ++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 38 insertions(+), 7 deletions(-)


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/2] KVM: VMX: Save and restore tr selector across mode switches
  2011-01-03 12:28 [PATCH 0/2] Fix vmx real-mode state leakage Avi Kivity
@ 2011-01-03 12:28 ` Avi Kivity
  2011-01-03 12:28 ` [PATCH 2/2] KVM: VMX: Avoid leaking fake realmode state to userspace Avi Kivity
  2011-01-07  9:47 ` [PATCH 0/2] Fix vmx real-mode state leakage Marcelo Tosatti
  2 siblings, 0 replies; 4+ messages in thread
From: Avi Kivity @ 2011-01-03 12:28 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

When emulating real mode we play with tr hidden state, but leave
tr.selector alone.  That works well, except for save/restore, since
loading TR writes it to the hidden state in vmx->rmode.

Fix by also saving and restoring the tr selector; this makes things
more consistent and allows migration to work during the early
boot stages of Windows XP.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/vmx.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index bf89ec2..a2e83a9 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -1683,6 +1683,7 @@ static void enter_pmode(struct kvm_vcpu *vcpu)
 	vmx->emulation_required = 1;
 	vmx->rmode.vm86_active = 0;
 
+	vmcs_write16(GUEST_TR_SELECTOR, vmx->rmode.tr.selector);
 	vmcs_writel(GUEST_TR_BASE, vmx->rmode.tr.base);
 	vmcs_write32(GUEST_TR_LIMIT, vmx->rmode.tr.limit);
 	vmcs_write32(GUEST_TR_AR_BYTES, vmx->rmode.tr.ar);
@@ -1756,6 +1757,7 @@ static void enter_rmode(struct kvm_vcpu *vcpu)
 	vmx->emulation_required = 1;
 	vmx->rmode.vm86_active = 1;
 
+	vmx->rmode.tr.selector = vmcs_read16(GUEST_TR_SELECTOR);
 	vmx->rmode.tr.base = vmcs_readl(GUEST_TR_BASE);
 	vmcs_writel(GUEST_TR_BASE, rmode_tss_base(vcpu->kvm));
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2] KVM: VMX: Avoid leaking fake realmode state to userspace
  2011-01-03 12:28 [PATCH 0/2] Fix vmx real-mode state leakage Avi Kivity
  2011-01-03 12:28 ` [PATCH 1/2] KVM: VMX: Save and restore tr selector across mode switches Avi Kivity
@ 2011-01-03 12:28 ` Avi Kivity
  2011-01-07  9:47 ` [PATCH 0/2] Fix vmx real-mode state leakage Marcelo Tosatti
  2 siblings, 0 replies; 4+ messages in thread
From: Avi Kivity @ 2011-01-03 12:28 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

When emulating real mode, we fake some state:

 - tr.base points to a fake vm86 tss
 - segment registers are made to conform to vm86 restrictions

change vmx_get_segment() not to expose this fake state to userspace;
instead, return the original state.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/vmx.c |   43 ++++++++++++++++++++++++++++++++++++-------
 1 files changed, 36 insertions(+), 7 deletions(-)

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index a2e83a9..87ad551 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2032,23 +2032,40 @@ static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
 	vmcs_writel(GUEST_CR4, hw_cr4);
 }
 
-static u64 vmx_get_segment_base(struct kvm_vcpu *vcpu, int seg)
-{
-	struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
-
-	return vmcs_readl(sf->base);
-}
-
 static void vmx_get_segment(struct kvm_vcpu *vcpu,
 			    struct kvm_segment *var, int seg)
 {
+	struct vcpu_vmx *vmx = to_vmx(vcpu);
 	struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
+	struct kvm_save_segment *save;
 	u32 ar;
 
+	if (vmx->rmode.vm86_active
+	    && (seg == VCPU_SREG_TR || seg == VCPU_SREG_ES
+		|| seg == VCPU_SREG_DS || seg == VCPU_SREG_FS
+		|| seg == VCPU_SREG_GS)
+	    && !emulate_invalid_guest_state) {
+		switch (seg) {
+		case VCPU_SREG_TR: save = &vmx->rmode.tr; break;
+		case VCPU_SREG_ES: save = &vmx->rmode.es; break;
+		case VCPU_SREG_DS: save = &vmx->rmode.ds; break;
+		case VCPU_SREG_FS: save = &vmx->rmode.fs; break;
+		case VCPU_SREG_GS: save = &vmx->rmode.gs; break;
+		default: BUG();
+		}
+		var->selector = save->selector;
+		var->base = save->base;
+		var->limit = save->limit;
+		ar = save->ar;
+		if (seg == VCPU_SREG_TR
+		    || var->selector == vmcs_read16(sf->selector))
+			goto use_saved_rmode_seg;
+	}
 	var->base = vmcs_readl(sf->base);
 	var->limit = vmcs_read32(sf->limit);
 	var->selector = vmcs_read16(sf->selector);
 	ar = vmcs_read32(sf->ar_bytes);
+use_saved_rmode_seg:
 	if ((ar & AR_UNUSABLE_MASK) && !emulate_invalid_guest_state)
 		ar = 0;
 	var->type = ar & 15;
@@ -2062,6 +2079,18 @@ static void vmx_get_segment(struct kvm_vcpu *vcpu,
 	var->unusable = (ar >> 16) & 1;
 }
 
+static u64 vmx_get_segment_base(struct kvm_vcpu *vcpu, int seg)
+{
+	struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
+	struct kvm_segment s;
+
+	if (to_vmx(vcpu)->rmode.vm86_active) {
+		vmx_get_segment(vcpu, &s, seg);
+		return s.base;
+	}
+	return vmcs_readl(sf->base);
+}
+
 static int vmx_get_cpl(struct kvm_vcpu *vcpu)
 {
 	if (!is_protmode(vcpu))
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 0/2] Fix vmx real-mode state leakage
  2011-01-03 12:28 [PATCH 0/2] Fix vmx real-mode state leakage Avi Kivity
  2011-01-03 12:28 ` [PATCH 1/2] KVM: VMX: Save and restore tr selector across mode switches Avi Kivity
  2011-01-03 12:28 ` [PATCH 2/2] KVM: VMX: Avoid leaking fake realmode state to userspace Avi Kivity
@ 2011-01-07  9:47 ` Marcelo Tosatti
  2 siblings, 0 replies; 4+ messages in thread
From: Marcelo Tosatti @ 2011-01-07  9:47 UTC (permalink / raw)
  To: Avi Kivity; +Cc: kvm

On Mon, Jan 03, 2011 at 02:28:50PM +0200, Avi Kivity wrote:
> When emulating real mode, we fake some segment state to conform with vm86
> mode.  Unfortunately, we allow the guest to see this fake state if we live
> migrate when this state is in effect.  This patchset corrects the problem.
> 
> Avi Kivity (2):
>   KVM: VMX: Save and restore tr selector across mode switches
>   KVM: VMX: Avoid leaking fake realmode state to userspace
> 
>  arch/x86/kvm/vmx.c |   45 ++++++++++++++++++++++++++++++++++++++-------
>  1 files changed, 38 insertions(+), 7 deletions(-)

Applied, thanks.


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2011-01-07  9:48 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-01-03 12:28 [PATCH 0/2] Fix vmx real-mode state leakage Avi Kivity
2011-01-03 12:28 ` [PATCH 1/2] KVM: VMX: Save and restore tr selector across mode switches Avi Kivity
2011-01-03 12:28 ` [PATCH 2/2] KVM: VMX: Avoid leaking fake realmode state to userspace Avi Kivity
2011-01-07  9:47 ` [PATCH 0/2] Fix vmx real-mode state leakage Marcelo Tosatti

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox