Package: src:xen
Version: 4.13
Tags: patch

I've been playing try to get Xen 4.13 to cross-build for ARM.  In the
process I've been running into bunches of problems, so here are fixes.

OCAML/xenstored is being problematic, that looks like outright bugs on
ocaml-nox making it unusable for cross-building.

I'm including copies of 3 patches from Julien Grall.  Upstream source for
this is: git://xenbits.xen.org/people/julieng/xen-unstable.git  The
branch "arm-dma/v2".

Why yes, I am trying to get Xen operational on a Raspberry PI.  Why do
you ask?  :-)


-- 
(\___(\___(\______          --=> 8-) EHM <=--          ______/)___/)___/)
 \BS (    |         ehem+sig...@m5p.com  PGP 87145445         |    )   /
  \_CS\   |  _____  -O #include <stddisclaimer.h> O-   _____  |   /  _/
8A19\___\_|_/58D2 7E3D DDF4 7BA6 <-PGP-> 41D1 B375 37D0 8714\_|_/___/5445


>From e8cba1d9fdbb595d80e37e06c544634b879552ca Mon Sep 17 00:00:00 2001
From: Elliott Mitchell <ehem+deb...@m5p.com>
Date: Thu, 16 Jul 2020 22:39:45 -0700
Subject: [PATCH 01/10] Revert "debian/rules: Do not try to move EFI binaries
 on armhf"

This reverts commit 8ff478af61fa8a87806a89bbd618cd9da2354302.
---
 debian/rules | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/debian/rules b/debian/rules
index 543c735f3e..cd90e27038 100755
--- a/debian/rules
+++ b/debian/rules
@@ -224,10 +224,7 @@ override_dh_auto_install: $(TEMPLATED_FILES)
 		-C tools/firmware install-shim
 	:
 	@# Inexplicably, upstream puts the efi binares in usr/lib64
