lkml.org 
[lkml]   [2020]   [Apr]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    From
    SubjectRe: [PATCH v2] x86/kvm: Disable KVM_ASYNC_PF_SEND_ALWAYS
    Date
    Andy Lutomirski <luto@amacapital.net> writes:
    >> On Apr 7, 2020, at 10:21 AM, Vivek Goyal <vgoyal@redhat.com> wrote:
    >> Whether interrupts are enabled or not check only happens before we decide
    >> if async pf protocol should be followed or not. Once we decide to
    >> send PAGE_NOT_PRESENT, later notification PAGE_READY does not check
    >> if interrupts are enabled or not. And it kind of makes sense otherwise
    >> guest process will wait infinitely to receive PAGE_READY.
    >>
    >> I modified the code a bit to disable interrupt and wait 10 seconds (after
    >> getting PAGE_NOT_PRESENT message). And I noticed that error async pf
    >> got delivered after 10 seconds after enabling interrupts. So error
    >> async pf was not lost because interrupts were disabled.

    Async PF is not the same as a real #PF. It just hijacked the #PF vector
    because someone thought this is a brilliant idea.

    >> Havind said that, I thought disabling interrupts does not mask exceptions.
    >> So page fault exception should have been delivered even with interrupts
    >> disabled. Is that correct? May be there was no vm exit/entry during
    >> those 10 seconds and that's why.

    No. Async PF is not a real exception. It has interrupt semantics and it
    can only be injected when the guest has interrupts enabled. It's bad
    design.

    > My point is that the entire async pf is nonsense. There are two types of events right now:
    >
    > “Page not ready”: normally this isn’t even visible to the guest — the
    > guest just waits. With async pf, the idea is to try to tell the guest
    > that a particular instruction would block and the guest should do
    > something else instead. Sending a normal exception is a poor design,
    > though: the guest may not expect this instruction to cause an
    > exception. I think KVM should try to deliver an *interrupt* and, if it
    > can’t, then just block the guest.

    That's pretty much what it does, just that it runs this through #PF and
    has the checks for interrupts disabled - i.e can't right now' around
    that. If it can't then KVM schedules the guest out until the situation
    has been resolved.

    > “Page ready”: this is a regular asynchronous notification just like,
    > say, a virtio completion. It should be an ordinary interrupt. Some in
    > memory data structure should indicate which pages are ready.
    >
    > “Page is malfunctioning” is tricky because you *must* deliver the
    > event. x86’s #MC is not exactly a masterpiece, but it does kind of
    > work.

    Nooooo. This does not need #MC at all. Don't even think about it.

    The point is that the access to such a page is either happening in user
    space or in kernel space with a proper exception table fixup.

    That means a real #PF is perfectly fine. That can be injected any time
    and does not have the interrupt semantics of async PF.

    So now lets assume we distangled async PF from #PF and made it a regular
    interrupt, then the following situation still needs to be dealt with:

    guest -> access faults

    host -> injects async fault

    guest -> handles and blocks the task

    host figures out that the page does not exist anymore and now needs to
    fixup the situation.

    host -> injects async wakeup

    guest -> returns from aysnc PF interrupt and retries the instruction
    which faults again.

    host -> knows by now that this is a real fault and injects a proper #PF

    guest -> #PF runs and either sends signal to user space or runs
    the exception table fixup for a kernel fault.

    Thanks,

    tglx




    \
     
     \ /
      Last update: 2020-04-07 22:21    [W:9.255 / U:0.032 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site