diff mbox

[PATCHv2,1/6] KVM: emulator: drop RPL check from linearize() function

Message ID 1356015467-32607-2-git-send-email-gleb@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Gleb Natapov Dec. 20, 2012, 2:57 p.m. UTC
According to Intel SDM Vol3 Section 5.5 "Privilege Levels" and 5.6
"Privilege Level Checking When Accessing Data Segments" RPL checking is
done during loading of a segment selector, not during data access. We
already do checking during segment selector loading, so drop the check
during data access. Checking RPL during data access triggers #GP if
after transition from real mode to protected mode RPL bits in a segment
selector are set.

Signed-off-by: Gleb Natapov <gleb@redhat.com>
---
 arch/x86/kvm/emulate.c |    7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

Comments

Jan Kiszka Feb. 11, 2013, 4:58 p.m. UTC | #1
On 2012-12-20 15:57, Gleb Natapov wrote:
> According to Intel SDM Vol3 Section 5.5 "Privilege Levels" and 5.6
> "Privilege Level Checking When Accessing Data Segments" RPL checking is
> done during loading of a segment selector, not during data access. We
> already do checking during segment selector loading, so drop the check
> during data access. Checking RPL during data access triggers #GP if
> after transition from real mode to protected mode RPL bits in a segment
> selector are set.
> 
> Signed-off-by: Gleb Natapov <gleb@redhat.com>
> ---
>  arch/x86/kvm/emulate.c |    7 +------
>  1 file changed, 1 insertion(+), 6 deletions(-)
> 
> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
> index c7547b3..a3d31e3 100644
> --- a/arch/x86/kvm/emulate.c
> +++ b/arch/x86/kvm/emulate.c
> @@ -665,7 +665,7 @@ static int __linearize(struct x86_emulate_ctxt *ctxt,
>  	ulong la;
>  	u32 lim;
>  	u16 sel;
> -	unsigned cpl, rpl;
> +	unsigned cpl;
>  
>  	la = seg_base(ctxt, addr.seg) + addr.ea;
>  	switch (ctxt->mode) {
> @@ -699,11 +699,6 @@ static int __linearize(struct x86_emulate_ctxt *ctxt,
>  				goto bad;
>  		}
>  		cpl = ctxt->ops->cpl(ctxt);
> -		if (ctxt->mode == X86EMUL_MODE_REAL)
> -			rpl = 0;
> -		else
> -			rpl = sel & 3;
> -		cpl = max(cpl, rpl);
>  		if (!(desc.type & 8)) {
>  			/* data segment */
>  			if (cpl > desc.dpl)
> 

I suppose this one is queued for 3.8 and stable already, right? We
happen to hit the case reliably while booting an older SUSE guest on an
AMD host.

Jan
Gleb Natapov Feb. 11, 2013, 5:25 p.m. UTC | #2
On Mon, Feb 11, 2013 at 05:58:24PM +0100, Jan Kiszka wrote:
> On 2012-12-20 15:57, Gleb Natapov wrote:
> > According to Intel SDM Vol3 Section 5.5 "Privilege Levels" and 5.6
> > "Privilege Level Checking When Accessing Data Segments" RPL checking is
> > done during loading of a segment selector, not during data access. We
> > already do checking during segment selector loading, so drop the check
> > during data access. Checking RPL during data access triggers #GP if
> > after transition from real mode to protected mode RPL bits in a segment
> > selector are set.
> > 
> > Signed-off-by: Gleb Natapov <gleb@redhat.com>
> > ---
> >  arch/x86/kvm/emulate.c |    7 +------
> >  1 file changed, 1 insertion(+), 6 deletions(-)
> > 
> > diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
> > index c7547b3..a3d31e3 100644
> > --- a/arch/x86/kvm/emulate.c
> > +++ b/arch/x86/kvm/emulate.c
> > @@ -665,7 +665,7 @@ static int __linearize(struct x86_emulate_ctxt *ctxt,
> >  	ulong la;
> >  	u32 lim;
> >  	u16 sel;
> > -	unsigned cpl, rpl;
> > +	unsigned cpl;
> >  
> >  	la = seg_base(ctxt, addr.seg) + addr.ea;
> >  	switch (ctxt->mode) {
> > @@ -699,11 +699,6 @@ static int __linearize(struct x86_emulate_ctxt *ctxt,
> >  				goto bad;
> >  		}
> >  		cpl = ctxt->ops->cpl(ctxt);
> > -		if (ctxt->mode == X86EMUL_MODE_REAL)
> > -			rpl = 0;
> > -		else
> > -			rpl = sel & 3;
> > -		cpl = max(cpl, rpl);
> >  		if (!(desc.type & 8)) {
> >  			/* data segment */
> >  			if (cpl > desc.dpl)
> > 
> 
> I suppose this one is queued for 3.8 and stable already, right? We
> happen to hit the case reliably while booting an older SUSE guest on an
> AMD host.
> 
The patch was in the middle of the pile of vmx real mode fixes. I had
no reports that it can be triggered on its own, so it was not queued
neither to 3.8 nor to stable. Is it a regression?  If yes what version
the bug appears in?

--
			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
Jan Kiszka Feb. 11, 2013, 5:31 p.m. UTC | #3
On 2013-02-11 18:25, Gleb Natapov wrote:
> On Mon, Feb 11, 2013 at 05:58:24PM +0100, Jan Kiszka wrote:
>> On 2012-12-20 15:57, Gleb Natapov wrote:
>>> According to Intel SDM Vol3 Section 5.5 "Privilege Levels" and 5.6
>>> "Privilege Level Checking When Accessing Data Segments" RPL checking is
>>> done during loading of a segment selector, not during data access. We
>>> already do checking during segment selector loading, so drop the check
>>> during data access. Checking RPL during data access triggers #GP if
>>> after transition from real mode to protected mode RPL bits in a segment
>>> selector are set.
>>>
>>> Signed-off-by: Gleb Natapov <gleb@redhat.com>
>>> ---
>>>  arch/x86/kvm/emulate.c |    7 +------
>>>  1 file changed, 1 insertion(+), 6 deletions(-)
>>>
>>> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
>>> index c7547b3..a3d31e3 100644
>>> --- a/arch/x86/kvm/emulate.c
>>> +++ b/arch/x86/kvm/emulate.c
>>> @@ -665,7 +665,7 @@ static int __linearize(struct x86_emulate_ctxt *ctxt,
>>>  	ulong la;
>>>  	u32 lim;
>>>  	u16 sel;
>>> -	unsigned cpl, rpl;
>>> +	unsigned cpl;
>>>  
>>>  	la = seg_base(ctxt, addr.seg) + addr.ea;
>>>  	switch (ctxt->mode) {
>>> @@ -699,11 +699,6 @@ static int __linearize(struct x86_emulate_ctxt *ctxt,
>>>  				goto bad;
>>>  		}
>>>  		cpl = ctxt->ops->cpl(ctxt);
>>> -		if (ctxt->mode == X86EMUL_MODE_REAL)
>>> -			rpl = 0;
>>> -		else
>>> -			rpl = sel & 3;
>>> -		cpl = max(cpl, rpl);
>>>  		if (!(desc.type & 8)) {
>>>  			/* data segment */
>>>  			if (cpl > desc.dpl)
>>>
>>
>> I suppose this one is queued for 3.8 and stable already, right? We
>> happen to hit the case reliably while booting an older SUSE guest on an
>> AMD host.
>>
> The patch was in the middle of the pile of vmx real mode fixes. I had
> no reports that it can be triggered on its own, so it was not queued
> neither to 3.8 nor to stable. Is it a regression?  If yes what version
> the bug appears in?

It is a regression of 618ff15 ("implement segment permission checks"),
thus 3.0. We are running on such a 3.0.x host kernel (SLES11.2), and
this issue only triggers on specific hosts with specific guest
configurations. After no longer seeing it with kvm/next, I bisected the
fix to this commit and instrumented it to ensure the case was actually hit.

Jan
Gleb Natapov Feb. 11, 2013, 5:40 p.m. UTC | #4
On Mon, Feb 11, 2013 at 06:31:59PM +0100, Jan Kiszka wrote:
> On 2013-02-11 18:25, Gleb Natapov wrote:
> > On Mon, Feb 11, 2013 at 05:58:24PM +0100, Jan Kiszka wrote:
> >> On 2012-12-20 15:57, Gleb Natapov wrote:
> >>> According to Intel SDM Vol3 Section 5.5 "Privilege Levels" and 5.6
> >>> "Privilege Level Checking When Accessing Data Segments" RPL checking is
> >>> done during loading of a segment selector, not during data access. We
> >>> already do checking during segment selector loading, so drop the check
> >>> during data access. Checking RPL during data access triggers #GP if
> >>> after transition from real mode to protected mode RPL bits in a segment
> >>> selector are set.
> >>>
> >>> Signed-off-by: Gleb Natapov <gleb@redhat.com>
> >>> ---
> >>>  arch/x86/kvm/emulate.c |    7 +------
> >>>  1 file changed, 1 insertion(+), 6 deletions(-)
> >>>
> >>> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
> >>> index c7547b3..a3d31e3 100644
> >>> --- a/arch/x86/kvm/emulate.c
> >>> +++ b/arch/x86/kvm/emulate.c
> >>> @@ -665,7 +665,7 @@ static int __linearize(struct x86_emulate_ctxt *ctxt,
> >>>  	ulong la;
> >>>  	u32 lim;
> >>>  	u16 sel;
> >>> -	unsigned cpl, rpl;
> >>> +	unsigned cpl;
> >>>  
> >>>  	la = seg_base(ctxt, addr.seg) + addr.ea;
> >>>  	switch (ctxt->mode) {
> >>> @@ -699,11 +699,6 @@ static int __linearize(struct x86_emulate_ctxt *ctxt,
> >>>  				goto bad;
> >>>  		}
> >>>  		cpl = ctxt->ops->cpl(ctxt);
> >>> -		if (ctxt->mode == X86EMUL_MODE_REAL)
> >>> -			rpl = 0;
> >>> -		else
> >>> -			rpl = sel & 3;
> >>> -		cpl = max(cpl, rpl);
> >>>  		if (!(desc.type & 8)) {
> >>>  			/* data segment */
> >>>  			if (cpl > desc.dpl)
> >>>
> >>
> >> I suppose this one is queued for 3.8 and stable already, right? We
> >> happen to hit the case reliably while booting an older SUSE guest on an
> >> AMD host.
> >>
> > The patch was in the middle of the pile of vmx real mode fixes. I had
> > no reports that it can be triggered on its own, so it was not queued
> > neither to 3.8 nor to stable. Is it a regression?  If yes what version
> > the bug appears in?
> 
> It is a regression of 618ff15 ("implement segment permission checks"),
Naturally :)

> thus 3.0. We are running on such a 3.0.x host kernel (SLES11.2), and
> this issue only triggers on specific hosts with specific guest
> configurations. After no longer seeing it with kvm/next, I bisected the
> fix to this commit and instrumented it to ensure the case was actually hit.
> 
I see. Too later to try and push it to 3.8 now, will queue for stable. Not
sure if 3.0 is still maintained by stable folks though.

--
			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
Gleb Natapov Feb. 11, 2013, 5:50 p.m. UTC | #5
On Mon, Feb 11, 2013 at 07:40:38PM +0200, Gleb Natapov wrote:
> On Mon, Feb 11, 2013 at 06:31:59PM +0100, Jan Kiszka wrote:
> > On 2013-02-11 18:25, Gleb Natapov wrote:
> > > On Mon, Feb 11, 2013 at 05:58:24PM +0100, Jan Kiszka wrote:
> > >> On 2012-12-20 15:57, Gleb Natapov wrote:
> > >>> According to Intel SDM Vol3 Section 5.5 "Privilege Levels" and 5.6
> > >>> "Privilege Level Checking When Accessing Data Segments" RPL checking is
> > >>> done during loading of a segment selector, not during data access. We
> > >>> already do checking during segment selector loading, so drop the check
> > >>> during data access. Checking RPL during data access triggers #GP if
> > >>> after transition from real mode to protected mode RPL bits in a segment
> > >>> selector are set.
> > >>>
> > >>> Signed-off-by: Gleb Natapov <gleb@redhat.com>
> > >>> ---
> > >>>  arch/x86/kvm/emulate.c |    7 +------
> > >>>  1 file changed, 1 insertion(+), 6 deletions(-)
> > >>>
> > >>> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
> > >>> index c7547b3..a3d31e3 100644
> > >>> --- a/arch/x86/kvm/emulate.c
> > >>> +++ b/arch/x86/kvm/emulate.c
> > >>> @@ -665,7 +665,7 @@ static int __linearize(struct x86_emulate_ctxt *ctxt,
> > >>>  	ulong la;
> > >>>  	u32 lim;
> > >>>  	u16 sel;
> > >>> -	unsigned cpl, rpl;
> > >>> +	unsigned cpl;
> > >>>  
> > >>>  	la = seg_base(ctxt, addr.seg) + addr.ea;
> > >>>  	switch (ctxt->mode) {
> > >>> @@ -699,11 +699,6 @@ static int __linearize(struct x86_emulate_ctxt *ctxt,
> > >>>  				goto bad;
> > >>>  		}
> > >>>  		cpl = ctxt->ops->cpl(ctxt);
> > >>> -		if (ctxt->mode == X86EMUL_MODE_REAL)
> > >>> -			rpl = 0;
> > >>> -		else
> > >>> -			rpl = sel & 3;
> > >>> -		cpl = max(cpl, rpl);
> > >>>  		if (!(desc.type & 8)) {
> > >>>  			/* data segment */
> > >>>  			if (cpl > desc.dpl)
> > >>>
> > >>
> > >> I suppose this one is queued for 3.8 and stable already, right? We
> > >> happen to hit the case reliably while booting an older SUSE guest on an
> > >> AMD host.
> > >>
> > > The patch was in the middle of the pile of vmx real mode fixes. I had
> > > no reports that it can be triggered on its own, so it was not queued
> > > neither to 3.8 nor to stable. Is it a regression?  If yes what version
> > > the bug appears in?
> > 
> > It is a regression of 618ff15 ("implement segment permission checks"),
> Naturally :)
> 
> > thus 3.0. We are running on such a 3.0.x host kernel (SLES11.2), and
> > this issue only triggers on specific hosts with specific guest
> > configurations. After no longer seeing it with kvm/next, I bisected the
> > fix to this commit and instrumented it to ensure the case was actually hit.
> > 
> I see. Too later to try and push it to 3.8 now, will queue for stable. Not
> sure if 3.0 is still maintained by stable folks though.
> 
And just after I wrote that 3.0.63 was announced.

--
			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
Jan Kiszka Feb. 11, 2013, 6:05 p.m. UTC | #6
On 2013-02-11 18:50, Gleb Natapov wrote:
> On Mon, Feb 11, 2013 at 07:40:38PM +0200, Gleb Natapov wrote:
>> On Mon, Feb 11, 2013 at 06:31:59PM +0100, Jan Kiszka wrote:
>>> On 2013-02-11 18:25, Gleb Natapov wrote:
>>>> On Mon, Feb 11, 2013 at 05:58:24PM +0100, Jan Kiszka wrote:
>>>>> On 2012-12-20 15:57, Gleb Natapov wrote:
>>>>>> According to Intel SDM Vol3 Section 5.5 "Privilege Levels" and 5.6
>>>>>> "Privilege Level Checking When Accessing Data Segments" RPL checking is
>>>>>> done during loading of a segment selector, not during data access. We
>>>>>> already do checking during segment selector loading, so drop the check
>>>>>> during data access. Checking RPL during data access triggers #GP if
>>>>>> after transition from real mode to protected mode RPL bits in a segment
>>>>>> selector are set.
>>>>>>
>>>>>> Signed-off-by: Gleb Natapov <gleb@redhat.com>
>>>>>> ---
>>>>>>  arch/x86/kvm/emulate.c |    7 +------
>>>>>>  1 file changed, 1 insertion(+), 6 deletions(-)
>>>>>>
>>>>>> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
>>>>>> index c7547b3..a3d31e3 100644
>>>>>> --- a/arch/x86/kvm/emulate.c
>>>>>> +++ b/arch/x86/kvm/emulate.c
>>>>>> @@ -665,7 +665,7 @@ static int __linearize(struct x86_emulate_ctxt *ctxt,
>>>>>>  	ulong la;
>>>>>>  	u32 lim;
>>>>>>  	u16 sel;
>>>>>> -	unsigned cpl, rpl;
>>>>>> +	unsigned cpl;
>>>>>>  
>>>>>>  	la = seg_base(ctxt, addr.seg) + addr.ea;
>>>>>>  	switch (ctxt->mode) {
>>>>>> @@ -699,11 +699,6 @@ static int __linearize(struct x86_emulate_ctxt *ctxt,
>>>>>>  				goto bad;
>>>>>>  		}
>>>>>>  		cpl = ctxt->ops->cpl(ctxt);
>>>>>> -		if (ctxt->mode == X86EMUL_MODE_REAL)
>>>>>> -			rpl = 0;
>>>>>> -		else
>>>>>> -			rpl = sel & 3;
>>>>>> -		cpl = max(cpl, rpl);
>>>>>>  		if (!(desc.type & 8)) {
>>>>>>  			/* data segment */
>>>>>>  			if (cpl > desc.dpl)
>>>>>>
>>>>>
>>>>> I suppose this one is queued for 3.8 and stable already, right? We
>>>>> happen to hit the case reliably while booting an older SUSE guest on an
>>>>> AMD host.
>>>>>
>>>> The patch was in the middle of the pile of vmx real mode fixes. I had
>>>> no reports that it can be triggered on its own, so it was not queued
>>>> neither to 3.8 nor to stable. Is it a regression?  If yes what version
>>>> the bug appears in?
>>>
>>> It is a regression of 618ff15 ("implement segment permission checks"),
>> Naturally :)
>>
>>> thus 3.0. We are running on such a 3.0.x host kernel (SLES11.2), and
>>> this issue only triggers on specific hosts with specific guest
>>> configurations. After no longer seeing it with kvm/next, I bisected the
>>> fix to this commit and instrumented it to ensure the case was actually hit.
>>>
>> I see. Too later to try and push it to 3.8 now, will queue for stable. Not
>> sure if 3.0 is still maintained by stable folks though.
>>
> And just after I wrote that 3.0.63 was announced.

Well, if you consider pushing it that far, an adapted version will be
needed. For us, it is not that important as we already have to patch kvm
down there due to missing f1c1da2bde (SVM: Keep intercepting task
switching with NPT enabled).

Jan
Gleb Natapov Feb. 11, 2013, 6:40 p.m. UTC | #7
On Mon, Feb 11, 2013 at 07:05:50PM +0100, Jan Kiszka wrote:
> >>> thus 3.0. We are running on such a 3.0.x host kernel (SLES11.2), and
> >>> this issue only triggers on specific hosts with specific guest
> >>> configurations. After no longer seeing it with kvm/next, I bisected the
> >>> fix to this commit and instrumented it to ensure the case was actually hit.
> >>>
> >> I see. Too later to try and push it to 3.8 now, will queue for stable. Not
> >> sure if 3.0 is still maintained by stable folks though.
> >>
> > And just after I wrote that 3.0.63 was announced.
> 
> Well, if you consider pushing it that far, an adapted version will be
> needed. For us, it is not that important as we already have to patch kvm
> down there due to missing f1c1da2bde (SVM: Keep intercepting task
> switching with NPT enabled).
> 
OK, no reason to push it that far then.

--
			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
diff mbox

Patch

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index c7547b3..a3d31e3 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -665,7 +665,7 @@  static int __linearize(struct x86_emulate_ctxt *ctxt,
 	ulong la;
 	u32 lim;
 	u16 sel;
-	unsigned cpl, rpl;
+	unsigned cpl;
 
 	la = seg_base(ctxt, addr.seg) + addr.ea;
 	switch (ctxt->mode) {
@@ -699,11 +699,6 @@  static int __linearize(struct x86_emulate_ctxt *ctxt,
 				goto bad;
 		}
 		cpl = ctxt->ops->cpl(ctxt);
-		if (ctxt->mode == X86EMUL_MODE_REAL)
-			rpl = 0;
-		else
-			rpl = sel & 3;
-		cpl = max(cpl, rpl);
 		if (!(desc.type & 8)) {
 			/* data segment */
 			if (cpl > desc.dpl)