2020-02-24 18:57:52

by Paolo Bonzini

[permalink] [raw]
Subject: [FYI PATCH 0/3] CVE-2020-2732

vmx_check_intercept is not yet fully implemented by KVM on Intel processors,
causing e.g. the I/O or MSR interception bitmaps not to be checked.
In general we can just disallow instruction emulation on behalf of L1,
but this series also implements I/O port checks.

Paolo

Oliver Upton (2):
KVM: nVMX: Refactor IO bitmap checks into helper function
KVM: nVMX: Check IO instruction VM-exit conditions

Paolo Bonzini (1):
KVM: nVMX: Don't emulate instructions in guest mode

arch/x86/kvm/vmx/nested.c | 39 ++++++++++++++++++++-----------
arch/x86/kvm/vmx/nested.h | 2 ++
arch/x86/kvm/vmx/vmx.c | 59 +++++++++++++++++++++++++++++++++++++++++------
3 files changed, 79 insertions(+), 21 deletions(-)

--
1.8.3.1


2020-02-24 18:58:26

by Paolo Bonzini

[permalink] [raw]
Subject: [FYI PATCH 1/3] KVM: nVMX: Don't emulate instructions in guest mode

vmx_check_intercept is not yet fully implemented. To avoid emulating
instructions disallowed by the L1 hypervisor, refuse to emulate
instructions by default.

Cc: [email protected]
[Made commit, added commit msg - Oliver]
Signed-off-by: Oliver Upton <[email protected]>
Signed-off-by: Paolo Bonzini <[email protected]>
---
arch/x86/kvm/vmx/vmx.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index dcca514ffd42..5801a86f9c24 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -7164,7 +7164,7 @@ static int vmx_check_intercept(struct kvm_vcpu *vcpu,
}

/* TODO: check more intercepts... */
- return X86EMUL_CONTINUE;
+ return X86EMUL_UNHANDLEABLE;
}

#ifdef CONFIG_X86_64
--
1.8.3.1


2020-02-29 18:07:57

by Jan Kiszka

[permalink] [raw]
Subject: Re: [FYI PATCH 1/3] KVM: nVMX: Don't emulate instructions in guest mode

On 24.02.20 19:56, Paolo Bonzini wrote:
> vmx_check_intercept is not yet fully implemented. To avoid emulating
> instructions disallowed by the L1 hypervisor, refuse to emulate
> instructions by default.
>
> Cc: [email protected]
> [Made commit, added commit msg - Oliver]
> Signed-off-by: Oliver Upton <[email protected]>
> Signed-off-by: Paolo Bonzini <[email protected]>
> ---
> arch/x86/kvm/vmx/vmx.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> index dcca514ffd42..5801a86f9c24 100644
> --- a/arch/x86/kvm/vmx/vmx.c
> +++ b/arch/x86/kvm/vmx/vmx.c
> @@ -7164,7 +7164,7 @@ static int vmx_check_intercept(struct kvm_vcpu *vcpu,
> }
>
> /* TODO: check more intercepts... */
> - return X86EMUL_CONTINUE;
> + return X86EMUL_UNHANDLEABLE;
> }
>
> #ifdef CONFIG_X86_64
>

Is this expected to cause regressions on less common workloads?
Jailhouse as L1 now fails when Linux as L2 tries to boot a CPU: L2-Linux
gets a triple fault on load_current_idt() in start_secondary(). Only
bisected so far, didn't debug further.

Jan

2020-02-29 18:40:36

by Oliver Upton

[permalink] [raw]
Subject: Re: [FYI PATCH 1/3] KVM: nVMX: Don't emulate instructions in guest mode

Hi Jan,

On Sat, Feb 29, 2020 at 10:00 AM Jan Kiszka <[email protected]> wrote:
> Is this expected to cause regressions on less common workloads?
> Jailhouse as L1 now fails when Linux as L2 tries to boot a CPU: L2-Linux
> gets a triple fault on load_current_idt() in start_secondary(). Only
> bisected so far, didn't debug further.

I'm guessing that Jailhouse doesn't use 'descriptor table exiting', so
when KVM gets the corresponding exit from L2 the emulation burden is
on L0. We now refuse the emulation, which kicks a #UD back to L2. I
can get a patch out quickly to address this case (like the PIO exiting
one that came in this series) but the eventual solution is to map
emulator intercept checks into VM-exits + call into the
nested_vmx_exit_reflected() plumbing.

--
Thanks,
Oliver

2020-02-29 19:03:10

by Jim Mattson

[permalink] [raw]
Subject: Re: [FYI PATCH 1/3] KVM: nVMX: Don't emulate instructions in guest mode

On Sat, Feb 29, 2020 at 10:33 AM Oliver Upton <[email protected]> wrote:
>
> Hi Jan,
>
> On Sat, Feb 29, 2020 at 10:00 AM Jan Kiszka <[email protected]> wrote:
> > Is this expected to cause regressions on less common workloads?
> > Jailhouse as L1 now fails when Linux as L2 tries to boot a CPU: L2-Linux
> > gets a triple fault on load_current_idt() in start_secondary(). Only
> > bisected so far, didn't debug further.
>
> I'm guessing that Jailhouse doesn't use 'descriptor table exiting', so
> when KVM gets the corresponding exit from L2 the emulation burden is
> on L0. We now refuse the emulation, which kicks a #UD back to L2. I
> can get a patch out quickly to address this case (like the PIO exiting
> one that came in this series) but the eventual solution is to map
> emulator intercept checks into VM-exits + call into the
> nested_vmx_exit_reflected() plumbing.

If Jailhouse doesn't use descriptor table exiting, why is L0
intercepting descriptor table instructions? Is this just so that L0
can partially emulate UMIP on hardware that doesn't support it?

