x86/vpt: guarantee the return value of pt_update_irq() set in vIRR or PIR
authorChao Gao <chao.gao@intel.com>
Tue, 24 Oct 2017 14:02:40 +0000 (16:02 +0200)
committerJan Beulich <jbeulich@suse.com>
Tue, 24 Oct 2017 14:02:40 +0000 (16:02 +0200)
commitb8acf328ac86fbb45831917a61e94be2de34294d
tree8ab39339d84141668540495d492752fa0bcf72d6
parente008f7619dcd6d549727c9635b3f9f3c7ee483ed
x86/vpt: guarantee the return value of pt_update_irq() set in vIRR or PIR

pt_update_irq() is expected to return the vector number of periodic
timer interrupt, which should be set in vIRR of vlapic or in PIR.
Otherwise it would trigger the assertion in vmx_intr_assist(), please
seeing https://lists.xenproject.org/archives/html/xen-devel/2017-10/msg00915.html.

But it fails to achieve that in the following two case:
1. hvm_isa_irq_assert() may not set the corresponding bit in vIRR for
mask field of IOAPIC RTE is set. Please refer to the call tree
vmx_intr_assist() -> pt_update_irq() -> hvm_isa_irq_assert() ->
assert_irq() -> assert_gsi() -> vioapic_irq_positive_edge(). The patch
checks whether the vector is set or not in vIRR of vlapic or PIR before
returning.

2. someone changes the vector field of IOAPIC RTE between asserting
the irq and getting the vector of the irq, leading to setting the
old vector number but returning a different vector number. This patch
allows hvm_isa_irq_assert() to accept a callback which can get the
interrupt vector with irq_lock held. Thus, no one can change the vector
between the two operations.

BTW, the first argument of pi_test_and_set_pir() should be uint8_t
and I take this chance to fix it.

Signed-off-by: Chao Gao <chao.gao@intel.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Release-acked-by: Julien Grall <julien.grall@linaro.org>
xen/arch/x86/hvm/dm.c
xen/arch/x86/hvm/irq.c
xen/arch/x86/hvm/pmtimer.c
xen/arch/x86/hvm/rtc.c
xen/arch/x86/hvm/vlapic.c
xen/arch/x86/hvm/vmx/vmx.c
xen/arch/x86/hvm/vpt.c
xen/include/asm-x86/hvm/hvm.h
xen/include/asm-x86/hvm/irq.h
xen/include/asm-x86/hvm/vlapic.h
xen/include/asm-x86/hvm/vmx/vmx.h