public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* Regression problem with commit 5045b46803
@ 2014-08-13 17:14 Nadav Amit
  2014-08-17  6:17 ` Paolo Bonzini
  0 siblings, 1 reply; 19+ messages in thread
From: Nadav Amit @ 2014-08-13 17:14 UTC (permalink / raw)
  To: pbonzini; +Cc: kvm

Commit 5045b46803 added a check that cs.dpl equals cs.rpl during
task-switch. Unfortunately, is causes some of my tests that run well on
bare-metal to fail.

Although this check is mentioned in table 7-1 of the SDM as causing a
#TSS exception, it is not mentioned in table 6-6 that lists "invalid TSS
conditions" which cause #TSS exceptions.

Thus, I recommend on reverting commit 5045b46803, or alternatively
rechecking task-switch behavior on bare-metal.

Nadav

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

* Re: Regression problem with commit 5045b46803
  2014-08-13 17:14 Regression problem with commit 5045b46803 Nadav Amit
@ 2014-08-17  6:17 ` Paolo Bonzini
  2014-08-17  6:23   ` Nadav Amit
  0 siblings, 1 reply; 19+ messages in thread
From: Paolo Bonzini @ 2014-08-17  6:17 UTC (permalink / raw)
  To: Nadav Amit; +Cc: kvm

Il 13/08/2014 19:14, Nadav Amit ha scritto:
> Commit 5045b46803 added a check that cs.dpl equals cs.rpl during
> task-switch. Unfortunately, is causes some of my tests that run well on
> bare-metal to fail.
> 
> Although this check is mentioned in table 7-1 of the SDM as causing a
> #TSS exception, it is not mentioned in table 6-6 that lists "invalid TSS
> conditions" which cause #TSS exceptions.
> 
> Thus, I recommend on reverting commit 5045b46803, or alternatively
> rechecking task-switch behavior on bare-metal.

Can you provide a kvm-unit-tests test for this?

Paolo


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

* Re: Regression problem with commit 5045b46803
  2014-08-17  6:17 ` Paolo Bonzini
@ 2014-08-17  6:23   ` Nadav Amit
  2014-08-17  6:28     ` Paolo Bonzini
  0 siblings, 1 reply; 19+ messages in thread
From: Nadav Amit @ 2014-08-17  6:23 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kvm


On Aug 17, 2014, at 9:17 AM, Paolo Bonzini <pbonzini@redhat.com> wrote:

> Il 13/08/2014 19:14, Nadav Amit ha scritto:
>> Commit 5045b46803 added a check that cs.dpl equals cs.rpl during
>> task-switch. Unfortunately, is causes some of my tests that run well on
>> bare-metal to fail.
>> 
>> Although this check is mentioned in table 7-1 of the SDM as causing a
>> #TSS exception, it is not mentioned in table 6-6 that lists "invalid TSS
>> conditions" which cause #TSS exceptions.
>> 
>> Thus, I recommend on reverting commit 5045b46803, or alternatively
>> rechecking task-switch behavior on bare-metal.
> 
> Can you provide a kvm-unit-tests test for this?

I need to put time into writing one. However, the unit test would prove nothing.
The question is how bare-metal behaves. According to what I see, it does not perform this check.

Nadav

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

* Re: Regression problem with commit 5045b46803
  2014-08-17  6:23   ` Nadav Amit
@ 2014-08-17  6:28     ` Paolo Bonzini
  2014-08-17  7:19       ` Nadav Amit
  0 siblings, 1 reply; 19+ messages in thread
From: Paolo Bonzini @ 2014-08-17  6:28 UTC (permalink / raw)
  To: Nadav Amit; +Cc: kvm

Il 17/08/2014 08:23, Nadav Amit ha scritto:
>>> >> Although this check is mentioned in table 7-1 of the SDM as causing a
>>> >> #TSS exception, it is not mentioned in table 6-6 that lists "invalid TSS
>>> >> conditions" which cause #TSS exceptions.
>>> >> 
>>> >> Thus, I recommend on reverting commit 5045b46803, or alternatively
>>> >> rechecking task-switch behavior on bare-metal.
>> > 
>> > Can you provide a kvm-unit-tests test for this?
> I need to put time into writing one. However, the unit test would prove nothing.
> The question is how bare-metal behaves. According to what I see, it does not perform this check.

Yes, but I still prefer to have a test, in case I find some time to fix
kvm-unit-tests to work on bare metal (or on Bochs).

There are already a few task switch tests (32-bit only).

Paolo

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

* Re: Regression problem with commit 5045b46803
  2014-08-17  6:28     ` Paolo Bonzini
@ 2014-08-17  7:19       ` Nadav Amit
  2014-08-17  9:35         ` Paolo Bonzini
  0 siblings, 1 reply; 19+ messages in thread
From: Nadav Amit @ 2014-08-17  7:19 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: KVM


On Aug 17, 2014, at 9:28 AM, Paolo Bonzini <pbonzini@redhat.com> wrote:

