Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xen: update to 4.14.2. #30599

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions srcpkgs/xen/files/xen.conf
@@ -1,3 +1,4 @@
xenfs
xen-evtchn
xen-gntdev
xen-gntalloc
Expand Down
9 changes: 5 additions & 4 deletions srcpkgs/xen/files/xen/run
@@ -1,5 +1,6 @@
#!/bin/sh
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
#!/bin/sh -e
sv check xenstored >/dev/null
sv check xenconsoled >/dev/null
xenstore-write "/local/domain/0/domid" 0
xenstore-write "/local/domain/0/name" "Domain-0"
exec chpst -b xen pause
6 changes: 6 additions & 0 deletions srcpkgs/xen/files/xenconsoled/check
@@ -0,0 +1,6 @@
#!/bin/sh
exec > /dev/null
exec 2>&1

# Exit 0 if the xenconsoled lock is taken (E.G., by a running xenconsoled).
! chpst -L /run/xen/xenconsoled-running.lck true
2 changes: 2 additions & 0 deletions srcpkgs/xen/files/xenconsoled/log/run
@@ -0,0 +1,2 @@
#!/bin/sh
exec logger -p daemon.notice -t xenconsoled
9 changes: 6 additions & 3 deletions srcpkgs/xen/files/xenconsoled/run
@@ -1,4 +1,7 @@
#!/bin/sh
sv check xenstored >/dev/null || exit 1
#!/bin/sh -e
exec 2>&1
sv check xenstored >/dev/null

# xenconsoled writes per-domU logs and hypervisor.log here:
mkdir -p /var/log/xen/console
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would move this to xenconsoled/log/run unless xenconsoled/run is the process that writes to it.

exec xenconsoled -i --log=all
exec chpst -L /run/xen/xenconsoled-running.lck xenconsoled -i --log=all
7 changes: 7 additions & 0 deletions srcpkgs/xen/files/xenstored/check
@@ -0,0 +1,7 @@
#!/bin/sh
exec > /dev/null
exec 2>&1

# If this is a dom0 and the root key in xenstore exists, then xenstored
# must be running.
grep -q control_d /proc/xen/capabilities && /usr/bin/xenstore-exists /
2 changes: 2 additions & 0 deletions srcpkgs/xen/files/xenstored/log/run
@@ -0,0 +1,2 @@
#!/bin/sh
exec logger -p daemon.notice -t xenstored
13 changes: 9 additions & 4 deletions srcpkgs/xen/files/xenstored/run
@@ -1,7 +1,12 @@
#!/bin/sh
#!/bin/sh -e
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
grep -q control_d /proc/xen/capabilities
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

[ -r conf ] && . ./conf
XENSTORED="${XENSTORED:-xenstored}"
XENSTORED_ARGS="${XENSTORED_ARGS} --no-fork"

exec "${XENSTORED}" ${XENSTORED_ARGS}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add --no-fork here rather than to the variable, because it will always be required and we don't want to make people who customize the args have to remember to include it.

15 changes: 15 additions & 0 deletions 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.2.orig/tools/configure.ac xen-4.14.2/tools/configure.ac
--- xen-4.14.2.orig/tools/configure.ac 2020-12-17 16:47:25.000000000 +0000
+++ xen-4.14.2/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)

97 changes: 0 additions & 97 deletions srcpkgs/xen/patches/xsa360-4.14.patch

This file was deleted.

120 changes: 120 additions & 0 deletions srcpkgs/xen/patches/xsa373-4.14-1.patch
@@ -0,0 +1,120 @@
From: Jan Beulich <jbeulich@suse.com>
Subject: VT-d: size qinval queue dynamically

With the present synchronous model, we need two slots for every
operation (the operation itself and a wait descriptor). There can be
one such pair of requests pending per CPU. To ensure that under all
normal circumstances a slot is always available when one is requested,
size the queue ring according to the number of present CPUs.

This is part of XSA-373 / CVE-2021-28692.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Paul Durrant <paul@xen.org>

--- a/xen/drivers/passthrough/vtd/iommu.h
+++ b/xen/drivers/passthrough/vtd/iommu.h
@@ -450,17 +450,9 @@ struct qinval_entry {
}q;
};

