From 3b58700705b09ff80c7e14e5088c7592dc8acb97 Mon Sep 17 00:00:00 2001 From: Christopher Brannon Date: Wed, 17 Feb 2021 19:09:50 -0800 Subject: [PATCH 1/2] xen: prevent unwanted service starts, support oxenstored in service. This is a rather convoluted fix for issue 18676. We don't want to burn cycles and spam the user when the Xen services are enabled and the system is not booted as a Xen dom0. Booting a Xen install into vanilla Linux without Xen is sometimes useful; that experience should be more pleasant now. Also, make the xenstored implementation selectable. There are two implementations shipped by Xen and in our Xen package: the original one written in C (binary is just called xenstored) and a newer one in ocaml (oxenstored). oxenstored is -- IME -- more reliable. Make it configurable in ./conf, but leave the default as-is. Add a patch to fix failing to build from source on musl with newer argp-standalone. --- srcpkgs/xen/files/xen.conf | 1 + srcpkgs/xen/files/xen/run | 7 +++++-- srcpkgs/xen/files/xenconsoled/check | 15 ++++++++++++++ srcpkgs/xen/files/xenconsoled/log/run | 2 ++ srcpkgs/xen/files/xenconsoled/run | 8 ++++++++ srcpkgs/xen/files/xenstored/check | 11 ++++++++++ srcpkgs/xen/files/xenstored/log/run | 2 ++ srcpkgs/xen/files/xenstored/run | 25 ++++++++++++++++++++--- srcpkgs/xen/patches/argp-standalone.patch | 15 ++++++++++++++ srcpkgs/xen/template | 2 +- 10 files changed, 82 insertions(+), 6 deletions(-) create mode 100755 srcpkgs/xen/files/xenconsoled/check create mode 100755 srcpkgs/xen/files/xenconsoled/log/run create mode 100755 srcpkgs/xen/files/xenstored/check create mode 100755 srcpkgs/xen/files/xenstored/log/run create mode 100644 srcpkgs/xen/patches/argp-standalone.patch diff --git a/srcpkgs/xen/files/xen.conf b/srcpkgs/xen/files/xen.conf index 4fbf6c96bc8e..95b777b20a1d 100644 --- a/srcpkgs/xen/files/xen.conf +++ b/srcpkgs/xen/files/xen.conf @@ -1,3 +1,4 @@ +xenfs xen-evtchn xen-gntdev xen-gntalloc diff --git a/srcpkgs/xen/files/xen/run b/srcpkgs/xen/files/xen/run index b35a945d1bec..c60cd582208d 100755 --- a/srcpkgs/xen/files/xen/run +++ b/srcpkgs/xen/files/xen/run @@ -1,5 +1,8 @@ #!/bin/sh +sv start xenconsoled > /dev/null || exit 1 sv check xenconsoled >/dev/null || exit 1 -xenstore-write "/local/domain/0/domid" 0 || exit 1 -xenstore-write "/local/domain/0/name" "Domain-0" || exit 1 +if ! pgrep -f '^shim-xenconsoled' ; then + xenstore-write "/local/domain/0/domid" 0 || exit 1 + xenstore-write "/local/domain/0/name" "Domain-0" || exit 1 +fi exec chpst -b xen pause diff --git a/srcpkgs/xen/files/xenconsoled/check b/srcpkgs/xen/files/xenconsoled/check new file mode 100755 index 000000000000..05cfd18d0b30 --- /dev/null +++ b/srcpkgs/xen/files/xenconsoled/check @@ -0,0 +1,15 @@ +#!/bin/sh + +exec > /dev/null +exec 2>&1 + +# Check for the faux xenconsoled first: +pgrep -f '^shim-xenconsoled' && exit 0 + +# There's not really a good way to check for xenconsoled being up. +# The best I can come up with is to look at the open FDs, and if +# hypervisor.log is open, then xenconsoled is almost certainly started +# and ready to use. +PID="$(pidof xenconsoled)" || exit 1 +expr "x${PID}" ':' 'x[0-9]\+$' > /dev/null || exit 1 +ls -l "/proc/${PID}/fd" 2>/dev/null |grep -q hypervisor.log diff --git a/srcpkgs/xen/files/xenconsoled/log/run b/srcpkgs/xen/files/xenconsoled/log/run new file mode 100755 index 000000000000..da2b3ba7d791 --- /dev/null +++ b/srcpkgs/xen/files/xenconsoled/log/run @@ -0,0 +1,2 @@ +#!/bin/sh +exec logger -p daemon.notice -t xenconsoled diff --git a/srcpkgs/xen/files/xenconsoled/run b/srcpkgs/xen/files/xenconsoled/run index bf13989cdb95..72d541803795 100755 --- a/srcpkgs/xen/files/xenconsoled/run +++ b/srcpkgs/xen/files/xenconsoled/run @@ -1,4 +1,12 @@ #!/bin/sh +exec 2>&1 +sv start xenstored >/dev/null || exit 1 sv check xenstored >/dev/null || exit 1 + +if pgrep -f '^shim-xenstored' ; then + # Not a Xen dom0; make this a no-op service. + exec chpst -b 'shim-xenconsoled' pause +fi + mkdir -p /var/log/xen/console exec xenconsoled -i --log=all diff --git a/srcpkgs/xen/files/xenstored/check b/srcpkgs/xen/files/xenstored/check new file mode 100755 index 000000000000..88df8d1ac170 --- /dev/null +++ b/srcpkgs/xen/files/xenstored/check @@ -0,0 +1,11 @@ +#!/bin/sh +exec > /dev/null +exec 2>&1 + +# Check for faux xenstored first. If it is, we aren't running under +# a Xen dom0. Consider xenstored started. +pgrep -f '^shim-xenstored' && exit 0 + +# The root key should always exist if xenstored is running, so we have +# a simple test. +/usr/bin/xenstore-exists / diff --git a/srcpkgs/xen/files/xenstored/log/run b/srcpkgs/xen/files/xenstored/log/run new file mode 100755 index 000000000000..bab732f16ce6 --- /dev/null +++ b/srcpkgs/xen/files/xenstored/log/run @@ -0,0 +1,2 @@ +#!/bin/sh +exec logger -p daemon.notice -t xenstored diff --git a/srcpkgs/xen/files/xenstored/run b/srcpkgs/xen/files/xenstored/run index f30d9adefaa4..5015fd75a1d3 100755 --- a/srcpkgs/xen/files/xenstored/run +++ b/srcpkgs/xen/files/xenstored/run @@ -1,7 +1,26 @@ #!/bin/sh +exec 2>&1 [ ! -d /run/xen ] && mkdir -p /run/xen -modprobe -q xen-evtchn xen-gnttalloc || exit 1 mountpoint -q /proc/xen || mount -t xenfs xenfs /proc/xen +# If not running in a Xen dom0, then this service is a no-op +# and we can't start a real xenstored. +grep -q control_d /proc/xen/capabilities || \ + exec chpst -b \ + 'shim-xenstored; see /etc/sv/xenstored/run to find out what this is' \ + pause mountpoint -q /var/lib/xenstored || mount -t tmpfs xenstored /var/lib/xenstored -grep -q control_d /proc/xen/capabilities || exit 1 -exec xenstored --verbose --no-fork + +# shellcheck disable=SC1091 +[ -r conf ] && . ./conf +XENSTORED="${XENSTORED:-xenstored}" +case "$(basename "${XENSTORED}")" in + oxenstored) + XENSTORED_ARGS="${XENSTORED_ARGS:---no-fork}" + ;; + *) + XENSTORED_ARGS="${XENSTORED_ARGS:---verbose --no-fork}" + ;; +esac + +# shellcheck disable=SC2086 +exec "${XENSTORED}" ${XENSTORED_ARGS} diff --git a/srcpkgs/xen/patches/argp-standalone.patch b/srcpkgs/xen/patches/argp-standalone.patch new file mode 100644 index 000000000000..5ff66ce732f8 --- /dev/null +++ b/srcpkgs/xen/patches/argp-standalone.patch @@ -0,0 +1,15 @@ +Fix build with recent argp-standalone. +I'll try and get this upstreamed so we don't have to carry it. + +diff -Nur xen-4.14.1.orig/tools/configure.ac xen-4.14.1/tools/configure.ac +--- xen-4.14.1.orig/tools/configure.ac 2020-12-17 16:47:25.000000000 +0000 ++++ xen-4.14.1/tools/configure.ac 2021-02-20 19:44:33.618002472 +0000 +@@ -426,7 +426,7 @@ + AC_CHECK_LIB([iconv], [libiconv_open], [libiconv="y"], [libiconv="n"]) + AC_SUBST(libiconv) + AC_CHECK_HEADER([argp.h], [ +-AC_CHECK_LIB([argp], [argp_usage], [argp_ldflags="-largp"]) ++AC_CHECK_LIB([argp], [argp_parse], [argp_ldflags="-largp"]) + ], [AC_MSG_ERROR([Could not find argp])]) + AC_SUBST(argp_ldflags) + diff --git a/srcpkgs/xen/template b/srcpkgs/xen/template index 092460ea73e5..d058c7697ce9 100644 --- a/srcpkgs/xen/template +++ b/srcpkgs/xen/template @@ -1,7 +1,7 @@ # Template file for 'xen' pkgname=xen version=4.14.1 -revision=2 +revision=3 # grep -R IPXE_GIT_TAG src/xen-*/tools/firmware/etherboot _git_tag_ipxe=4bd064de239dab2426b31c9789a1f4d78087dc63 # TODO: arm / aarch64 From 4a4789c64a4250ae7d3e1be9c7553dd48e5069f9 Mon Sep 17 00:00:00 2001 From: Christopher Brannon Date: Wed, 28 Apr 2021 04:36:32 -0700 Subject: [PATCH 2/2] xen: update to 4.14.2. --- srcpkgs/xen/patches/xsa360-4.14.patch | 97 --------------------------- srcpkgs/xen/template | 6 +- 2 files changed, 3 insertions(+), 100 deletions(-) delete mode 100644 srcpkgs/xen/patches/xsa360-4.14.patch diff --git a/srcpkgs/xen/patches/xsa360-4.14.patch b/srcpkgs/xen/patches/xsa360-4.14.patch deleted file mode 100644 index 1bc185b110dc..000000000000 --- a/srcpkgs/xen/patches/xsa360-4.14.patch +++ /dev/null @@ -1,97 +0,0 @@ -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 - ---- a/xen/arch/x86/irq.c -+++ b/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. */ ---- a/xen/drivers/passthrough/pci.c -+++ b/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); ---- a/xen/include/asm-x86/hvm/irq.h -+++ b/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. */ diff --git a/srcpkgs/xen/template b/srcpkgs/xen/template index d058c7697ce9..9c95003e069a 100644 --- a/srcpkgs/xen/template +++ b/srcpkgs/xen/template @@ -1,7 +1,7 @@ # Template file for 'xen' pkgname=xen -version=4.14.1 -revision=3 +version=4.14.2 +revision=1 # grep -R IPXE_GIT_TAG src/xen-*/tools/firmware/etherboot _git_tag_ipxe=4bd064de239dab2426b31c9789a1f4d78087dc63 # TODO: arm / aarch64 @@ -23,7 +23,7 @@ homepage="https://www.xenproject.org/" distfiles=" https://downloads.xenproject.org/release/xen/${version}/${pkgname}-${version}.tar.gz https://github.com/ipxe/ipxe/archive/${_git_tag_ipxe}.tar.gz" -checksum="cf0d7316ad674491f49b7ef0518cb1d906a2e3bfad639deef0ef2343b119ac0c +checksum="e35099a963070e3c9f425d1e36cbb1c40b7874ef449bfafd6688343783cb25ad 4850691d6f196eaf4d6210f2de01383251b3ea1b928141da9ce28c0b06a90938" skip_extraction="${_git_tag_ipxe}.tar.gz" nopie=yes