> Il 17/08/2014 08:23, Nadav Amit ha scritto:
>>>>>> Although this check is mentioned in table 7-1 of the SDM as causing a
>>>>>> #TSS exception, it is not mentioned in table 6-6 that lists "invalid TSS
>>>>>> conditions" which cause #TSS exceptions.
>>>>>> 
>>>>>> Thus, I recommend on reverting commit 5045b46803, or alternatively
>>>>>> rechecking task-switch behavior on bare-metal.
>>>> 
>>>> Can you provide a kvm-unit-tests test for this?
>> 
>> The question is how bare-metal behaves. According to what I see, it does not perform this check.
> 
> Yes, but I still prefer to have a test, in case I find some time to fix
> kvm-unit-tests to work on bare metal (or on Bochs).
> 
> There are already a few task switch tests (32-bit only).
> 

Can you please assist in running the existing task-switch tests first?

In x86_64 the task-switch tests are skipped. If I configure the tests to use the i386 architecture, the build fails.
Even after fixing the compilation errors, I don’t manage to get the task-switch tests to pass.

Nadav


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

* Re: Regression problem with commit 5045b46803
  2014-08-17  7:19       ` Nadav Amit
@ 2014-08-17  9:35         ` Paolo Bonzini
  2014-08-17 19:32           ` [PATCH] KVM: x86: Revert "check CS.DPL against RPL during task switch" Nadav Amit
  0 siblings, 1 reply; 19+ messages in thread
From: Paolo Bonzini @ 2014-08-17  9:35 UTC (permalink / raw)
  To: Nadav Amit; +Cc: KVM

Il 17/08/2014 09:19, Nadav Amit ha scritto:
> Can you please assist in running the existing task-switch tests first?
> 
> In x86_64 the task-switch tests are skipped. If I configure the tests to use the i386 architecture, the build fails.
> Even after fixing the compilation errors, I don’t manage to get the task-switch tests to pass.

Bitrot...  I sent a patch to fix this.  BTW you might be using the wrong
account to send email from? :)

Paolo

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

* [PATCH] KVM: x86: Revert "check CS.DPL against RPL during task switch"
  2014-08-17  9:35         ` Paolo Bonzini
@ 2014-08-17 19:32           ` Nadav Amit
  2014-08-17 19:34             ` [PATCH kvm-unit-tests] x86: Test task-switch with cs.rpl != cs.dpl Nadav Amit
  2014-08-17 21:09             ` [PATCH] KVM: x86: Revert "check CS.DPL against RPL during task switch" Paolo Bonzini
  0 siblings, 2 replies; 19+ messages in thread
From: Nadav Amit @ 2014-08-17 19:32 UTC (permalink / raw)
  To: pbonzini; +Cc: kvm, Nadav Amit

This reverts commit 5045b468037dfe1c848827ce10e99d87f5669160.  Although the
cs.dpl=cs.rpl check is mentioned in table 7-1 of the SDM as causing a #TSS
exception, it is not mentioned in table 6-6 that lists "invalid TSS conditions"
which cause #TSS exceptions. As it causes some tests, which pass on bare-metal,
to fail - it should be reverted.

Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
---
 arch/x86/kvm/emulate.c | 32 +++++++++++++++-----------------
 1 file changed, 15 insertions(+), 17 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 56657b0..b73c9e8 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -1415,7 +1415,7 @@ static int write_segment_descriptor(struct x86_emulate_ctxt *ctxt,
 
 /* Does not support long mode */
 static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
-				     u16 selector, int seg, u8 cpl, bool in_task_switch)
+				     u16 selector, int seg, u8 cpl)
 {
 	struct desc_struct seg_desc, old_desc;
 	u8 dpl, rpl;
@@ -1491,9 +1491,6 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
 			goto exception;
 		break;
 	case VCPU_SREG_CS:
-		if (in_task_switch && rpl != dpl)
-			goto exception;
-
 		if (!(seg_desc.type & 8))
 			goto exception;
 
@@ -1560,7 +1557,7 @@ static int load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
 				   u16 selector, int seg)
 {
 	u8 cpl = ctxt->ops->cpl(ctxt);
-	return __load_segment_descriptor(ctxt, selector, seg, cpl, false);
+	return __load_segment_descriptor(ctxt, selector, seg, cpl);
 }
 
 static void write_register_operand(struct operand *op)
@@ -2460,19 +2457,19 @@ static int load_state_from_tss16(struct x86_emulate_ctxt *ctxt,
 	 * Now load segment descriptors. If fault happens at this stage
 	 * it is handled in a context of new task
 	 */
-	ret = __load_segment_descriptor(ctxt, tss->ldt, VCPU_SREG_LDTR, cpl, true);
+	ret = __load_segment_descriptor(ctxt, tss->ldt, VCPU_SREG_LDTR, cpl);
 	if (ret != X86EMUL_CONTINUE)
 		return ret;
-	ret = __load_segment_descriptor(ctxt, tss->es, VCPU_SREG_ES, cpl, true);
+	ret = __load_segment_descriptor(ctxt, tss->es, VCPU_SREG_ES, cpl);
 	if (ret != X86EMUL_CONTINUE)
 		return ret;
-	ret = __load_segment_descriptor(ctxt, tss->cs, VCPU_SREG_CS, cpl, true);
+	ret = __load_segment_descriptor(ctxt, tss->cs, VCPU_SREG_CS, cpl);
 	if (ret != X86EMUL_CONTINUE)
 		return ret;
-	ret = __load_segment_descriptor(ctxt, tss->ss, VCPU_SREG_SS, cpl, true);
+	ret = __load_segment_descriptor(ctxt, tss->ss, VCPU_SREG_SS, cpl);
 	if (ret != X86EMUL_CONTINUE)
 		return ret;
-	ret = __load_segment_descriptor(ctxt, tss->ds, VCPU_SREG_DS, cpl, true);
+	ret = __load_segment_descriptor(ctxt, tss->ds, VCPU_SREG_DS, cpl);
 	if (ret != X86EMUL_CONTINUE)
 		return ret;
 
@@ -2597,25 +2594,26 @@ static int load_state_from_tss32(struct x86_emulate_ctxt *ctxt,
 	 * Now load segment descriptors. If fault happenes at this stage
 	 * it is handled in a context of new task
 	 */
-	ret = __load_segment_descriptor(ctxt, tss->ldt_selector, VCPU_SREG_LDTR, cpl, true);
+	ret = __load_segment_descriptor(ctxt, tss->ldt_selector, VCPU_SREG_LDTR,
+					cpl);
 	if (ret != X86EMUL_CONTINUE)
 		return ret;
-	ret = __load_segment_descriptor(ctxt, tss->es, VCPU_SREG_ES, cpl, true);
+	ret = __load_segment_descriptor(ctxt, tss->es, VCPU_SREG_ES, cpl);
 	if (ret != X86EMUL_CONTINUE)
 		return ret;
-	ret = __load_segment_descriptor(ctxt, tss->cs, VCPU_SREG_CS, cpl, true);
+	ret = __load_segment_descriptor(ctxt, tss->cs, VCPU_SREG_CS, cpl);
 	if (ret != X86EMUL_CONTINUE)
 		return ret;
-	ret = __load_segment_descriptor(ctxt, tss->ss, VCPU_SREG_SS, cpl, true);
+	ret = __load_segment_descriptor(ctxt, tss->ss, VCPU_SREG_SS, cpl);
 	if (ret != X86EMUL_CONTINUE)
 		return ret;
-	ret = __load_segment_descriptor(ctxt, tss->ds, VCPU_SREG_DS, cpl, true);
+	ret = __load_segment_descriptor(ctxt, tss->ds, VCPU_SREG_DS, cpl);
 	if (ret != X86EMUL_CONTINUE)
 		return ret;
-	ret = __load_segment_descriptor(ctxt, tss->fs, VCPU_SREG_FS, cpl, true);
+	ret = __load_segment_descriptor(ctxt, tss->fs, VCPU_SREG_FS, cpl);
 	if (ret != X86EMUL_CONTINUE)
 		return ret;
-	ret = __load_segment_descriptor(ctxt, tss->gs, VCPU_SREG_GS, cpl, true);
+	ret = __load_segment_descriptor(ctxt, tss->gs, VCPU_SREG_GS, cpl);
 	if (ret != X86EMUL_CONTINUE)
 		return ret;
 
-- 
1.9.1


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

* [PATCH kvm-unit-tests] x86: Test task-switch with cs.rpl != cs.dpl
  2014-08-17 19:32           ` [PATCH] KVM: x86: Revert "check CS.DPL against RPL during task switch" Nadav Amit