2020-02-29 19:34:36

by Jan Kiszka

[permalink] [raw]
Subject: Re: [FYI PATCH 1/3] KVM: nVMX: Don't emulate instructions in guest mode

On 29.02.20 20:00, Jim Mattson wrote:
> On Sat, Feb 29, 2020 at 10:33 AM Oliver Upton <[email protected]> wrote:
>>
>> Hi Jan,
>>
>> On Sat, Feb 29, 2020 at 10:00 AM Jan Kiszka <[email protected]> wrote:
>>> Is this expected to cause regressions on less common workloads?
>>> Jailhouse as L1 now fails when Linux as L2 tries to boot a CPU: L2-Linux
>>> gets a triple fault on load_current_idt() in start_secondary(). Only
>>> bisected so far, didn't debug further.
>>
>> I'm guessing that Jailhouse doesn't use 'descriptor table exiting', so
>> when KVM gets the corresponding exit from L2 the emulation burden is
>> on L0. We now refuse the emulation, which kicks a #UD back to L2. I
>> can get a patch out quickly to address this case (like the PIO exiting
>> one that came in this series) but the eventual solution is to map
>> emulator intercept checks into VM-exits + call into the
>> nested_vmx_exit_reflected() plumbing.
>
> If Jailhouse doesn't use descriptor table exiting, why is L0
> intercepting descriptor table instructions? Is this just so that L0
> can partially emulate UMIP on hardware that doesn't support it?
>

That seems to be the case: My host lacks umip, L1 has it. So, KVM is
intercepting descriptor table load instructions to emulate umip.
Jailhouse never activates that interception.

Jan

2020-02-29 20:18:29

by Jim Mattson

[permalink] [raw]
Subject: Re: [FYI PATCH 1/3] KVM: nVMX: Don't emulate instructions in guest mode

Since UMIP emulation is broken, I'm not sure why anyone would use it.
(Sorry, Paolo.)

On Sat, Feb 29, 2020 at 11:21 AM Jan Kiszka <[email protected]> wrote:
>
> On 29.02.20 20:00, Jim Mattson wrote:
> > On Sat, Feb 29, 2020 at 10:33 AM Oliver Upton <[email protected]> wrote:
> >>
> >> Hi Jan,
> >>
> >> On Sat, Feb 29, 2020 at 10:00 AM Jan Kiszka <[email protected]> wrote:
> >>> Is this expected to cause regressions on less common workloads?
> >>> Jailhouse as L1 now fails when Linux as L2 tries to boot a CPU: L2-Linux
> >>> gets a triple fault on load_current_idt() in start_secondary(). Only
> >>> bisected so far, didn't debug further.
> >>
> >> I'm guessing that Jailhouse doesn't use 'descriptor table exiting', so
> >> when KVM gets the corresponding exit from L2 the emulation burden is
> >> on L0. We now refuse the emulation, which kicks a #UD back to L2. I
> >> can get a patch out quickly to address this case (like the PIO exiting
> >> one that came in this series) but the eventual solution is to map
> >> emulator intercept checks into VM-exits + call into the
> >> nested_vmx_exit_reflected() plumbing.
> >
> > If Jailhouse doesn't use descriptor table exiting, why is L0
> > intercepting descriptor table instructions? Is this just so that L0
> > can partially emulate UMIP on hardware that doesn't support it?
> >
>
> That seems to be the case: My host lacks umip, L1 has it. So, KVM is
> intercepting descriptor table load instructions to emulate umip.
> Jailhouse never activates that interception.
>
> Jan

2020-02-29 20:50:58

by Jan Kiszka

[permalink] [raw]
Subject: Re: [FYI PATCH 1/3] KVM: nVMX: Don't emulate instructions in guest mode

On 29.02.20 21:17, Jim Mattson wrote:
> Since UMIP emulation is broken, I'm not sure why anyone would use it.
> (Sorry, Paolo.)

FWIW, adding "-umip" to the "-cpu host" in my qemu setup works around
the bug.

Jan

>
> On Sat, Feb 29, 2020 at 11:21 AM Jan Kiszka <[email protected]> wrote:
>>
>> On 29.02.20 20:00, Jim Mattson wrote:
>>> On Sat, Feb 29, 2020 at 10:33 AM Oliver Upton <[email protected]> wrote:
>>>>
>>>> Hi Jan,
>>>>
>>>> On Sat, Feb 29, 2020 at 10:00 AM Jan Kiszka <[email protected]> wrote:
>>>>> Is this expected to cause regressions on less common workloads?
>>>>> Jailhouse as L1 now fails when Linux as L2 tries to boot a CPU: L2-Linux
>>>>> gets a triple fault on load_current_idt() in start_secondary(). Only
>>>>> bisected so far, didn't debug further.
>>>>
>>>> I'm guessing that Jailhouse doesn't use 'descriptor table exiting', so
>>>> when KVM gets the corresponding exit from L2 the emulation burden is
>>>> on L0. We now refuse the emulation, which kicks a #UD back to L2. I
>>>> can get a patch out quickly to address this case (like the PIO exiting
>>>> one that came in this series) but the eventual solution is to map
>>>> emulator intercept checks into VM-exits + call into the
>>>> nested_vmx_exit_reflected() plumbing.
>>>
>>> If Jailhouse doesn't use descriptor table exiting, why is L0
>>> intercepting descriptor table instructions? Is this just so that L0
>>> can partially emulate UMIP on hardware that doesn't support it?
>>>
>>
>> That seems to be the case: My host lacks umip, L1 has it. So, KVM is
>> intercepting descriptor table load instructions to emulate umip.
>> Jailhouse never activates that interception.
>>
>> Jan