Files
xen/docs/misc/arm/device-tree/booting.txt
T
Henry Wang 44e9dcc48b xen/arm: Allocate and free P2M pages from the P2M pool
This commit sets/tearsdown of p2m pages pool for non-privileged Arm
guests by calling `p2m_set_allocation` and `p2m_teardown_allocation`.

- For dom0, P2M pages should come from heap directly instead of p2m
pool, so that the kernel may take advantage of the extended regions.

- For xl guests, the setting of the p2m pool is called in
`XEN_DOMCTL_shadow_op` and the p2m pool is destroyed in
`domain_relinquish_resources`. Note that domctl->u.shadow_op.mb is
updated with the new size when setting the p2m pool.

- For dom0less domUs, the setting of the p2m pool is called before
allocating memory during domain creation. Users can specify the p2m
pool size by `xen,domain-p2m-mem-mb` dts property.

To actually allocate/free pages from the p2m pool, this commit adds
two helper functions namely `p2m_alloc_page` and `p2m_free_page` to
`struct p2m_domain`. By replacing the `alloc_domheap_page` and
`free_domheap_page` with these two helper functions, p2m pages can
be added/removed from the list of p2m pool rather than from the heap.

Since page from `p2m_alloc_page` is cleaned, take the opportunity
to remove the redundant `clean_page` in `p2m_create_table`.

This is part of CVE-2022-33747 / XSA-409.

Signed-off-by: Henry Wang <Henry.Wang@arm.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
master commit: cbea5a1149
master date: 2022-10-11 14:28:44 +0200
2022-10-11 14:55:53 +02:00

360 lines
11 KiB
Plaintext