@ 2014-08-17 19:34             ` Nadav Amit
  2014-08-19 10:27               ` Paolo Bonzini
  2014-08-17 21:09             ` [PATCH] KVM: x86: Revert "check CS.DPL against RPL during task switch" Paolo Bonzini
  1 sibling, 1 reply; 19+ messages in thread
From: Nadav Amit @ 2014-08-17 19:34 UTC (permalink / raw)
  To: pbonzini; +Cc: kvm, Nadav Amit

Commit 5045b46803 added a check that cs.dpl equals cs.rpl during task-switch.
This is a wrong check, and this test introduces a test in which cs.dpl !=
cs.rpl. To do so, it configures tss.cs to be conforming with rpl=3 and dpl=0.
Since the cpl after calling is 3, it does not make any prints in the callee.

Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
---
 x86/taskswitch2.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/x86/taskswitch2.c b/x86/taskswitch2.c
index 92fc941..d96853f 100644
--- a/x86/taskswitch2.c
+++ b/x86/taskswitch2.c
@@ -7,6 +7,8 @@
 
 #define MAIN_TSS_SEL (FIRST_SPARE_SEL + 0)
 #define VM86_TSS_SEL (FIRST_SPARE_SEL + 8)
+#define USER_CS_SEL  (FIRST_SPARE_SEL + 16)
+#define USER_DS_SEL  (FIRST_SPARE_SEL + 24)
 
 static volatile int test_count;
 static volatile unsigned int test_divider;
@@ -102,6 +104,14 @@ start:
 	goto start;
 }
 
+static void user_tss(void)
+{
+start:
+	test_count++;
+	asm volatile ("iret");
+	goto start;
+}
+
 void test_kernel_mode_int()
 {
 	unsigned int res;
@@ -201,6 +211,18 @@ void test_kernel_mode_int()
 	asm volatile ("ljmp $" xstr(TSS_INTR) ", $0xf4f4f4f4");
 	printf("Jump back succeeded\n");
 	report("ljmp", test_count == 1);
+
+	/* test lcall with conforming segment, cs.dpl != cs.rpl */
+	test_count = 0;
+	set_intr_task_gate(0, user_tss);
+
+	tss_intr.cs = USER_CS_SEL | 3;
+	tss_intr.ss = USER_DS_SEL | 3;
+	tss_intr.ds = tss_intr.gs = tss_intr.fs = tss_intr.ss;
+	set_gdt_entry(USER_CS_SEL, 0, 0xffffffff, 0x9f, 0xc0);
+	set_gdt_entry(USER_DS_SEL, 0, 0xffffffff, 0xf3, 0xc0);
+	asm volatile("lcall $" xstr(TSS_INTR) ", $0xf4f4f4f4");
+	report("lcall when cs.rpl != cs.dpl", test_count == 1);
 }
 
 void test_vm86_switch(void)
-- 
1.9.1


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

* Re: [PATCH] KVM: x86: Revert "check CS.DPL against RPL during task switch"
  2014-08-17 19:32           ` [PATCH] KVM: x86: Revert "check CS.DPL against RPL during task switch" Nadav Amit
  2014-08-17 19:34             ` [PATCH kvm-unit-tests] x86: Test task-switch with cs.rpl != cs.dpl Nadav Amit
@ 2014-08-17 21:09             ` Paolo Bonzini
  2014-08-17 21:13               ` Paolo Bonzini
  2014-08-17 21:39               ` Nadav Amit
  1 sibling, 2 replies; 19+ messages in thread
