diff mbox

2.6.38-rc6: general protection error inside KVM 64 bits guest

Message ID 20110306124238.GC25565@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Gleb Natapov March 6, 2011, 12:42 p.m. UTC
None

Comments

Francis Moreau May 27, 2011, 10:22 a.m. UTC | #1
Hi guys,

Sorry for resurrecting this but I just checkout kernel v2.6.39 and
this fix doesn't seem to be present in this release...

Am I wrong ?

Thanks

On Wed, Mar 9, 2011 at 11:07 AM, Francis Moreau <francis.moro@gmail.com> wrote:
> On Wed, Mar 9, 2011 at 11:03 AM, Avi Kivity <avi@redhat.com> wrote:
>> On 03/09/2011 11:32 AM, Gleb Natapov wrote:
>>>
>>> On Wed, Mar 09, 2011 at 10:30:56AM +0100, Francis Moreau wrote:
>>> >  On Wed, Mar 9, 2011 at 10:25 AM, Gleb Natapov<gleb@redhat.com>  wrote:
>>> >  >  On Wed, Mar 09, 2011 at 08:05:54AM +0100, Francis Moreau wrote:
>>> >  >>  Hi,
>>> >  >>
>>> >  >>  On Sun, Mar 6, 2011 at 4:08 PM, Avi Kivity<avi@redhat.com>  wrote:
>>> >  >>  >  On 03/06/2011 05:02 PM, Avi Kivity wrote:
>>> >  >>  >>
>>> >  >>  >>  (for #TS we need additional logic... will this arch never end?)
>>> >  >>  >>
>>> >  >>  >
>>> >  >>  >  Actually these instructions don't generate #TS.
>>> >  >>  >
>>> >  >>
>>> >  >>  I just wanted to know if this issue is going to be fixed before
>>> > 2.6.38 is out ?
>>> >  >>
>>> >  >  I posted updated patches. It is up to maintainers to decide if the
>>> >  >  patches should be included in 2.6.38 at such late rc stage.
>>> >  >
>>> >
>>> >  Would have been nice to CC me since I reported the issue.
>>> >
>>> Yes, sorry about that. Avi please add Reported-by: to the patch too.
>>>
>>
>> Will be happy to add an -and-tested-by: too if you get the chance.
>>
>
> Sure you can add this since I already tested it and it fixed my test case.
>
> thanks
> --
> Francis
>
Gleb Natapov May 27, 2011, 12:48 p.m. UTC | #2
On Fri, May 27, 2011 at 12:22:52PM +0200, Francis Moreau wrote:
> Hi guys,
> 
> Sorry for resurrecting this but I just checkout kernel v2.6.39 and
> this fix doesn't seem to be present in this release...
> 
> Am I wrong ?
> 
Hmm. Should be fixed by commit: 5601d05b8c340ee2643febc146099325eff187eb

> Thanks
> 
> On Wed, Mar 9, 2011 at 11:07 AM, Francis Moreau <francis.moro@gmail.com> wrote:
> > On Wed, Mar 9, 2011 at 11:03 AM, Avi Kivity <avi@redhat.com> wrote:
> >> On 03/09/2011 11:32 AM, Gleb Natapov wrote:
> >>>
> >>> On Wed, Mar 09, 2011 at 10:30:56AM +0100, Francis Moreau wrote:
> >>> >  On Wed, Mar 9, 2011 at 10:25 AM, Gleb Natapov<gleb@redhat.com>  wrote:
> >>> >  >  On Wed, Mar 09, 2011 at 08:05:54AM +0100, Francis Moreau wrote:
> >>> >  >>  Hi,
> >>> >  >>
> >>> >  >>  On Sun, Mar 6, 2011 at 4:08 PM, Avi Kivity<avi@redhat.com>  wrote:
> >>> >  >>  >  On 03/06/2011 05:02 PM, Avi Kivity wrote:
> >>> >  >>  >>
> >>> >  >>  >>  (for #TS we need additional logic... will this arch never end?)
> >>> >  >>  >>
> >>> >  >>  >
> >>> >  >>  >  Actually these instructions don't generate #TS.
> >>> >  >>  >
> >>> >  >>
> >>> >  >>  I just wanted to know if this issue is going to be fixed before
> >>> > 2.6.38 is out ?
> >>> >  >>
> >>> >  >  I posted updated patches. It is up to maintainers to decide if the
> >>> >  >  patches should be included in 2.6.38 at such late rc stage.
> >>> >  >
> >>> >
> >>> >  Would have been nice to CC me since I reported the issue.
> >>> >
> >>> Yes, sorry about that. Avi please add Reported-by: to the patch too.
> >>>
> >>
> >> Will be happy to add an -and-tested-by: too if you get the chance.
> >>
> >
> > Sure you can add this since I already tested it and it fixed my test case.
> >
> > thanks
> > --
> > Francis
> >
> 
> 
> 
> -- 
> Francis

--
			Gleb.
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Francis Moreau May 27, 2011, 2:30 p.m. UTC | #3
Hello

2011/5/27 Gleb Natapov <gleb@redhat.com>:
> On Fri, May 27, 2011 at 12:22:52PM +0200, Francis Moreau wrote:
>> Hi guys,
>>
>> Sorry for resurrecting this but I just checkout kernel v2.6.39 and
>> this fix doesn't seem to be present in this release...
>>
>> Am I wrong ?
>>
> Hmm. Should be fixed by commit: 5601d05b8c340ee2643febc146099325eff187eb
>

Ah you're right, I was using a slightly different fix (your orginal
one), and I missed this commit.

Thanks
diff mbox

Patch

diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index 50ebc32..7ef5b86 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -142,10 +142,8 @@  struct x86_emulate_ops {
 	int (*pio_out_emulated)(int size, unsigned short port, const void *val,
 				unsigned int count, struct kvm_vcpu *vcpu);
 
-	bool (*get_cached_descriptor)(struct desc_struct *desc,
-				      int seg, struct kvm_vcpu *vcpu);
-	void (*set_cached_descriptor)(struct desc_struct *desc,
-				      int seg, struct kvm_vcpu *vcpu);
+	bool (*get_cached_descriptor)(void *p, int seg, struct kvm_vcpu *vcpu);
+	void (*set_cached_descriptor)(void *p, int seg, struct kvm_vcpu *vcpu);
 	u16 (*get_segment_selector)(int seg, struct kvm_vcpu *vcpu);
 	void (*set_segment_selector)(u16 sel, int seg, struct kvm_vcpu *vcpu);
 	unsigned long (*get_cached_segment_base)(int seg, struct kvm_vcpu *vcpu);
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index ad46239..d7d8b63 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -1764,25 +1764,35 @@  static bool emulator_io_port_access_allowed(struct x86_emulate_ctxt *ctxt,
 					    struct x86_emulate_ops *ops,
 					    u16 port, u16 len)
 {
-	struct desc_struct tr_seg;
+	union {
+		struct desc_struct tss32;
+#ifdef CONFIG_X86_64
+		struct ldttss_desc64 tss64;
+#endif
+	} tr_seg; 
 	int r;
 	u16 io_bitmap_ptr;
 	u8 perm, bit_idx = port & 0x7;
 	unsigned mask = (1 << len) - 1;
+	unsigned long base;
 
 	ops->get_cached_descriptor(&tr_seg, VCPU_SREG_TR, ctxt->vcpu);
-	if (!tr_seg.p)
+	if (!tr_seg.tss32.p)
 		return false;
-	if (desc_limit_scaled(&tr_seg) < 103)
+	if (desc_limit_scaled(&tr_seg.tss32) < 103)
 		return false;
-	r = ops->read_std(get_desc_base(&tr_seg) + 102, &io_bitmap_ptr, 2,
-			  ctxt->vcpu, NULL);
+	base = get_desc_base(&tr_seg.tss32);
+#ifdef CONFIG_X86_64
+	if (ctxt->mode == X86EMUL_MODE_PROT64)
+		base |= ((u64)tr_seg.tss64.base3) << 32;
+#endif
+	r = ops->read_std(base + 102, &io_bitmap_ptr, 2, ctxt->vcpu, NULL);
 	if (r != X86EMUL_CONTINUE)
 		return false;
-	if (io_bitmap_ptr + port/8 > desc_limit_scaled(&tr_seg))
+	if (io_bitmap_ptr + port/8 > desc_limit_scaled(&tr_seg.tss32))
 		return false;
-	r = ops->read_std(get_desc_base(&tr_seg) + io_bitmap_ptr + port/8,
-			  &perm, 1, ctxt->vcpu, NULL);
+	r = ops->read_std(base + io_bitmap_ptr + port/8, &perm, 1, ctxt->vcpu,
+			  NULL);
 	if (r != X86EMUL_CONTINUE)
 		return false;
 	if ((perm >> bit_idx) & mask)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 785ae0c..e41e098 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4162,11 +4162,12 @@  static unsigned long emulator_get_cached_segment_base(int seg,
 	return get_segment_base(vcpu, seg);
 }
 
-static bool emulator_get_cached_descriptor(struct desc_struct *desc, int seg,
+static bool emulator_get_cached_descriptor(void *p, int seg,
 					   struct kvm_vcpu *vcpu)
 {
 	struct kvm_segment var;
-
+	struct desc_struct *desc = p;
+	
 	kvm_get_segment(vcpu, &var, seg);
 
 	if (var.unusable)
@@ -4185,13 +4186,22 @@  static bool emulator_get_cached_descriptor(struct desc_struct *desc, int seg,
 	desc->d = var.db;
 	desc->g = var.g;
 
+#ifdef CONFIG_X86_64
+	if (seg == VCPU_SREG_TR && is_long_mode(vcpu)) {
+		struct ldttss_desc64 *tss64 = p;
+		tss64->base3 = var.base >> 32;
+		tss64->zero1 = 0;
+	}
+#endif
+
 	return true;
 }
 
-static void emulator_set_cached_descriptor(struct desc_struct *desc, int seg,
+static void emulator_set_cached_descriptor(void *p, int seg,
 					   struct kvm_vcpu *vcpu)
 {
 	struct kvm_segment var;
+	struct desc_struct *desc = p;
 
 	/* needed to preserve selector */
 	kvm_get_segment(vcpu, &var, seg);
@@ -4211,6 +4221,12 @@  static void emulator_set_cached_descriptor(struct desc_struct *desc, int seg,
 	var.present = desc->p;
 	var.unusable = !var.present;
 	var.padding = 0;
+#ifdef CONFIG_X86_64
+	if (seg == VCPU_SREG_TR && is_long_mode(vcpu)) {
+		struct ldttss_desc64 *tss64 = p;
+		var.base |= ((u64)tss64->base3) << 32;
+	}
+#endif
 
 	kvm_set_segment(vcpu, &var, seg);
 	return;