head 1.2; access; symbols pkgsrc-2021Q1:1.1.0.4 pkgsrc-2021Q1-base:1.1 pkgsrc-2020Q4:1.1.0.2; locks; strict; comment @# @; 1.2 date 2021.03.30.06.59.03; author bouyer; state dead; branches; next 1.1; commitid 0qeTE1RWBrm5HiNC; 1.1 date 2021.02.03.22.27.16; author bouyer; state Exp; branches 1.1.2.1; next ; commitid QOP6jD82GSUuCjGC; 1.1.2.1 date 2021.02.03.22.27.16; author bsiegert; state dead; branches; next 1.1.2.2; commitid 5HgW8JnukcjuoUHC; 1.1.2.2 date 2021.02.16.07.57.46; author bsiegert; state Exp; branches; next ; commitid 5HgW8JnukcjuoUHC; desc @@ 1.2 log @Update xentools413 and xentools413 to 4.13.3. Changes since 4.13.2: inlcude security fixes for all XSA known to date (up to XSA-369). Other minor bug fixes. @ text @$NetBSD: patch-XSA360,v 1.1 2021/02/03 22:27:16 bouyer Exp $ From: Roger Pau Monne Subject: x86/dpci: do not remove pirqs from domain tree on unbind A fix for a previous issue removed the pirqs from the domain tree when they are unbound in order to prevent shared pirqs from triggering a BUG_ON in __pirq_guest_unbind if they are unbound multiple times. That caused free_domain_pirqs to no longer unmap the pirqs because they are gone from the domain pirq tree, thus leaving stale unbound pirqs after domain destruction if the domain had mapped dpci pirqs after shutdown. Take a different approach to fix the original issue, instead of removing the pirq from d->pirq_tree clear the flags of the dpci pirq struct to signal that the pirq is now unbound. This prevents calling pirq_guest_unbind multiple times for the same pirq without having to remove it from the domain pirq tree. This is XSA-360. Fixes: 5b58dad089 ('x86/pass-through: avoid double IRQ unbind during domain cleanup') Signed-off-by: Roger Pau Monné Reviewed-by: Jan Beulich --- xen/arch/x86/irq.c.orig +++ xen/arch/x86/irq.c @@@@ -1331,7 +1331,7 @@@@ void (pirq_cleanup_check)(struct pirq *p } if ( radix_tree_delete(&d->pirq_tree, pirq->pirq) != pirq ) - BUG_ON(!d->is_dying); + BUG(); } /* Flush all ready EOIs from the top of this CPU's pending-EOI stack. */ --- xen/drivers/passthrough/pci.c.orig +++ xen/drivers/passthrough/pci.c @@@@ -862,6 +862,10 @@@@ static int pci_clean_dpci_irq(struct dom { struct dev_intx_gsi_link *digl, *tmp; + if ( !pirq_dpci->flags ) + /* Already processed. */ + return 0; + pirq_guest_unbind(d, dpci_pirq(pirq_dpci)); if ( pt_irq_need_timer(pirq_dpci->flags) ) @@@@ -872,15 +876,10 @@@@ static int pci_clean_dpci_irq(struct dom list_del(&digl->list); xfree(digl); } + /* Note the pirq is now unbound. */ + pirq_dpci->flags = 0; - radix_tree_delete(&d->pirq_tree, dpci_pirq(pirq_dpci)->pirq); - - if ( !pt_pirq_softirq_active(pirq_dpci) ) - return 0; - - domain_get_irq_dpci(d)->pending_pirq_dpci = pirq_dpci; - - return -ERESTART; + return pt_pirq_softirq_active(pirq_dpci) ? -ERESTART : 0; } static int pci_clean_dpci_irqs(struct domain *d) @@@@ -897,18 +896,8 @@@@ static int pci_clean_dpci_irqs(struct do hvm_irq_dpci = domain_get_irq_dpci(d); if ( hvm_irq_dpci != NULL ) { - int ret = 0; - - if ( hvm_irq_dpci->pending_pirq_dpci ) - { - if ( pt_pirq_softirq_active(hvm_irq_dpci->pending_pirq_dpci) ) - ret = -ERESTART; - else - hvm_irq_dpci->pending_pirq_dpci = NULL; - } + int ret = pt_pirq_iterate(d, pci_clean_dpci_irq, NULL); - if ( !ret ) - ret = pt_pirq_iterate(d, pci_clean_dpci_irq, NULL); if ( ret ) { spin_unlock(&d->event_lock); --- xen/include/asm-x86/hvm/irq.h.orig +++ xen/include/asm-x86/hvm/irq.h @@@@ -160,8 +160,6 @@@@ struct hvm_irq_dpci { DECLARE_BITMAP(isairq_map, NR_ISAIRQS); /* Record of mapped Links */ uint8_t link_cnt[NR_LINK]; - /* Clean up: Entry with a softirq invocation pending / in progress. */ - struct hvm_pirq_dpci *pending_pirq_dpci; }; /* Machine IRQ to guest device/intx mapping. */ @ 1.1 log @Add upstream patches for Xen security advisory 355 and 360. Bump PKGREVSION @ text @d1 1 a1 1 $NetBSD: $ @ 1.1.2.1 log @file patch-XSA360 was added on branch pkgsrc-2020Q4 on 2021-02-16 07:57:46 +0000 @ text @d1 99 @ 1.1.2.2 log @Pullup ticket #6422 - requested by bouyer sysutils/xenkernel413: security fix Revisions pulled up: - sysutils/xenkernel413/Makefile 1.12 - sysutils/xenkernel413/distinfo 1.9 - sysutils/xenkernel413/patches/patch-XSA355 1.1 - sysutils/xenkernel413/patches/patch-XSA360 1.1 --- Module Name: pkgsrc Committed By: bouyer Date: Wed Feb 3 22:27:16 UTC 2021 Modified Files: pkgsrc/sysutils/xenkernel413: Makefile distinfo Added Files: pkgsrc/sysutils/xenkernel413/patches: patch-XSA355 patch-XSA360 Log Message: Add upstream patches for Xen security advisory 355 and 360. Bump PKGREVSION @ text @a0 99 $NetBSD: patch-XSA360,v 1.1 2021/02/03 22:27:16 bouyer Exp $ From: Roger Pau Monne Subject: x86/dpci: do not remove pirqs from domain tree on unbind A fix for a previous issue removed the pirqs from the domain tree when they are unbound in order to prevent shared pirqs from triggering a BUG_ON in __pirq_guest_unbind if they are unbound multiple times. That caused free_domain_pirqs to no longer unmap the pirqs because they are gone from the domain pirq tree, thus leaving stale unbound pirqs after domain destruction if the domain had mapped dpci pirqs after shutdown. Take a different approach to fix the original issue, instead of removing the pirq from d->pirq_tree clear the flags of the dpci pirq struct to signal that the pirq is now unbound. This prevents calling pirq_guest_unbind multiple times for the same pirq without having to remove it from the domain pirq tree. This is XSA-360. Fixes: 5b58dad089 ('x86/pass-through: avoid double IRQ unbind during domain cleanup') Signed-off-by: Roger Pau Monné Reviewed-by: Jan Beulich --- xen/arch/x86/irq.c.orig +++ xen/arch/x86/irq.c @@@@ -1331,7 +1331,7 @@@@ void (pirq_cleanup_check)(struct pirq *p } if ( radix_tree_delete(&d->pirq_tree, pirq->pirq) != pirq ) - BUG_ON(!d->is_dying); + BUG(); } /* Flush all ready EOIs from the top of this CPU's pending-EOI stack. */ --- xen/drivers/passthrough/pci.c.orig +++ xen/drivers/passthrough/pci.c @@@@ -862,6 +862,10 @@@@ static int pci_clean_dpci_irq(struct dom { struct dev_intx_gsi_link *digl, *tmp; + if ( !pirq_dpci->flags ) + /* Already processed. */ + return 0; + pirq_guest_unbind(d, dpci_pirq(pirq_dpci)); if ( pt_irq_need_timer(pirq_dpci->flags) ) @@@@ -872,15 +876,10 @@@@ static int pci_clean_dpci_irq(struct dom list_del(&digl->list); xfree(digl); } + /* Note the pirq is now unbound. */ + pirq_dpci->flags = 0; - radix_tree_delete(&d->pirq_tree, dpci_pirq(pirq_dpci)->pirq); - - if ( !pt_pirq_softirq_active(pirq_dpci) ) - return 0; - - domain_get_irq_dpci(d)->pending_pirq_dpci = pirq_dpci; - - return -ERESTART; + return pt_pirq_softirq_active(pirq_dpci) ? -ERESTART : 0; } static int pci_clean_dpci_irqs(struct domain *d) @@@@ -897,18 +896,8 @@@@ static int pci_clean_dpci_irqs(struct do hvm_irq_dpci = domain_get_irq_dpci(d); if ( hvm_irq_dpci != NULL ) { - int ret = 0; - - if ( hvm_irq_dpci->pending_pirq_dpci ) - { - if ( pt_pirq_softirq_active(hvm_irq_dpci->pending_pirq_dpci) ) - ret = -ERESTART; - else - hvm_irq_dpci->pending_pirq_dpci = NULL; - } + int ret = pt_pirq_iterate(d, pci_clean_dpci_irq, NULL); - if ( !ret ) - ret = pt_pirq_iterate(d, pci_clean_dpci_irq, NULL); if ( ret ) { spin_unlock(&d->event_lock); --- xen/include/asm-x86/hvm/irq.h.orig +++ xen/include/asm-x86/hvm/irq.h @@@@ -160,8 +160,6 @@@@ struct hvm_irq_dpci { DECLARE_BITMAP(isairq_map, NR_ISAIRQS); /* Record of mapped Links */ uint8_t link_cnt[NR_LINK]; - /* Clean up: Entry with a softirq invocation pending / in progress. */ - struct hvm_pirq_dpci *pending_pirq_dpci; }; /* Machine IRQ to guest device/intx mapping. */ @