From: Paolo Bonzini @ 2014-08-17 21:09 UTC (permalink / raw)
  To: Nadav Amit; +Cc: kvm

Il 17/08/2014 21:32, Nadav Amit ha scritto:
> This reverts commit 5045b468037dfe1c848827ce10e99d87f5669160.  Although the
> cs.dpl=cs.rpl check is mentioned in table 7-1 of the SDM as causing a #TSS
> exception, it is not mentioned in table 6-6 that lists "invalid TSS conditions"
> which cause #TSS exceptions. As it causes some tests, which pass on bare-metal,
> to fail - it should be reverted.

Right.  However, I think reverting the patch is too big a hammer.  We 
still need in_task_switch to raise TS_VECTOR instead of GP_VECTOR, so I 
propose instead something like:

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 56657b0bb3bb..cd230b035514 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -1468,7 +1468,7 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
 		return ret;
 
 	err_code = selector & 0xfffc;
-	err_vec = GP_VECTOR;
+	err_vec = in_task_switch ? TS_VECTOR : GP_VECTOR;
 
 	/* can't load system descriptor into segment selector */
 	if (seg <= VCPU_SREG_GS && !seg_desc.s)
@@ -1491,9 +1491,6 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
 			goto exception;
 		break;
 	case VCPU_SREG_CS:
-		if (in_task_switch && rpl != dpl)
-			goto exception;
-
 		if (!(seg_desc.type & 8))
 			goto exception;
 

either in a single patch or as two separate patch.  I'll test this against
your test case and repost (not before Tuesday).

Paolo

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

* Re: [PATCH] KVM: x86: Revert "check CS.DPL against RPL during task switch"
  2014-08-17 21:09             ` [PATCH] KVM: x86: Revert "check CS.DPL against RPL during task switch" Paolo Bonzini
@ 2014-08-17 21:13               ` Paolo Bonzini
  2014-08-17 21:33                 ` Nadav Amit
  2014-08-17 21:39               ` Nadav Amit
  1 sibling, 1 reply; 19+ messages in thread
From: Paolo Bonzini @ 2014-08-17 21:13 UTC (permalink / raw)
  To: Nadav Amit; +Cc: kvm

Il 17/08/2014 23:09, Paolo Bonzini ha scritto:
> Il 17/08/2014 21:32, Nadav Amit ha scritto:
>> This reverts commit 5045b468037dfe1c848827ce10e99d87f5669160.  Although the
>> cs.dpl=cs.rpl check is mentioned in table 7-1 of the SDM as causing a #TSS
>> exception, it is not mentioned in table 6-6 that lists "invalid TSS conditions"
>> which cause #TSS exceptions. As it causes some tests, which pass on bare-metal,
>> to fail - it should be reverted.
> 
> Right.  However, I think reverting the patch is too big a hammer.  We 
> still need in_task_switch to raise TS_VECTOR instead of GP_VECTOR, so I 
> propose instead something like:
> 
> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
> index 56657b0bb3bb..cd230b035514 100644
> --- a/arch/x86/kvm/emulate.c
> +++ b/arch/x86/kvm/emulate.c
> @@ -1468,7 +1468,7 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
>  		return ret;
>  
>  	err_code = selector & 0xfffc;
> -	err_vec = GP_VECTOR;
> +	err_vec = in_task_switch ? TS_VECTOR : GP_VECTOR;
>  
>  	/* can't load system descriptor into segment selector */
>  	if (seg <= VCPU_SREG_GS && !seg_desc.s)
> @@ -1491,9 +1491,6 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
>  			goto exception;
>  		break;
>  	case VCPU_SREG_CS:
> -		if (in_task_switch && rpl != dpl)
> -			goto exception;
> -
>  		if (!(seg_desc.type & 8))
>  			goto exception;
>  

Also, what about the rpl > cpl test below, for non-conforming code
segments?  It is not mentioned in table 6-6 either.

Paolo


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