Dom0 kernel and ramdisk modules
================================
Xen is passed the dom0 kernel and initrd via a reference in the /chosen
node of the device tree.
Each node contains the following properties:
- compatible
Must always include at least the generic compatiblity string:
"multiboot,module"
Optionally a more specific compatible string may be used in
addition to the above. One of:
- "multiboot,kernel" -- the dom0 kernel
- "multiboot,ramdisk" -- the dom0 ramdisk
- "xen,xsm-policy" -- XSM policy blob
It is normally recommended to include a more specific
compatible string (if one applies) in addition to the generic
string (which must always be present).
Xen will assume that the first module which lacks a more
specific compatible string is a "multiboot,kernel".
Xen will examine each module, starting from the second
module that lacks a specific compatible string. Xen will
check each such module for the XSM Magic number:
- For a module which has the XSM Magic number: it will be
treated by Xen as if its compatible string was
"xen,xsm-policy";
- For a module which does not have the XSM Magic: the second
module lacking a compatible string will be treated by Xen as
if its compatible string was "multiboot,ramdisk"; for the
third and subsequent modules which lack a specific
compatible string, Xen will not apply any special treatment.
This means if the ramdisk module is present and does not have the
compatible string "multiboot,ramdisk", then it must always be the
second module.
Note: This XSM Magic detection behavior was introduced by Xen 4.7.
Xen 4.6 (and downwards) still requires the XSM module to have the
compatible string "xen,xsm-policy".
Xen 4.4 supported a different set of legacy compatible strings
which remain supported such that systems supporting both 4.4
and later can use a single DTB.
However when booting Xen using UEFI, the legacy compatible
strings are not supported.
- "xen,multiboot-module" equivalent to "multiboot,module"
- "xen,linux-zimage" equivalent to "multiboot,kernel"
- "xen,linux-initrd" equivalent to "multiboot,ramdisk"
For compatibility with Xen 4.4 the more specific "xen,linux-*"
names are non-optional and must be included.
- reg
Specifies the physical address of the module in RAM and the
length of the module.
- bootargs (optional)
Command line associated with this module. See below for the
priority of this field vs. other mechanisms of specifying the
bootargs for the kernel.
- xen,uefi-binary (UEFI boot only)
String property that specifies the file name to be loaded by the UEFI
boot for this module. If this is specified, there is no need to specify
the reg property because it will be created by the UEFI stub on boot.
This option is needed only when UEFI boot is used, the node needs to be
compatible with multiboot,kernel or multiboot,ramdisk.
Examples
========
A boot module of unspecified type:
module@0xc0000000 {
compatible = "multiboot,module";
reg = <0xc0000000 0x1234>;
bootargs = "...";
};
A boot module containing a ramdisk:
module@0xd0000000 {
compatible = "multiboot,ramdisk", "multiboot,module";
reg = <0xd0000000 0x5678>;
};
The previous examples are compatible with Xen 4.5+ only.
To be compatible with Xen 4.4 as well use the legacy names:
module@0xd0000000 {
compatible = "xen,linux-initrd", "xen,multiboot-module";
reg = <0xd0000000 0x5678>;
};
Command lines
=============
Xen also checks for properties directly under /chosen to find suitable command
lines for Xen and Dom0. The logic is the following:
- If xen,xen-bootargs is present, it will be used for Xen.
- If xen,dom0-bootargs is present, it will be used for Dom0.
- If xen,xen-bootargs is _not_ present, but xen,dom0-bootargs is,
bootargs will be used for Xen.
- If a kernel boot module is present and has a bootargs property then
the top-level bootargs will used for Xen.
- If no Xen specific properties are present, bootargs is for Dom0.
- If xen,xen-bootargs is present, but xen,dom0-bootargs is missing,
bootargs will be used for Dom0.
Most of these cases is to make booting with Xen-unaware bootloaders easier.
For those you would hardcode the Xen commandline in the DTB under
/chosen/xen,xen-bootargs and would let the bootloader set the Dom0 command
line by writing bootargs (as for native Linux).
A Xen-aware bootloader would set xen,xen-bootargs for Xen, xen,dom0-bootargs
for Dom0 and bootargs for native Linux.
UEFI boot and DT
================
When Xen is booted using UEFI, it doesn't read the configuration file if any
multiboot module is specified. To force Xen to load the configuration file, the
boolean property xen,uefi-cfg-load must be declared in the /chosen node.
Creating Multiple Domains directly from Xen
===========================================
It is possible to have Xen create other domains, in addition to dom0,
out of the information provided via device tree. A kernel and initrd
(optional) need to be specified for each guest.
For each domain to be created there needs to be one node under /chosen
with the following properties:
- compatible
For domUs: "xen,domain"
- memory
A 64-bit integer specifying the amount of kilobytes of RAM to
allocate to the guest.
- cpus
An integer specifying the number of vcpus to allocate to the guest.
- vpl011
An empty property to enable/disable a virtual pl011 for the guest to
use. The virtual pl011 uses SPI number 0 (see GUEST_VPL011_SPI).
Please note that the SPI used for the virtual pl011 could clash with the
physical SPI of a physical device assigned to the guest.
- nr_spis
Optional. A 32-bit integer specifying the number of SPIs (Shared
Peripheral Interrupts) to allocate for the domain. If nr_spis is
missing, the max number of SPIs supported by the physical GIC is
used, or GUEST_VPL011_SPI+1 if vpl011 is enabled, whichever is
greater.
- #address-cells and #size-cells
Both #address-cells and #size-cells need to be specified because
both sub-nodes (described shortly) have reg properties.
- xen,domain-p2m-mem-mb
Optional. A 32-bit integer specifying the amount of megabytes of RAM
used for the domain P2M pool. This is in-sync with the shadow_memory
option in xl.cfg. Leaving this field empty in device tree will lead to
the default size of domain P2M pool, i.e. 1MB per guest vCPU plus 4KB
per MB of guest RAM plus 512KB for guest extended regions.
Under the "xen,domain" compatible node, one or more sub-nodes are present
for the DomU kernel and ramdisk.
The kernel sub-node has the following properties:
- compatible
"multiboot,kernel", "multiboot,module"
- reg
Specifies the physical address of the kernel in RAM and its
length.
- bootargs (optional)
Command line parameters for the guest kernel.
- xen,uefi-binary (UEFI boot only)
String property that specifies the file name to be loaded by the UEFI boot
for this module. If this is specified, there is no need to specify the reg
property because it will be created by the UEFI stub on boot.
This option is needed only when UEFI boot is used.
The ramdisk sub-node has the following properties:
- compatible
"multiboot,ramdisk", "multiboot,module"
- reg
Specifies the physical address of the ramdisk in RAM and its
length.
- xen,uefi-binary (UEFI boot only)
String property that specifies the file name to be loaded by the UEFI boot
for this module. If this is specified, there is no need to specify the reg
property because it will be created by the UEFI stub on boot.
This option is needed only when UEFI boot is used.
Example
=======
chosen {
domU1 {
compatible = "xen,domain";
#address-cells = <0x2>;
#size-cells = <0x1>;
memory = <0 131072>;
cpus = <2>;
vpl011;
module@0x4a000000 {
compatible = "multiboot,kernel", "multiboot,module";
reg = <0x0 0x4a000000 0xffffff>;
bootargs = "console=ttyAMA0 init=/bin/sh";
};
module@0x4b000000 {
compatible = "multiboot,ramdisk", "multiboot,module";
reg = <0x0 0x4b000000 0xffffff>;
};
};
domU2 {
compatible = "xen,domain";
#address-cells = <0x2>;
#size-cells = <0x1>;
memory = <0 65536>;
cpus = <1>;
module@0x4c000000 {
compatible = "multiboot,kernel", "multiboot,module";
reg = <0x0 0x4c000000 0xffffff>;
bootargs = "console=ttyAMA0 init=/bin/sh";
};
module@0x4d000000 {
compatible = "multiboot,ramdisk", "multiboot,module";
reg = <0x0 0x4d000000 0xffffff>;
};
};
};
Device Assignment
=================
Device Assignment (Passthrough) is supported by adding another module,
alongside the kernel and ramdisk, with the device tree fragment
corresponding to the device node to assign to the guest.
The dtb sub-node should have the following properties:
- compatible
"multiboot,device-tree" and "multiboot,module"
- reg
Specifies the physical address of the device tree binary fragment
RAM and its length.
- xen,uefi-binary (UEFI boot only)
String property that specifies the file name to be loaded by the UEFI boot
for this module. If this is specified, there is no need to specify the reg
property because it will be created by the UEFI stub on boot.
This option is needed only when UEFI boot is used.
As an example:
module@0xc000000 {
compatible = "multiboot,device-tree", "multiboot,module";
reg = <0x0 0xc000000 0xffffff>;
};
The DTB fragment is loaded at 0xc000000 in the example above. It should
follow the convention explained in docs/misc/arm/passthrough.txt. The
DTB fragment will be added to the guest device tree, so that the guest
kernel will be able to discover the device.
Static Allocation
=============
Static Allocation refers to system or sub-system(domains) for which memory
areas are pre-defined by configuration using physical address ranges.
Memory can be statically allocated to a domain using the property "xen,static-
mem" defined in the domain configuration. The number of cells for the address
and the size must be defined using respectively the properties
"#xen,static-mem-address-cells" and "#xen,static-mem-size-cells".
The property 'memory' is still needed and should match the amount of memory
given to the guest. Currently, it either comes from static memory or lets Xen
allocate from heap. *Mixing* is not supported.
The static memory will be mapped in the guest at the usual guest memory
addresses (GUEST_RAM0_BASE, GUEST_RAM1_BASE) defined by
xen/include/public/arch-arm.h.
Below is an example on how to specify the static memory region in the
device-tree:
/ {
chosen {
domU1 {
compatible = "xen,domain";
#address-cells = <0x2>;
#size-cells = <0x2>;
cpus = <2>;
memory = <0x0 0x80000>;
#xen,static-mem-address-cells = <0x1>;
#xen,static-mem-size-cells = <0x1>;
xen,static-mem = <0x30000000 0x20000000>;
...
};
};
};
This will reserve a 512MB region starting at the host physical address
0x30000000 to be exclusively used by DomU1.