-/* Order of queue invalidation pages(max is 8) */
-#define QINVAL_PAGE_ORDER 2
-
-#define QINVAL_ARCH_PAGE_ORDER (QINVAL_PAGE_ORDER + PAGE_SHIFT_4K - PAGE_SHIFT)
-#define QINVAL_ARCH_PAGE_NR ( QINVAL_ARCH_PAGE_ORDER < 0 ? \
- 1 : \
- 1 << QINVAL_ARCH_PAGE_ORDER )
-
/* Each entry is 16 bytes, so 2^8 entries per page */
#define QINVAL_ENTRY_ORDER ( PAGE_SHIFT - 4 )
-#define QINVAL_ENTRY_NR (1 << (QINVAL_PAGE_ORDER + 8))
+#define QINVAL_MAX_ENTRY_NR (1u << (7 + QINVAL_ENTRY_ORDER))

/* Status data flag */
#define QINVAL_STAT_INIT 0
--- a/xen/drivers/passthrough/vtd/qinval.c
+++ b/xen/drivers/passthrough/vtd/qinval.c
@@ -31,6 +31,9 @@

#define VTD_QI_TIMEOUT 1

+static unsigned int __read_mostly qi_pg_order;
+static unsigned int __read_mostly qi_entry_nr;
+
static int __must_check invalidate_sync(struct vtd_iommu *iommu);

static void print_qi_regs(struct vtd_iommu *iommu)
@@ -55,7 +58,7 @@ static unsigned int qinval_next_index(st
tail >>= QINVAL_INDEX_SHIFT;

/* (tail+1 == head) indicates a full queue, wait for HW */
- while ( ( tail + 1 ) % QINVAL_ENTRY_NR ==
+ while ( ((tail + 1) & (qi_entry_nr - 1)) ==
( dmar_readq(iommu->reg, DMAR_IQH_REG) >> QINVAL_INDEX_SHIFT ) )
cpu_relax();

@@ -68,7 +71,7 @@ static void qinval_update_qtail(struct v

/* Need hold register lock when update tail */
ASSERT( spin_is_locked(&iommu->register_lock) );
- val = (index + 1) % QINVAL_ENTRY_NR;
+ val = (index + 1) & (qi_entry_nr - 1);
dmar_writeq(iommu->reg, DMAR_IQT_REG, (val << QINVAL_INDEX_SHIFT));
}

@@ -403,8 +406,28 @@ int enable_qinval(struct vtd_iommu *iomm

if ( iommu->qinval_maddr == 0 )
{
- iommu->qinval_maddr = alloc_pgtable_maddr(QINVAL_ARCH_PAGE_NR,
- iommu->node);
+ if ( !qi_entry_nr )
+ {
+ /*
+ * With the present synchronous model, we need two slots for every
+ * operation (the operation itself and a wait descriptor). There
+ * can be one such pair of requests pending per CPU. One extra
+ * entry is needed as the ring is considered full when there's
+ * only one entry left.
+ */
+ BUILD_BUG_ON(CONFIG_NR_CPUS * 2 >= QINVAL_MAX_ENTRY_NR);
+ qi_pg_order = get_order_from_bytes((num_present_cpus() * 2 + 1) <<
+ (PAGE_SHIFT -
+ QINVAL_ENTRY_ORDER));
+ qi_entry_nr = 1u << (qi_pg_order + QINVAL_ENTRY_ORDER);
+
+ dprintk(XENLOG_INFO VTDPREFIX,
+ "QI: using %u-entry ring(s)\n", qi_entry_nr);
+ }
+
+ iommu->qinval_maddr =
+ alloc_pgtable_maddr(qi_entry_nr >> QINVAL_ENTRY_ORDER,
+ iommu->node);
if ( iommu->qinval_maddr == 0 )
{
dprintk(XENLOG_WARNING VTDPREFIX,
@@ -418,15 +441,16 @@ int enable_qinval(struct vtd_iommu *iomm

spin_lock_irqsave(&iommu->register_lock, flags);

- /* Setup Invalidation Queue Address(IQA) register with the
- * address of the page we just allocated. QS field at
- * bits[2:0] to indicate size of queue is one 4KB page.
- * That's 256 entries. Queued Head (IQH) and Queue Tail (IQT)
- * registers are automatically reset to 0 with write
- * to IQA register.
+ /*
+ * Setup Invalidation Queue Address (IQA) register with the address of the
+ * pages we just allocated. The QS field at bits[2:0] indicates the size
+ * (page order) of the queue.
+ *
+ * Queued Head (IQH) and Queue Tail (IQT) registers are automatically
+ * reset to 0 with write to IQA register.
*/
dmar_writeq(iommu->reg, DMAR_IQA_REG,
- iommu->qinval_maddr | QINVAL_PAGE_ORDER);
+ iommu->qinval_maddr | qi_pg_order);

dmar_writeq(iommu->reg, DMAR_IQT_REG, 0);