* Re: [PATCH] KVM: x86: Revert "check CS.DPL against RPL during task switch"
  2014-08-17 21:13               ` Paolo Bonzini
@ 2014-08-17 21:33                 ` Nadav Amit
  2014-08-17 21:52                   ` Paolo Bonzini
  0 siblings, 1 reply; 19+ messages in thread
From: Nadav Amit @ 2014-08-17 21:33 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Nadav Amit, kvm


On Aug 18, 2014, at 12:13 AM, Paolo Bonzini <pbonzini@redhat.com> wrote:

> Il 17/08/2014 23:09, Paolo Bonzini ha scritto:
>> Il 17/08/2014 21:32, Nadav Amit ha scritto:
>>> This reverts commit 5045b468037dfe1c848827ce10e99d87f5669160.  Although the
>>> cs.dpl=cs.rpl check is mentioned in table 7-1 of the SDM as causing a #TSS
>>> exception, it is not mentioned in table 6-6 that lists "invalid TSS conditions"
>>> which cause #TSS exceptions. As it causes some tests, which pass on bare-metal,
>>> to fail - it should be reverted.
>> 
>> Right.  However, I think reverting the patch is too big a hammer.  We 
>> still need in_task_switch to raise TS_VECTOR instead of GP_VECTOR, so I 
>> propose instead something like:
>> 
>> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
>> index 56657b0bb3bb..cd230b035514 100644
>> --- a/arch/x86/kvm/emulate.c
>> +++ b/arch/x86/kvm/emulate.c
>> @@ -1468,7 +1468,7 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
>> 		return ret;
>> 
>> 	err_code = selector & 0xfffc;
>> -	err_vec = GP_VECTOR;
>> +	err_vec = in_task_switch ? TS_VECTOR : GP_VECTOR;
>> 
>> 	/* can't load system descriptor into segment selector */
>> 	if (seg <= VCPU_SREG_GS && !seg_desc.s)
>> @@ -1491,9 +1491,6 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
>> 			goto exception;
>> 		break;
>> 	case VCPU_SREG_CS:
>> -		if (in_task_switch && rpl != dpl)
>> -			goto exception;
>> -
>> 		if (!(seg_desc.type & 8))
>> 			goto exception;
>> 
> 
> Also, what about the rpl > cpl test below, for non-conforming code
> segments?  It is not mentioned in table 6-6 either.

As far as I understand, after task-switch cpl = cs.rpl. This is how the load_state_from_tss32 does it, and follows SDM 7.3, Task Switching: 
"The new task begins executing at the privilege level specified in the CPL field of the CS register, which is loaded from the TSS.”
As a result, this condition can never occur during task-switch.

Do I miss anything?

Nadav



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

* Re: [PATCH] KVM: x86: Revert "check CS.DPL against RPL during task switch"
  2014-08-17 21:09             ` [PATCH] KVM: x86: Revert "check CS.DPL against RPL during task switch" Paolo Bonzini
  2014-08-17 21:13               ` Paolo Bonzini
@ 2014-08-17 21:39               ` Nadav Amit
  2014-08-17 21:52                 ` Paolo Bonzini
  1 sibling, 1 reply; 19+ messages in thread
From: Nadav Amit @ 2014-08-17 21:39 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Nadav Amit, kvm

[-- Attachment #1: Type: text/plain, Size: 2009 bytes --]


On Aug 18, 2014, at 12:09 AM, Paolo Bonzini <pbonzini@redhat.com> wrote:

> Il 17/08/2014 21:32, Nadav Amit ha scritto:
>> This reverts commit 5045b468037dfe1c848827ce10e99d87f5669160.  Although the
>> cs.dpl=cs.rpl check is mentioned in table 7-1 of the SDM as causing a #TSS
>> exception, it is not mentioned in table 6-6 that lists "invalid TSS conditions"
>> which cause #TSS exceptions. As it causes some tests, which pass on bare-metal,
>> to fail - it should be reverted.
> 
> Right.  However, I think reverting the patch is too big a hammer.  We 
> still need in_task_switch to raise TS_VECTOR instead of GP_VECTOR, so I 
> propose instead something like:
> 
> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
> index 56657b0bb3bb..cd230b035514 100644
> --- a/arch/x86/kvm/emulate.c
> +++ b/arch/x86/kvm/emulate.c
> @@ -1468,7 +1468,7 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
>  		return ret;
> 
>  	err_code = selector & 0xfffc;
> -	err_vec = GP_VECTOR;
> +	err_vec = in_task_switch ? TS_VECTOR : GP_VECTOR;
> 
>  	/* can't load system descriptor into segment selector */
>  	if (seg <= VCPU_SREG_GS && !seg_desc.s)
> @@ -1491,9 +1491,6 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
>  			goto exception;
>  		break;
>  	case VCPU_SREG_CS:
> -		if (in_task_switch && rpl != dpl)
> -			goto exception;
> -
>  		if (!(seg_desc.type & 8))
>  			goto exception;
> 
> 
> either in a single patch or as two separate patch.  I'll test this against
> your test case and repost (not before Tuesday).
> 

I missed the TS_VECTOR thing. Yes, in that case, full revert makes no sense. I’m in no hurry with this patch, and I posted it during your vacation only because it is a recent bug.
Anyhow, you may want to look at another patch I sent, "KVM: x86: Avoid emulating instructions on #UD mistakenly”, ASAP. It fixes a bug that was introduced into 3.17-RC1 and is visible in userspace.

Nadav




[-- Attachment #2: Message signed with OpenPGP using GPGMail --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

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

* Re: [PATCH] KVM: x86: Revert "check CS.DPL against RPL during task switch"
  2014-08-17 21:39               ` Nadav Amit