-	case $(flavour) in \
-		armhf) ;; \
-		*) mv $t/usr/lib64/efi/* $t/boot/. ;; \
-	esac
+	mv $t/usr/lib64/efi/* $t/boot/.
 	:
 	@# This file contains an arch-specific path and we put it
 	@# in xen-utils-common, an arch-all package.  But the
-- 
2.20.1

>From ad0e2a13b9a30efee7af5670dcc4aa9e0ed2d99f Mon Sep 17 00:00:00 2001
From: Elliott Mitchell <ehem+deb...@m5p.com>
Date: Thu, 16 Jul 2020 22:16:50 -0700
Subject: [PATCH 02/10] debian/rules: Only install PV shim for supported
 architectures

UEFI is available on ARM64 devices, but presently there is no Xen
configuration for building the PV shim on ARM.  The install step needs
to match the build step, so modify the install step.

Take out a typo while at it.
---
 debian/rules | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/debian/rules b/debian/rules
index cd90e27038..c3d5ed8941 100755
--- a/debian/rules
+++ b/debian/rules
@@ -217,11 +217,15 @@ override_dh_auto_install: $(TEMPLATED_FILES)
 	:
 	@# shim install target needs to be run separately because we
 	@# need to pass it the make_args_xen settings, in particular
-	@# on i386 bwe need to pass x86_64 here to actually build it.
+	@# on i386 we need to pass x86_64 here to actually build it.
 	@# Luckily this target, unlike the build, is a noop on
 	@# shimless arches, so it does not need to be conditional.
-	$(MAKE) $(make_args_xen) DESTDIR=$t $(make_args_xen) \
-		-C tools/firmware install-shim
+	case $(flavour) in \
+	amd64|i386) \
+		$(MAKE) $(make_args_xen) DESTDIR=$t $(make_args_xen) \
+			-C tools/firmware install-shim \
+	;; \
+	esac
 	:
 	@# Inexplicably, upstream puts the efi binares in usr/lib64
 	mv $t/usr/lib64/efi/* $t/boot/.
-- 
2.20.1

>From 2b74f2b56c6417555746a9ebf06faf220d062a7c Mon Sep 17 00:00:00 2001
From: Elliott Mitchell <ehem+deb...@m5p.com>
Date: Thu, 16 Jul 2020 23:37:42 -0700
Subject: [PATCH 03/10] debian/rules: Fix binary shuffling script for
 cross-building

`ldd` doesn't work with cross-builds, so use `file` to detect scripts
and `strings | grep` for identifying linked libraries.

Script almost conforms to POSIX shell standard, so adjust to conform and
switch to /bin/sh.  Simplify pipe structure, do more work in parent
shell.
---
 debian/shuffle-binaries | 44 +++++++++++++++++++++++------------------
 1 file changed, 25 insertions(+), 19 deletions(-)

diff --git a/debian/shuffle-binaries b/debian/shuffle-binaries
index cff6de5428..e8af88f555 100755
--- a/debian/shuffle-binaries
+++ b/debian/shuffle-binaries
@@ -1,6 +1,5 @@
-#!/bin/bash
+#!/bin/sh
 set -e
-set -o pipefail
 
 version=$1; shift
 
@@ -20,31 +19,38 @@ t=debian/tmp
 vd=/usr/lib/xen-$version/bin
 cd=/usr/lib/xen-common/bin
 
-mkdir -p $t/$vd
+mkdir -p "$t/$vd"
 
-for binary in `find $t/usr/{bin,sbin} -type f`; do
+find "$t"/usr/*bin -type f | while read exec; do
 	reason=''
-	{ ldd "$binary" ||: ; } | { fgrep '=>' ||: ; } \
-	| (
-		while read lib dummy; do
+
+	# filter out scripts
+	file "$exec" | grep -q -eELF.\\+version.\\+interpreter || continue
+
+	# ldd doesn't work for cross-building
+	reason=$(
+		strings "$exec" | grep -e^lib.\\+\\.so\\.\[.0-9\]\\+\$ | \
+		while read lib; do
 			lib=${lib%.so.*}
-			if grep -F "usr/lib/*/$lib.so.*" $list >/dev/null; then
-				reason+=" $lib"
+			if grep -q -F "usr/lib/*/$lib.so.*" $list; then
+				printf " %s" "$lib"
 			fi
 		done
+	)
 
-		if [ "x$reason" = x ]; then
-			exit 0
-		fi
+	# if no reason, then skip
+	[ -n "$reason" ] || continue
 
-		echo "shuffling $binary $reason"
+	echo "shuffling $exec$reason"
 
