[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] xen/arm: Skip memory nodes if not enabled



During the Linux kernel booting, an error is reported by the Xen
hypervisor:

  (XEN) arch/arm/p2m.c:2202: d0v0: Failing to acquire the MFN 0x1a02dc

The kernel attempts to use an invalid memory frame number, which can be
converted to: 0x1a02dc << PAGE_SHIFT, resulting in 0x1_a02d_c000.

The invalid memory frame falls into a reserved memory node, which is
defined in the device tree as below:

  reserved-memory {
          #address-cells = <0x02>;
          #size-cells = <0x02>;
          ranges;

          ...

          ethosn_reserved {
                  compatible = "shared-dma-pool";
                  reg = <0x01 0xa0000000 0x00 0x20000000>;
                  status = "disabled";
                  no-map;
          };

          ...
  };

Xen excludes all reserved memory regions from the frame management
through the dt_unreserved_regions() function. On the other hand, the
reserved memory nodes are passed to the Linux kernel. However, the Linux
kernel ignores the 'ethosn_reserved' node since its status is
"disabled". This leads to the Linux kernel to allocate pages from the
reserved memory range.

As a result, when the kernel passes the data structure residing in the
frame 0x1_a02d_c000 in the Xen hypervisor, the hypervisor detects that
it misses to manage the frame and reports the error.

Essentially, this issue is caused by the Xen hypervisor which misses to
handle the status for the memory nodes (for both the normal memory nodes
and the reserved memory nodes) and transfers them to the Linux kernel.

This patch introduces a function memory_node_is_available(). If it
detects a memory node is not enabled, the hypervisor will not add the
memory region into the memory lists. In the end, this avoids to generate
the memory nodes from the memory lists sent to the kernel and the kernel
cannot use the disabled memory nodes any longer.

Signed-off-by: Leo Yan <leo.yan@xxxxxxxxxx>
---
 xen/arch/arm/bootfdt.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/xen/arch/arm/bootfdt.c b/xen/arch/arm/bootfdt.c
index 2673ad17a1..b46dde06a9 100644
--- a/xen/arch/arm/bootfdt.c
+++ b/xen/arch/arm/bootfdt.c
@@ -206,11 +206,27 @@ int __init device_tree_for_each_node(const void *fdt, int 
node,
     return 0;
 }
 
+static bool __init memory_node_is_available(const void *fdt, unsigned long 
node)
+{
+    const char *status = fdt_getprop(fdt, node, "status", NULL);
+
+    if (!status)
+        return true;
+
+    if (!strcmp(status, "ok") || !strcmp(status, "okay"))
+        return true;
+
+    return false;
+}
+
 static int __init process_memory_node(const void *fdt, int node,
                                       const char *name, int depth,
                                       u32 address_cells, u32 size_cells,
                                       void *data)
 {
+    if (!memory_node_is_available(fdt, node))
+        return 0;
+
     return device_tree_get_meminfo(fdt, node, "reg", address_cells, size_cells,
                                    data, MEMBANK_DEFAULT);
 }
-- 
2.39.2




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.