@ 2014-08-17 21:52                 ` Paolo Bonzini
  0 siblings, 0 replies; 19+ messages in thread
From: Paolo Bonzini @ 2014-08-17 21:52 UTC (permalink / raw)
  To: Nadav Amit; +Cc: Nadav Amit, kvm

Il 17/08/2014 23:39, Nadav Amit ha scritto:
> I missed the TS_VECTOR thing. Yes, in that case, full revert makes no
> sense. I’m in no hurry with this patch, and I posted it during your
> vacation only because it is a recent bug. Anyhow, you may want to
> look at another patch I sent, "KVM: x86: Avoid emulating instructions
> on #UD mistakenly”, ASAP. It fixes a bug that was introduced into
> 3.17-RC1 and is visible in userspace.

Yes, it's on my list and will definitely get into one of the next 3.17
RCs.  Thanks,

Paolo

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

* Re: [PATCH] KVM: x86: Revert "check CS.DPL against RPL during task switch"
  2014-08-17 21:33                 ` Nadav Amit
@ 2014-08-17 21:52                   ` Paolo Bonzini
  0 siblings, 0 replies; 19+ messages in thread
From: Paolo Bonzini @ 2014-08-17 21:52 UTC (permalink / raw)
  To: Nadav Amit; +Cc: Nadav Amit, kvm

Il 17/08/2014 23:33, Nadav Amit ha scritto:
>> > Also, what about the rpl > cpl test below, for non-conforming code
>> > segments?  It is not mentioned in table 6-6 either.
> As far as I understand, after task-switch cpl = cs.rpl. This is how the load_state_from_tss32 does it, and follows SDM 7.3, Task Switching: 
> "The new task begins executing at the privilege level specified in the CPL field of the CS register, which is loaded from the TSS.”
> As a result, this condition can never occur during task-switch.
> 
> Do I miss anything?

No, you're right.

Paolo

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

* Re: [PATCH kvm-unit-tests] x86: Test task-switch with cs.rpl != cs.dpl
  2014-08-17 19:34             ` [PATCH kvm-unit-tests] x86: Test task-switch with cs.rpl != cs.dpl Nadav Amit
@ 2014-08-19 10:27               ` Paolo Bonzini
  2014-08-19 13:04                 ` [PATCH kvm-unit-tests v2] " Nadav Amit
  0 siblings, 1 reply; 19+ messages in thread
From: Paolo Bonzini @ 2014-08-19 10:27 UTC (permalink / raw)
  To: Nadav Amit; +Cc: kvm

Il 17/08/2014 21:34, Nadav Amit ha scritto:
> Commit 5045b46803 added a check that cs.dpl equals cs.rpl during task-switch.
> This is a wrong check, and this test introduces a test in which cs.dpl !=
> cs.rpl. To do so, it configures tss.cs to be conforming with rpl=3 and dpl=0.
> Since the cpl after calling is 3, it does not make any prints in the callee.
> 
> Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
> ---
>  x86/taskswitch2.c | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
> 
> diff --git a/x86/taskswitch2.c b/x86/taskswitch2.c
> index 92fc941..d96853f 100644
> --- a/x86/taskswitch2.c
> +++ b/x86/taskswitch2.c
> @@ -7,6 +7,8 @@
>  
>  #define MAIN_TSS_SEL (FIRST_SPARE_SEL + 0)
>  #define VM86_TSS_SEL (FIRST_SPARE_SEL + 8)
> +#define USER_CS_SEL  (FIRST_SPARE_SEL + 16)

Please call it CONFORM_CS_SEL since it's not really a user-mode selector
(DPL=0), it's just used as one (RPL=3).

> +#define USER_DS_SEL  (FIRST_SPARE_SEL + 24)

Not needed, see below.

>  
>  static volatile int test_count;
>  static volatile unsigned int test_divider;
> @@ -102,6 +104,14 @@ start:
>  	goto start;
>  }
>  
> +static void user_tss(void)
> +{
> +start:

Please add a printf and print_current_tss_info() here.

> +	test_count++;
> +	asm volatile ("iret");
> +	goto start;
> +}
> +
>  void test_kernel_mode_int()
>  {
>  	unsigned int res;
> @@ -201,6 +211,18 @@ void test_kernel_mode_int()
>  	asm volatile ("ljmp $" xstr(TSS_INTR) ", $0xf4f4f4f4");
>  	printf("Jump back succeeded\n");
>  	report("ljmp", test_count == 1);
> +
> +	/* test lcall with conforming segment, cs.dpl != cs.rpl */
> +	test_count = 0;
> +	set_intr_task_gate(0, user_tss);
> +
> +	tss_intr.cs = USER_CS_SEL | 3;
> +	tss_intr.ss = USER_DS_SEL | 3;
> +	tss_intr.ds = tss_intr.gs = tss_intr.fs = tss_intr.ss;
> +	set_gdt_entry(USER_CS_SEL, 0, 0xffffffff, 0x9f, 0xc0);
> +	set_gdt_entry(USER_DS_SEL, 0, 0xffffffff, 0xf3, 0xc0);

You can use USER_DS here.  Also, please put the test in a separate
function and call it last (after test_vm86_switch), because a failure in
this test breaks test_vm86_switch too.

Paolo

> +	asm volatile("lcall $" xstr(TSS_INTR) ", $0xf4f4f4f4");
> +	report("lcall when cs.rpl != cs.dpl", test_count == 1);
>  }
>  
>  void test_vm86_switch(void)
> 


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

