* [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