lkml.org 
[lkml]   [2022]   [Aug]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.19 0045/1157] KVM: x86/xen: Stop Xen timer before changing IRQ
    Date
    From: Coleman Dietsch <dietschc@csp.edu>

    commit c036899136355758dcd88878145036ab4d9c1f26 upstream.

    Stop Xen timer (if it's running) prior to changing the IRQ vector and
    potentially (re)starting the timer. Changing the IRQ vector while the
    timer is still running can result in KVM injecting a garbage event, e.g.
    vm_xen_inject_timer_irqs() could see a non-zero xen.timer_pending from
    a previous timer but inject the new xen.timer_virq.

    Fixes: 536395260582 ("KVM: x86/xen: handle PV timers oneshot mode")
    Cc: stable@vger.kernel.org
    Link: https://syzkaller.appspot.com/bug?id=8234a9dfd3aafbf092cc5a7cd9842e3ebc45fc42
    Reported-by: syzbot+e54f930ed78eb0f85281@syzkaller.appspotmail.com
    Signed-off-by: Coleman Dietsch <dietschc@csp.edu>
    Reviewed-by: Sean Christopherson <seanjc@google.com>
    Acked-by: David Woodhouse <dwmw@amazon.co.uk>
    Message-Id: <20220808190607.323899-3-dietschc@csp.edu>
    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    arch/x86/kvm/xen.c | 33 ++++++++++++++++-----------------
    1 file changed, 16 insertions(+), 17 deletions(-)

    --- a/arch/x86/kvm/xen.c
    +++ b/arch/x86/kvm/xen.c
    @@ -707,25 +707,24 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcp
    break;

    case KVM_XEN_VCPU_ATTR_TYPE_TIMER:
    - if (data->u.timer.port) {
    - if (data->u.timer.priority != KVM_IRQ_ROUTING_XEN_EVTCHN_PRIO_2LEVEL) {
    - r = -EINVAL;
    - break;
    - }
    - vcpu->arch.xen.timer_virq = data->u.timer.port;
    + if (data->u.timer.port &&
    + data->u.timer.priority != KVM_IRQ_ROUTING_XEN_EVTCHN_PRIO_2LEVEL) {
    + r = -EINVAL;
    + break;
    + }

    - if (!vcpu->arch.xen.timer.function)
    - kvm_xen_init_timer(vcpu);
    + if (!vcpu->arch.xen.timer.function)
    + kvm_xen_init_timer(vcpu);

    - /* Restart the timer if it's set */
    - if (data->u.timer.expires_ns)
    - kvm_xen_start_timer(vcpu, data->u.timer.expires_ns,
    - data->u.timer.expires_ns -
    - get_kvmclock_ns(vcpu->kvm));
    - } else if (kvm_xen_timer_enabled(vcpu)) {
    - kvm_xen_stop_timer(vcpu);
    - vcpu->arch.xen.timer_virq = 0;
    - }
    + /* Stop the timer (if it's running) before changing the vector */
    + kvm_xen_stop_timer(vcpu);
    + vcpu->arch.xen.timer_virq = data->u.timer.port;
    +
    + /* Start the timer if the new value has a valid vector+expiry. */
    + if (data->u.timer.port && data->u.timer.expires_ns)
    + kvm_xen_start_timer(vcpu, data->u.timer.expires_ns,
    + data->u.timer.expires_ns -
    + get_kvmclock_ns(vcpu->kvm));

    r = 0;
    break;

    \
     
     \ /
      Last update: 2022-08-15 23:57    [W:8.507 / U:0.140 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site