* [PATCH kvm-unit-tests v2] x86: Test task-switch with cs.rpl != cs.dpl
  2014-08-19 10:27               ` Paolo Bonzini
@ 2014-08-19 13:04                 ` Nadav Amit
  2014-08-19 13:28                   ` Paolo Bonzini
  0 siblings, 1 reply; 19+ messages in thread
From: Nadav Amit @ 2014-08-19 13:04 UTC (permalink / raw)
  To: gleb; +Cc: kvm, Nadav Amit

Commit 5045b46803 added a check that cs.dpl equals cs.rpl during task-switch.
This is a wrong check, and this patch introduces a test in which cs.dpl !=
cs.rpl. To do so, it configures tss.cs to be conforming with rpl=3 and dpl=0.
Since the cpl after calling is 3, it does not make any prints in the callee.

Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
---
 x86/taskswitch2.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/x86/taskswitch2.c b/x86/taskswitch2.c
index 92fc941..1fe833e 100644
--- a/x86/taskswitch2.c
+++ b/x86/taskswitch2.c
@@ -7,6 +7,7 @@
 
 #define MAIN_TSS_SEL (FIRST_SPARE_SEL + 0)
 #define VM86_TSS_SEL (FIRST_SPARE_SEL + 8)
+#define CONFORM_CS_SEL  (FIRST_SPARE_SEL + 16)
 
 static volatile int test_count;
 static volatile unsigned int test_divider;
@@ -102,6 +103,14 @@ start:
 	goto start;
 }
 
+static void user_tss(void)
+{
+start:
+	test_count++;
+	asm volatile ("iret");
+	goto start;
+}
+
 void test_kernel_mode_int()
 {
 	unsigned int res;
@@ -248,6 +257,19 @@ void test_vm86_switch(void)
     report("VM86", 1);
 }
 
+void test_conforming_switch(void)
+{
+	/* test lcall with conforming segment, cs.dpl != cs.rpl */
+	test_count = 0;
+	set_intr_task_gate(0, user_tss);
+
+	tss_intr.cs = CONFORM_CS_SEL | 3;
+	tss_intr.ds = tss_intr.gs = tss_intr.fs = tss_intr.ss = USER_DS;
+	set_gdt_entry(CONFORM_CS_SEL, 0, 0xffffffff, 0x9f, 0xc0);
+	asm volatile("lcall $" xstr(TSS_INTR) ", $0xf4f4f4f4");
+	report("lcall with cs.rpl != cs.dpl", test_count == 1);
+}
+
 int main()
 {
 	setup_vm();
@@ -256,6 +278,7 @@ int main()
 
 	test_kernel_mode_int();
 	test_vm86_switch();
+	test_conforming_switch();
 
 	return report_summary();
 }
-- 
1.9.1


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

* Re: [PATCH kvm-unit-tests v2] x86: Test task-switch with cs.rpl != cs.dpl
  2014-08-19 13:04                 ` [PATCH kvm-unit-tests v2] " Nadav Amit
@ 2014-08-19 13:28                   ` Paolo Bonzini
  2014-08-19 13:34                     ` Nadav Amit
  0 siblings, 1 reply; 19+ messages in thread
From: Paolo Bonzini @ 2014-08-19 13:28 UTC (permalink / raw)
  To: Nadav Amit, gleb; +Cc: kvm

Il 19/08/2014 15:04, Nadav Amit ha scritto:
> Commit 5045b46803 added a check that cs.dpl equals cs.rpl during task-switch.
> This is a wrong check, and this patch introduces a test in which cs.dpl !=
> cs.rpl. To do so, it configures tss.cs to be conforming with rpl=3 and dpl=0.
> Since the cpl after calling is 3, it does not make any prints in the callee.
> 
> Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
> ---
>  x86/taskswitch2.c | 23 +++++++++++++++++++++++
>  1 file changed, 23 insertions(+)
> 
> diff --git a/x86/taskswitch2.c b/x86/taskswitch2.c
> index 92fc941..1fe833e 100644
> --- a/x86/taskswitch2.c
> +++ b/x86/taskswitch2.c
> @@ -7,6 +7,7 @@
>  
>  #define MAIN_TSS_SEL (FIRST_SPARE_SEL + 0)
>  #define VM86_TSS_SEL (FIRST_SPARE_SEL + 8)
> +#define CONFORM_CS_SEL  (FIRST_SPARE_SEL + 16)
>  
>  static volatile int test_count;
>  static volatile unsigned int test_divider;
> @@ -102,6 +103,14 @@ start:
>  	goto start;
>  }
>  
> +static void user_tss(void)
> +{
> +start:
> +	test_count++;
> +	asm volatile ("iret");
> +	goto start;
> +}
> +
>  void test_kernel_mode_int()
>  {
>  	unsigned int res;
> @@ -248,6 +257,19 @@ void test_vm86_switch(void)
>      report("VM86", 1);
>  }
>  
> +void test_conforming_switch(void)
> +{
> +	/* test lcall with conforming segment, cs.dpl != cs.rpl */
> +	test_count = 0;
> +	set_intr_task_gate(0, user_tss);

No need to use set_intr_task_gate, since the IDT is not involved here.

        tss_intr.eip = (u32)user_tss;

is enough.

I fixed this up and applied the patch.  Thanks!

Paolo

> +
> +	tss_intr.cs = CONFORM_CS_SEL | 3;
> +	tss_intr.ds = tss_intr.gs = tss_intr.fs = tss_intr.ss = USER_DS;
> +	set_gdt_entry(CONFORM_CS_SEL, 0, 0xffffffff, 0x9f, 0xc0);
> +	asm volatile("lcall $" xstr(TSS_INTR) ", $0xf4f4f4f4");
> +	report("lcall with cs.rpl != cs.dpl", test_count == 1);
> +}
> +
>  int main()
>  {
>  	setup_vm();
> @@ -256,6 +278,7 @@ int main()
>  
>  	test_kernel_mode_int();
>  	test_vm86_switch();
> +	test_conforming_switch();
>  
>  	return report_summary();
>  }
> 


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

