* [bug report] x86/sev: Split up runtime #VC handler for correct state tracking
@ 2021-08-04 9:57 Dan Carpenter
2021-08-04 12:38 ` Joerg Roedel
0 siblings, 1 reply; 7+ messages in thread
From: Dan Carpenter @ 2021-08-04 9:57 UTC (permalink / raw)
To: jroedel; +Cc: kvm
Hello Joerg Roedel,
The patch be1a5408868a: "x86/sev: Split up runtime #VC handler for
correct state tracking" from Jun 18, 2021, leads to the following
static checker warning:
arch/x86/kernel/kvm.c:153 kvm_async_pf_task_wait_schedule()
warn: sleeping in atomic context
arch/x86/kernel/sev.c
1416 * Handle #DB before calling into !noinstr code to avoid recursive #DB.
1417 */
1418 if (vc_is_db(error_code)) {
1419 exc_debug(regs);
1420 return;
1421 }
1422
1423 irq_state = irqentry_nmi_enter(regs);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
preempt disabled inside irqentry_nmi_enter().
1424
1425 instrumentation_begin();
1426
1427 if (!vc_raw_handle_exception(regs, error_code)) {
^^^^^^^^^^^^^^^^^^^^^^^^
These sleeping in atomic static checker warnings come with a lot of
caveats because the call tree is very long and it's easy to have false
positives.
--> vc_raw_handle_exception()
--> vc_forward_exception()
--> exc_page_fault()
Page faults always sleep right?
1428 /* Show some debug info */
1429 show_regs(regs);
1430
1431 /* Ask hypervisor to sev_es_terminate */
1432 sev_es_terminate(GHCB_SEV_ES_REASON_GENERAL_REQUEST);
1433
1434 /* If that fails and we get here - just panic */
1435 panic("Returned from Terminate-Request to Hypervisor\n");
1436 }
1437
1438 instrumentation_end();
1439 irqentry_nmi_exit(regs, irq_state);
1440 }
regards,
dan carpenter
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [bug report] x86/sev: Split up runtime #VC handler for correct state tracking
2021-08-04 9:57 [bug report] x86/sev: Split up runtime #VC handler for correct state tracking Dan Carpenter
@ 2021-08-04 12:38 ` Joerg Roedel
2021-08-04 12:58 ` Dan Carpenter
0 siblings, 1 reply; 7+ messages in thread
From: Joerg Roedel @ 2021-08-04 12:38 UTC (permalink / raw)
To: Dan Carpenter; +Cc: kvm
Hi Dan,
On Wed, Aug 04, 2021 at 12:57:25PM +0300, Dan Carpenter wrote:
> These sleeping in atomic static checker warnings come with a lot of
> caveats because the call tree is very long and it's easy to have false
> positives.
>
> --> vc_raw_handle_exception()
> --> vc_forward_exception()
> --> exc_page_fault()
>
> Page faults always sleep right?
No, page faults do no always sleep, only when IO needs to be done to
fulfill the page fault request. In this case, the page-fault handler
will never sleep, because it is called with preemption disabled. The
page-fault handler can detect this and just do nothing. The #VC handler
will return for re-fault in this case.
Hope that helps,
Joerg
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [bug report] x86/sev: Split up runtime #VC handler for correct state tracking
2021-08-04 12:38 ` Joerg Roedel
@ 2021-08-04 12:58 ` Dan Carpenter
2021-08-04 13:35 ` Joerg Roedel
2021-08-04 14:23 ` Joerg Roedel
0 siblings, 2 replies; 7+ messages in thread
From: Dan Carpenter @ 2021-08-04 12:58 UTC (permalink / raw)
To: Joerg Roedel; +Cc: kvm
On Wed, Aug 04, 2021 at 02:38:35PM +0200, Joerg Roedel wrote:
> Hi Dan,
>
> On Wed, Aug 04, 2021 at 12:57:25PM +0300, Dan Carpenter wrote:
> > These sleeping in atomic static checker warnings come with a lot of
> > caveats because the call tree is very long and it's easy to have false
> > positives.
> >
> > --> vc_raw_handle_exception()
> > --> vc_forward_exception()
> > --> exc_page_fault()
> >
> > Page faults always sleep right?
>
> No, page faults do no always sleep, only when IO needs to be done to
> fulfill the page fault request. In this case, the page-fault handler
> will never sleep, because it is called with preemption disabled. The
> page-fault handler can detect this and just do nothing. The #VC handler
> will return for re-fault in this case.
Hm... Ok. Let give you the rest of the call tree then because I'm not
seeing where it checks preempt count.
exc_page_fault() <-- called with preempt disabled
--> kvm_handle_async_pf()
--> __kvm_handle_async_pf()
--> kvm_async_pf_task_wait_schedule() calls schedule().
regards,
dan carpenter
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [bug report] x86/sev: Split up runtime #VC handler for correct state tracking
2021-08-04 12:58 ` Dan Carpenter
@ 2021-08-04 13:35 ` Joerg Roedel
2021-08-04 13:42 ` Dan Carpenter
2021-08-04 14:23 ` Joerg Roedel
1 sibling, 1 reply; 7+ messages in thread
From: Joerg Roedel @ 2021-08-04 13:35 UTC (permalink / raw)
To: Dan Carpenter; +Cc: kvm
On Wed, Aug 04, 2021 at 03:58:34PM +0300, Dan Carpenter wrote:
> Hm... Ok. Let give you the rest of the call tree then because I'm not
> seeing where it checks preempt count.
The check is in faulthandler_disabled(), it checks for in_atomic().
Regards,
Joerg
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [bug report] x86/sev: Split up runtime #VC handler for correct state tracking
2021-08-04 13:35 ` Joerg Roedel
@ 2021-08-04 13:42 ` Dan Carpenter
0 siblings, 0 replies; 7+ messages in thread
From: Dan Carpenter @ 2021-08-04 13:42 UTC (permalink / raw)
To: Joerg Roedel; +Cc: kvm
On Wed, Aug 04, 2021 at 03:35:01PM +0200, Joerg Roedel wrote:
> On Wed, Aug 04, 2021 at 03:58:34PM +0300, Dan Carpenter wrote:
> > Hm... Ok. Let give you the rest of the call tree then because I'm not
> > seeing where it checks preempt count.
>
> The check is in faulthandler_disabled(), it checks for in_atomic().
>
That check is later after the caller tree that I pasted as already
called schedule().
regards,
dan carpenter
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [bug report] x86/sev: Split up runtime #VC handler for correct state tracking
2021-08-04 12:58 ` Dan Carpenter
2021-08-04 13:35 ` Joerg Roedel
@ 2021-08-04 14:23 ` Joerg Roedel
2021-08-06 8:35 ` Dan Carpenter
1 sibling, 1 reply; 7+ messages in thread
From: Joerg Roedel @ 2021-08-04 14:23 UTC (permalink / raw)
To: Dan Carpenter; +Cc: kvm
On Wed, Aug 04, 2021 at 03:58:34PM +0300, Dan Carpenter wrote:
> exc_page_fault() <-- called with preempt disabled
> --> kvm_handle_async_pf()
> --> __kvm_handle_async_pf()
> --> kvm_async_pf_task_wait_schedule() calls schedule().
This call path can not be taken in the page-fault handler when called
from the #VC handler. To take this path the host needs to inject an
async page-fault, especially setting async pf flags, without injecting a
page-fault exception on its own ... and when the #VC handler is running.
KVM is not doing that.
Okay, the hypervisor can be malicious, but otherwise this can't happen.
To mitigate a malicious hypervisor threat here it might be a solution to
not call the page-fault handler directly from the #VC handler and let it
re-fault after the #VC handler returned.
Regards,
Joerg
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [bug report] x86/sev: Split up runtime #VC handler for correct state tracking
2021-08-04 14:23 ` Joerg Roedel
@ 2021-08-06 8:35 ` Dan Carpenter
0 siblings, 0 replies; 7+ messages in thread
From: Dan Carpenter @ 2021-08-06 8:35 UTC (permalink / raw)
To: Joerg Roedel; +Cc: kvm
On Wed, Aug 04, 2021 at 04:23:26PM +0200, Joerg Roedel wrote:
> On Wed, Aug 04, 2021 at 03:58:34PM +0300, Dan Carpenter wrote:
> > exc_page_fault() <-- called with preempt disabled
> > --> kvm_handle_async_pf()
> > --> __kvm_handle_async_pf()
> > --> kvm_async_pf_task_wait_schedule() calls schedule().
>
> This call path can not be taken in the page-fault handler when called
> from the #VC handler. To take this path the host needs to inject an
> async page-fault, especially setting async pf flags, without injecting a
> page-fault exception on its own ... and when the #VC handler is running.
> KVM is not doing that.
>
> Okay, the hypervisor can be malicious, but otherwise this can't happen.
> To mitigate a malicious hypervisor threat here it might be a solution to
> not call the page-fault handler directly from the #VC handler and let it
> re-fault after the #VC handler returned.
>
Thanks for taking a look at this.
Also it turns out that my check wasn't taking in_atomic() into
consideration either so I've added that.
regards,
dan carpenter
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2021-08-06 8:38 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-04 9:57 [bug report] x86/sev: Split up runtime #VC handler for correct state tracking Dan Carpenter
2021-08-04 12:38 ` Joerg Roedel
2021-08-04 12:58 ` Dan Carpenter
2021-08-04 13:35 ` Joerg Roedel
2021-08-04 13:42 ` Dan Carpenter
2021-08-04 14:23 ` Joerg Roedel
2021-08-06 8:35 ` Dan Carpenter
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).