From: Sean Christopherson <seanjc@google.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: linux-kernel@vger.kernel.org, kvm@vger.kernel.org,
mlevitsk@redhat.com, vkuznets@redhat.com
Subject: Re: [PATCH v2 2/9] KVM: x86: remove return value of kvm_vcpu_block
Date: Wed, 17 Aug 2022 16:41:01 +0000 [thread overview]
Message-ID: <Yv0aHXcmuivyJDXw@google.com> (raw)
In-Reply-To: <78616cf8-2693-72cc-c2cc-5a849116ffc7@redhat.com>
On Wed, Aug 17, 2022, Paolo Bonzini wrote:
> On 8/17/22 01:34, Sean Christopherson wrote:
> > Isn't freeing up the return from kvm_vcpu_check_block() unnecessary? Can't we
> > just do:
> >
> > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> > index 9f11b505cbee..ccb9f8bdeb18 100644
> > --- a/arch/x86/kvm/x86.c
> > +++ b/arch/x86/kvm/x86.c
> > @@ -10633,7 +10633,7 @@ static inline int vcpu_block(struct kvm_vcpu *vcpu)
> > if (hv_timer)
> > kvm_lapic_switch_to_hv_timer(vcpu);
> >
> > - if (!kvm_check_request(KVM_REQ_UNHALT, vcpu))
> > + if (!kvm_arch_vcpu_runnable(vcpu))
> > return 1;
> > }
> >
> >
> > which IMO is more intuitive and doesn't require reworking halt-polling (again).
>
> This was my first idea indeed. However I didn't like calling
> kvm_arch_vcpu_runnable() again and "did it schedule()" seemed to be a less
> interesting result from kvm_vcpu_block() (and in fact kvm_vcpu_halt() does
> not bother passing it up the return chain).
The flip side of calling kvm_arch_vcpu_runnable() again is that KVM will immediately
wake the vCPU if it becomes runnable after kvm_vcpu_check_block(). The edge cases
where the vCPU becomes runnable late are unlikely to truly matter in practice, but
on the other hand manually re-checking kvm_arch_vcpu_runnable() means KVM gets both
cases "right" (waited=true iff vCPU actually waited, vCPU awakened ASAP), whereas
squishing the information into the return of kvm_vcpu_check_block() means KVM gets
both cases "wrong" (waited=true even if schedule() was never called, vCPU left in
a non-running state even though it's runnable).
My only hesitation with calling kvm_arch_vcpu_runnable() again is that it could be
problematic if KVM somehow managed to consume the event that caused kvm_vcpu_has_events()
to return true, but I don't see how that could happen without it being a KVM bug.
Ah, and if we do go with the explicit check, it should come with a comment to call
out that KVM needs to return up the stack, e.g.
/*
* If KVM stopped blocking the vCPU but the vCPU is still not
* runnable, then there is a pending host event of some kind,
* e.g. a pending signal. Return up the stack to service the
* pending event without changing the vCPU's activity state.
*/
if (!kvm_arch_vcpu_runnable(vcpu))
return 1;
so that we don't end combining the checks into:
while (!kvm_arch_vcpu_runnable(vcpu)) {
/*
* Switch to the software timer before halt-polling/blocking as
* the guest's timer may be a break event for the vCPU, and the
* hypervisor timer runs only when the CPU is in guest mode.
* Switch before halt-polling so that KVM recognizes an expired
* timer before blocking.
*/
hv_timer = kvm_lapic_hv_timer_in_use(vcpu);
if (hv_timer)
kvm_lapic_switch_to_sw_timer(vcpu);
kvm_vcpu_srcu_read_unlock(vcpu);
if (vcpu->arch.mp_state == KVM_MP_STATE_HALTED)
kvm_vcpu_halt(vcpu);
else
kvm_vcpu_block(vcpu);
kvm_vcpu_srcu_read_lock(vcpu);
if (hv_timer)
kvm_lapic_switch_to_hv_timer(vcpu);
}
which looks sane, but would mean KVM never bounces out to handle whatever event
needs handling.
Side topic, usage of kvm_apic_accept_events() appears to be broken (though nothing
can trigger the bug). If kvm_apic_accept_events() were to return an -errno, then
kvm_arch_vcpu_ioctl_run() would return '0' to userspace without updating
vcpu->run->exit_reason. I think an easy fix is to drop the return value entirely
and then WARN if kvm_check_nested_events() returns something other than -EBUSY.
if (is_guest_mode(vcpu)) {
r = kvm_check_nested_events(vcpu);
if (r < 0) {
WARN_ON_ONCE(r != -EBUSY);
return;
}
next prev parent reply other threads:[~2022-08-17 16:41 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-08-11 21:05 [PATCH v2 0/9] KVM: x86: never write to memory from kvm_vcpu_check_block Paolo Bonzini
2022-08-11 21:05 ` [PATCH v2 1/9] KVM: x86: check validity of argument to KVM_SET_MP_STATE Paolo Bonzini
2022-08-15 13:31 ` Maxim Levitsky
2022-08-16 22:50 ` Sean Christopherson
2022-08-11 21:05 ` [PATCH v2 2/9] KVM: x86: remove return value of kvm_vcpu_block Paolo Bonzini
2022-08-16 23:34 ` Sean Christopherson
2022-08-17 14:10 ` Maxim Levitsky
2022-08-17 15:31 ` Paolo Bonzini
2022-08-17 16:41 ` Sean Christopherson [this message]
2022-08-17 16:49 ` Paolo Bonzini
2022-09-20 0:42 ` Sean Christopherson
2022-08-11 21:05 ` [PATCH v2 3/9] KVM: x86: make kvm_vcpu_{block,halt} return whether vCPU is runnable Paolo Bonzini
2022-08-11 21:06 ` [PATCH v2 4/9] KVM: mips, x86: do not rely on KVM_REQ_UNHALT Paolo Bonzini
2022-08-11 21:06 ` [PATCH v2 5/9] KVM: remove KVM_REQ_UNHALT Paolo Bonzini
2022-08-11 21:06 ` [PATCH v2 6/9] KVM: x86: make vendor code check for all nested events Paolo Bonzini
2022-08-16 23:47 ` Sean Christopherson
2022-08-17 14:10 ` Maxim Levitsky
2022-08-11 21:06 ` [PATCH v2 7/9] KVM: nVMX: Make an event request when pending an MTF nested VM-Exit Paolo Bonzini
2022-08-17 14:11 ` Maxim Levitsky
2022-08-11 21:06 ` [PATCH v2 8/9] KVM: x86: lapic does not have to process INIT if it is blocked Paolo Bonzini
2022-08-17 0:07 ` Sean Christopherson
2022-08-17 14:11 ` Maxim Levitsky
2022-08-17 15:33 ` Paolo Bonzini
2022-08-11 21:06 ` [PATCH v2 9/9] KVM: x86: never write to memory from kvm_vcpu_check_block Paolo Bonzini
2022-08-16 23:45 ` Sean Christopherson
2022-08-17 14:11 ` Maxim Levitsky
2022-09-20 0:32 ` Sean Christopherson
2022-09-20 0:55 ` Sean Christopherson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Yv0aHXcmuivyJDXw@google.com \
--to=seanjc@google.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mlevitsk@redhat.com \
--cc=pbonzini@redhat.com \
--cc=vkuznets@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.