* Re: [PATCH kvm-unit-tests v2] x86: Test task-switch with cs.rpl != cs.dpl
  2014-08-19 13:28                   ` Paolo Bonzini
@ 2014-08-19 13:34                     ` Nadav Amit
  2014-08-19 13:37                       ` Paolo Bonzini
  0 siblings, 1 reply; 19+ messages in thread
From: Nadav Amit @ 2014-08-19 13:34 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Nadav Amit, gleb, kvm

[-- Attachment #1: Type: text/plain, Size: 621 bytes --]


On Aug 19, 2014, at 4:28 PM, Paolo Bonzini <pbonzini@redhat.com> wrote:

> Il 19/08/2014 15:04, Nadav Amit ha scritto:
>> 
>> +void test_conforming_switch(void)
>> +{
>> +	/* test lcall with conforming segment, cs.dpl != cs.rpl */
>> +	test_count = 0;
>> +	set_intr_task_gate(0, user_tss);
> 
> No need to use set_intr_task_gate, since the IDT is not involved here.
> 
>        tss_intr.eip = (u32)user_tss;
> 
> is enough.
> 
> I fixed this up and applied the patch.  Thanks!

I know, but all the other ‘call' tests did. If there is an error, at least it should be consistent. ;-)

Thanks,
Nadav

[-- Attachment #2: Message signed with OpenPGP using GPGMail --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

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

* Re: [PATCH kvm-unit-tests v2] x86: Test task-switch with cs.rpl != cs.dpl
  2014-08-19 13:34                     ` Nadav Amit
@ 2014-08-19 13:37                       ` Paolo Bonzini
  0 siblings, 0 replies; 19+ messages in thread
From: Paolo Bonzini @ 2014-08-19 13:37 UTC (permalink / raw)
  To: Nadav Amit; +Cc: Nadav Amit, gleb, kvm

Il 19/08/2014 15:34, Nadav Amit ha scritto:
> I know, but all the other ‘call' tests did. If there is an error, at
> least it should be consistent. ;-)

Right, let's fix it up:

diff --git a/x86/taskswitch2.c b/x86/taskswitch2.c
index fd9a404..3cfb467 100644
--- a/x86/taskswitch2.c
+++ b/x86/taskswitch2.c
@@ -190,7 +190,7 @@ void test_kernel_mode_int()

 	/* test that calling a task by lcall works */
 	test_count = 0;
-	set_intr_task_gate(0, irq_tss);
+	tss_intr.eip = (u32)irq_tss;
 	printf("Calling task by lcall\n");
 	/* hlt opcode is 0xf4 I use destination IP 0xf4f4f4f4 to catch
 	   incorrect instruction length calculation */
@@ -205,7 +205,7 @@ void test_kernel_mode_int()

 	/* test that calling a task by ljmp works */
 	test_count = 0;
-	set_intr_task_gate(0, jmp_tss);
+	tss_intr.eip = (u32)jmp_tss;
 	printf("Jumping to a task by ljmp\n");
 	asm volatile ("ljmp $" xstr(TSS_INTR) ", $0xf4f4f4f4");
 	printf("Jump back succeeded\n");


Paolo

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

end of thread, other threads:[~2014-08-19 13:38 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-08-13 17:14 Regression problem with commit 5045b46803 Nadav Amit
2014-08-17  6:17 ` Paolo Bonzini
2014-08-17  6:23   ` Nadav Amit
2014-08-17  6:28     ` Paolo Bonzini
2014-08-17  7:19       ` Nadav Amit
2014-08-17  9:35         ` Paolo Bonzini
2014-08-17 19:32           ` [PATCH] KVM: x86: Revert "check CS.DPL against RPL during task switch" Nadav Amit
2014-08-17 19:34             ` [PATCH kvm-unit-tests] x86: Test task-switch with cs.rpl != cs.dpl Nadav Amit
2014-08-19 10:27               ` Paolo Bonzini
2014-08-19 13:04                 ` [PATCH kvm-unit-tests v2] " Nadav Amit
2014-08-19 13:28                   ` Paolo Bonzini
2014-08-19 13:34                     ` Nadav Amit
2014-08-19 13:37                       ` Paolo Bonzini
2014-08-17 21:09             ` [PATCH] KVM: x86: Revert "check CS.DPL against RPL during task switch" Paolo Bonzini
2014-08-17 21:13               ` Paolo Bonzini
2014-08-17 21:33                 ` Nadav Amit
2014-08-17 21:52                   ` Paolo Bonzini
2014-08-17 21:39               ` Nadav Amit
2014-08-17 21:52                 ` Paolo Bonzini

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