-		leaf=${binary##*}
-		mv -v $binary $t/$vd/$leaf
-		ln -vs $cd/xen-utils-wrapper $binary
+	leaf=${exec##*}
+	mv -v $exec $t/$vd/$leaf
+	ln -vs $cd/xen-utils-wrapper $exec
 
-		touch debian/shuffle-binaries.stamp
-	)
+	touch "$0.stamp"
 done
 
-ls debian/shuffle-binaries.stamp
+if [ ! -e "$0.stamp" ]; then
+	echo "Failed to shuffle binaries!" 1>&2
+	exit 1
+fi
-- 
2.20.1

>From fd7a445d19c0408b31dc8acf100a08ec9359169a Mon Sep 17 00:00:00 2001
From: Elliott Mitchell <ehem+deb...@m5p.com>
Date: Fri, 17 Jul 2020 12:05:25 -0700
Subject: [PATCH 04/10] debian/rules: Adjust boot shuffling script for POSIX

Often /bin/sh is distinctly faster than Bash, so move to the better
interpreter.  Simplify variable usage to conform.
---
 debian/shuffle-boot-files | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/debian/shuffle-boot-files b/debian/shuffle-boot-files
index f7492c0c72..8e4ed7e64c 100755
--- a/debian/shuffle-boot-files
+++ b/debian/shuffle-boot-files
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
 
 set -e
 
@@ -26,6 +26,7 @@ verstring=$(readlink debian/tmp/boot/xen.gz ||
 verstring=${verstring##*/}
 verstring=${verstring%.gz}
 
-for f in `cd $t/boot && find * -type f -print`; do
-	cp -v $t/boot/$f $dest/${f/$verstring/xen-$version-$flavour}
+find "$t/boot" -type f -print | while read f
+do
+	cp -v "$f" "$dest${f#$t/boot}"
 done
-- 
2.20.1

>From 8d3a9adb267e100d14ac0f8ce1ef9bfe46cdde52 Mon Sep 17 00:00:00 2001
From: Elliott Mitchell <ehem+deb...@m5p.com>
Date: Thu, 16 Jul 2020 19:07:31 -0700
Subject: [PATCH 05/10] debian/rules: Combine shared Make args

The original author of debian/rules seemed to have planned to make use
of $(make_args_common), but never got to sharing combined values.  Since
some values are shareable, make use of the shared args.
---
 debian/rules | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/debian/rules b/debian/rules
index c3d5ed8941..23ffd830c2 100755
--- a/debian/rules
+++ b/debian/rules
@@ -134,15 +134,15 @@ dpkg_CFLAGS   := $(shell $(dbmo) dpkg-buildflags --get CFLAGS)
 dpkg_CPPFLAGS := $(shell $(dbmo) dpkg-buildflags --get CPPFLAGS)
 dpkg_LDFLAGS  := $(shell $(dbmo) dpkg-buildflags --get LDFLAGS)
 
-make_args_xen= $(make_args_common) \
+make_args_common := \
 	XEN_COMPILE_ARCH=$(xen_arch_$(DEB_BUILD_ARCH)) \
-	XEN_TARGET_ARCH=$(xen_arch_$(flavour)) \
+	XEN_TARGET_ARCH=$(xen_arch_$(flavour))
+
+make_args_xen := $(make_args_common)
 # (Xen upstream does not offer a separate CPPFLAGS,
 # so we pass those in CFLAGS.)
 
-make_args_tools= $(make_args_common) \
-	XEN_COMPILE_ARCH=$(xen_arch_$(DEB_BUILD_ARCH)) \
-	XEN_TARGET_ARCH=$(xen_arch_$(DEB_HOST_ARCH)) \
+make_args_tools := $(make_args_common) \
 	EXTRA_CFLAGS_XEN_TOOLS='$(dpkg_CFLAGS) $(dpkg_CPPFLAGS)' \
 	PREPEND_LDFLAGS_XEN_TOOLS='$(dpkg_LDFLAGS)'
 
-- 
2.20.1

>From a9aabbd637a715ededa8c98f500f290f06fdbe38 Mon Sep 17 00:00:00 2001
From: Elliott Mitchell <ehem+deb...@m5p.com>
Date: Thu, 16 Jul 2020 16:25:13 -0700
Subject: [PATCH 06/10] debian/rules: Add --host to tools configure target

Without this, we'll be building tools for the build machine, not the host
machine.
---
 debian/rules | 1 +
 1 file changed, 1 insertion(+)

diff --git a/debian/rules b/debian/rules
index 23ffd830c2..70235b494c 100755
--- a/debian/rules
+++ b/debian/rules
@@ -178,6 +178,7 @@ override_dh_auto_configure:
 		--includedir=/usr/include \
 		--libdir=/usr/lib/$(DEB_HOST_MULTIARCH) \
 		--with-libexec-libdir-suffix=/$(DEB_HOST_MULTIARCH) \
+		--host=$(DEB_HOST_MULTIARCH) \
 		--mandir=/usr/share/man \
 		--infodir=/usr/share/info \
 		--sysconfdir=/etc \
-- 
2.20.1

>From 32c6eb583c832cb21fece28e64111ee71a912a88 Mon Sep 17 00:00:00 2001
From: Elliott Mitchell <ehem+deb...@m5p.com>
Date: Thu, 16 Jul 2020 19:07:31 -0700
Subject: [PATCH 07/10] debian/rules: Set CC/LD for cross-building

Set $(CC) and $(LD) when cross-building.  People building ARM
executeables on ARM hosts are notably uncommon.
---
 debian/rules | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/debian/rules b/debian/rules
index 70235b494c..d1d467e9dd 100755
--- a/debian/rules
+++ b/debian/rules
@@ -138,6 +138,12 @@ make_args_common := \
 	XEN_COMPILE_ARCH=$(xen_arch_$(DEB_BUILD_ARCH)) \
 	XEN_TARGET_ARCH=$(xen_arch_$(flavour))
 
+ifneq ($(DEB_HOST_MULTIARCH),$(DEB_BUILD_MULTIARCH))
+make_args_common += \
+	CC=$(DEB_HOST_MULTIARCH)-gcc \
+	LD=$(DEB_HOST_MULTIARCH)-ld
+endif
+
 make_args_xen := $(make_args_common)
 # (Xen upstream does not offer a separate CPPFLAGS,
 # so we pass those in CFLAGS.)
-- 
2.20.1

>From 45003da04d29aa674e79e998dfc73b87cba7e7bb Mon Sep 17 00:00:00 2001
From: Julien Grall <jgr...@amazon.com>
Date: Sat, 16 May 2020 11:41:16 +0100
Subject: [PATCH 08/10] xen/arm: Allow a platform to override the DMA width

At the moment, Xen is assuming that all the devices are at least 32-bit
DMA capable. However, some SoC have devices that may be able to access
a much restricted range. For instance, the RPI has devices that can
only access the first 1GB of RAM.

The structure platform_desc is now extended to allow a platform to
override the DMA width. The new is used to implement
arch_get_dma_bit_size().

The prototype is now moved in asm-arm/mm.h as the function is not NUMA
specific. The implementation is done in platform.c so we don't have to
include platform.h everywhere. This should be fine as the function is
not expected to be called in hotpath.

Signed-off-by: Julien Grall <jgr...@amazon.com>
Reviewed-by: Volodymyr Babchuk <volodymyr_babc...@epam.com>
Tested-by: Corey Minyard <cminy...@mvista.com>

---

Cc: Jan Beulich <jbeul...@suse.com>
Cc: Andrew Cooper <andrew.coop...@citrix.com>
Cc: George Dunlap <george.dun...@citrix.com>

    Changes in v2:
        - Add Corey's tested-by
        - Add Volodymyr's reviewed-by

I noticed that arch_get_dma_bit_size() is only called when there is more
than one NUMA node. I am a bit unsure what is the reason behind it.

The goal for Arm is to use arch_get_dma_bit_size() when deciding how low
the first Dom0 bank should be allocated.
---
 xen/arch/arm/platform.c        | 5 +++++
 xen/include/asm-arm/mm.h       | 2 ++
 xen/include/asm-arm/numa.h     | 5 -----
 xen/include/asm-arm/platform.h | 2 ++
 4 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/xen/arch/arm/platform.c b/xen/arch/arm/platform.c
index 8eb0b6e57a..4db5bbb4c5 100644
--- a/xen/arch/arm/platform.c
+++ b/xen/arch/arm/platform.c
@@ -155,6 +155,11 @@ bool platform_device_is_blacklisted(const struct dt_device_node *node)
     return (dt_match_node(blacklist, node) != NULL);
 }
 
+unsigned int arch_get_dma_bitsize(void)
+{
+    return ( platform && platform->dma_bitsize ) ? platform->dma_bitsize : 32;
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h
index 333efd3a60..a557e100c1 100644
--- a/xen/include/asm-arm/mm.h
+++ b/xen/include/asm-arm/mm.h
@@ -363,6 +363,8 @@ int arch_acquire_resource(struct domain *d, unsigned int type, unsigned int id,
     return -EOPNOTSUPP;
 }
 
+unsigned int arch_get_dma_bitsize(void);
+
 #endif /*  __ARCH_ARM_MM__ */
 /*
  * Local variables:
diff --git a/xen/include/asm-arm/numa.h b/xen/include/asm-arm/numa.h
index 490d1f31aa..31a6de4e23 100644
--- a/xen/include/asm-arm/numa.h
+++ b/xen/include/asm-arm/numa.h
@@ -25,11 +25,6 @@ extern mfn_t first_valid_mfn;
 #define node_start_pfn(nid) (mfn_x(first_valid_mfn))
 #define __node_distance(a, b) (20)
 
-static inline unsigned int arch_get_dma_bitsize(void)
-{
-    return 32;
-}
-
 #endif /* __ARCH_ARM_NUMA_H */
 /*
  * Local variables:
diff --git a/xen/include/asm-arm/platform.h b/xen/include/asm-arm/platform.h
index ed4d30a1be..997eb25216 100644
--- a/xen/include/asm-arm/platform.h
+++ b/xen/include/asm-arm/platform.h
@@ -38,6 +38,8 @@ struct platform_desc {
      * List of devices which must not pass-through to a guest
      */
     const struct dt_device_match *blacklist_dev;
+    /* Override the DMA width (32-bit by default). */
+    unsigned int dma_bitsize;
 };
 
 /*
-- 
2.20.1

>From b3eb3e7068d274849d0c4a9aa54aa807ca57d3a7 Mon Sep 17 00:00:00 2001
From: Julien Grall <jgr...@amazon.com>
Date: Sat, 16 May 2020 11:57:00 +0100
Subject: [PATCH 09/10] xen/arm: Take into account the DMA width when
 allocating Dom0 memory banks

At the moment, Xen is assuming that all the devices are at least 32-bit
DMA capable. However, some SoCs have devices that may be able to access
a much restricted range. For instance, the Raspberry PI 4 has devices
that can only access the first GB of RAM.

The function arch_get_dma_bit_size() will return the lowest DMA width on
the platform. Use it to decide what is the limit for the low memory.

Signed-off-by: Julien Grall <jgr...@amazon.com>
Tested-by: Corey Minyard <cminy...@mvista.com>

---
    Changes in v2:
        - Remove left-over in the comment
        - Add Corey's tested-by
---
 xen/arch/arm/domain_build.c | 33 +++++++++++++++++++--------------
 1 file changed, 19 insertions(+), 14 deletions(-)

diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index dd9c3b73ba..c9982ba98f 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -210,10 +210,12 @@ fail:
  *    the ramdisk and DTB must be placed within a certain proximity of
  *    the kernel within RAM.
  * 3. For dom0 we want to place as much of the RAM as we reasonably can
- *    below 4GB, so that it can be used by non-LPAE enabled kernels (32-bit)
- *    or when a device assigned to dom0 can only do 32-bit DMA access.
- * 4. For 32-bit dom0 the kernel must be located below 4GB.
- * 5. We want to have a few largers banks rather than many smaller ones.
+ *    below 4GB, so that it can be used by non-LPAE enabled kernels (32-bit).
+ * 4. Some devices assigned to dom0 can only do 32-bit DMA access or
+ *    even be more restricted. We want to allocate as much of the RAM
+ *    as we reasonably can that can be accessed from all the devices..
+ * 5. For 32-bit dom0 the kernel must be located below 4GB.
+ * 6. We want to have a few largers banks rather than many smaller ones.
  *
  * For the first two requirements we need to make sure that the lowest
  * bank is sufficiently large.
@@ -244,9 +246,9 @@ fail:
  * we give up.
  *
  * For 32-bit domain we require that the initial allocation for the
- * first bank is under 4G. For 64-bit domain, the first bank is preferred
- * to be allocated under 4G. Then for the subsequent allocations we
- * initially allocate memory only from below 4GB. Once that runs out
+ * first bank is part of the low mem. For 64-bit, the first bank is preferred
+ * to be allocated in the low mem. Then for subsequent allocation, we
+ * initially allocate memory only from low mem. Once that runs out out
  * (as described above) we allow higher allocations and continue until
  * that runs out (or we have allocated sufficient dom0 memory).
  */
@@ -261,6 +263,7 @@ static void __init allocate_memory_11(struct domain *d,
     int i;
 
     bool lowmem = true;
+    unsigned int lowmem_bitsize = min(32U, arch_get_dma_bitsize());
     unsigned int bits;
 
     /*
@@ -281,7 +284,7 @@ static void __init allocate_memory_11(struct domain *d,
      */
     while ( order >= min_low_order )
     {
-        for ( bits = order ; bits <= (lowmem ? 32 : PADDR_BITS); bits++ )
+        for ( bits = order ; bits <= lowmem_bitsize; bits++ )
         {
             pg = alloc_domheap_pages(d, order, MEMF_bits(bits));
             if ( pg != NULL )
@@ -295,24 +298,26 @@ static void __init allocate_memory_11(struct domain *d,
         order--;
     }
 
-    /* Failed to allocate bank0 under 4GB */
+    /* Failed to allocate bank0 in the lowmem region. */
     if ( is_32bit_domain(d) )
         panic("Unable to allocate first memory bank\n");
 
-    /* Try to allocate memory from above 4GB */
-    printk(XENLOG_INFO "No bank has been allocated below 4GB.\n");
+    /* Try to allocate memory from above the lowmem region */
+    printk(XENLOG_INFO "No bank has been allocated below %u-bit.\n",
+           lowmem_bitsize);
     lowmem = false;
 
  got_bank0:
 
     /*
-     * If we failed to allocate bank0 under 4GB, continue allocating
-     * memory from above 4GB and fill in banks.
+     * If we failed to allocate bank0 in the lowmem region,
+     * continue allocating from above the lowmem and fill in banks.
      */
     order = get_allocation_size(kinfo->unassigned_mem);
     while ( kinfo->unassigned_mem && kinfo->mem.nr_banks < NR_MEM_BANKS )
     {
-        pg = alloc_domheap_pages(d, order, lowmem ? MEMF_bits(32) : 0);
+        pg = alloc_domheap_pages(d, order,
+                                 lowmem ? MEMF_bits(lowmem_bitsize) : 0);
         if ( !pg )
         {
             order --;
-- 
2.20.1

>From b454007737957f8b64b57ba5887836a80eb1c4d3 Mon Sep 17 00:00:00 2001
From: Julien Grall <jgr...@amazon.com>
Date: Sat, 16 May 2020 20:16:57 +0100
Subject: [PATCH 10/10] xen/arm: plat: Allocate as much as possible memory
 below 1GB for dom0 for RPI

The raspberry PI 4 has devices that can only DMA into the first GB of
the RAM. Therefore we want allocate as much as possible memory below 1GB
for dom0.

Use the recently introduced dma_bitsize field to specify the DMA width
supported.

Signed-off-by: Julien Grall <jgr...@amazon.com>
Reported-by: Corey Minyard <miny...@acm.org>
Tested-by: Corey Minyard <cminy...@mvista.com>

---
    Changes in v2:
        - 1G is 30 bits not 10!
        - Add Corey's tested-by
---
 xen/arch/arm/platforms/brcm-raspberry-pi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/xen/arch/arm/platforms/brcm-raspberry-pi.c b/xen/arch/arm/platforms/brcm-raspberry-pi.c
index b697fa2c6c..f5ae58a7d5 100644
--- a/xen/arch/arm/platforms/brcm-raspberry-pi.c
+++ b/xen/arch/arm/platforms/brcm-raspberry-pi.c
@@ -43,6 +43,7 @@ static const struct dt_device_match rpi4_blacklist_dev[] __initconst =
 PLATFORM_START(rpi4, "Raspberry Pi 4")
     .compatible     = rpi4_dt_compat,
     .blacklist_dev  = rpi4_blacklist_dev,
+    .dma_bitsize    = 30,
 PLATFORM_END
 
 /*
-- 
2.20.1

Reply via email to