forked from Minki/linux
ARM: XEN: Move xen_early_init() before efi_init()
Move xen_early_init() before efi_init(), then when calling efi_init() could initialize Xen specific UEFI. Check if it runs on Xen hypervisor through the flat dts. Cc: Russell King <linux@arm.linux.org.uk> Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org> Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Reviewed-by: Julien Grall <julien.grall@arm.com> Tested-by: Julien Grall <julien.grall@arm.com> Acked-by: Catalin Marinas <catalin.marinas@arm.com>
This commit is contained in:
parent
d22cbe651f
commit
9b08aaa319
@ -1064,6 +1064,7 @@ void __init setup_arch(char **cmdline_p)
|
|||||||
early_paging_init(mdesc);
|
early_paging_init(mdesc);
|
||||||
#endif
|
#endif
|
||||||
setup_dma_zone(mdesc);
|
setup_dma_zone(mdesc);
|
||||||
|
xen_early_init();
|
||||||
efi_init();
|
efi_init();
|
||||||
sanity_check_meminfo();
|
sanity_check_meminfo();
|
||||||
arm_memblock_init(mdesc);
|
arm_memblock_init(mdesc);
|
||||||
@ -1080,7 +1081,6 @@ void __init setup_arch(char **cmdline_p)
|
|||||||
|
|
||||||
arm_dt_init_cpu_maps();
|
arm_dt_init_cpu_maps();
|
||||||
psci_dt_init();
|
psci_dt_init();
|
||||||
xen_early_init();
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
if (is_smp()) {
|
if (is_smp()) {
|
||||||
if (!mdesc->smp_init || !mdesc->smp_init()) {
|
if (!mdesc->smp_init || !mdesc->smp_init()) {
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include <linux/irqreturn.h>
|
#include <linux/irqreturn.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
|
#include <linux/of_fdt.h>
|
||||||
#include <linux/of_irq.h>
|
#include <linux/of_irq.h>
|
||||||
#include <linux/of_address.h>
|
#include <linux/of_address.h>
|
||||||
#include <linux/cpuidle.h>
|
#include <linux/cpuidle.h>
|
||||||
@ -53,8 +54,6 @@ struct xen_memory_region xen_extra_mem[XEN_EXTRA_MEM_MAX_REGIONS] __initdata;
|
|||||||
|
|
||||||
static __read_mostly unsigned int xen_events_irq;
|
static __read_mostly unsigned int xen_events_irq;
|
||||||
|
|
||||||
static __initdata struct device_node *xen_node;
|
|
||||||
|
|
||||||
int xen_remap_domain_gfn_array(struct vm_area_struct *vma,
|
int xen_remap_domain_gfn_array(struct vm_area_struct *vma,
|
||||||
unsigned long addr,
|
unsigned long addr,
|
||||||
xen_pfn_t *gfn, int nr,
|
xen_pfn_t *gfn, int nr,
|
||||||
@ -238,6 +237,33 @@ static irqreturn_t xen_arm_callback(int irq, void *arg)
|
|||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static __initdata struct {
|
||||||
|
const char *compat;
|
||||||
|
const char *prefix;
|
||||||
|
const char *version;
|
||||||
|
bool found;
|
||||||
|
} hyper_node = {"xen,xen", "xen,xen-", NULL, false};
|
||||||
|
|
||||||
|
static int __init fdt_find_hyper_node(unsigned long node, const char *uname,
|
||||||
|
int depth, void *data)
|
||||||
|
{
|
||||||
|
const void *s = NULL;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (depth != 1 || strcmp(uname, "hypervisor") != 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (of_flat_dt_is_compatible(node, hyper_node.compat))
|
||||||
|
hyper_node.found = true;
|
||||||
|
|
||||||
|
s = of_get_flat_dt_prop(node, "compatible", &len);
|
||||||
|
if (strlen(hyper_node.prefix) + 3 < len &&
|
||||||
|
!strncmp(hyper_node.prefix, s, strlen(hyper_node.prefix)))
|
||||||
|
hyper_node.version = s + strlen(hyper_node.prefix);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* see Documentation/devicetree/bindings/arm/xen.txt for the
|
* see Documentation/devicetree/bindings/arm/xen.txt for the
|
||||||
* documentation of the Xen Device Tree format.
|
* documentation of the Xen Device Tree format.
|
||||||
@ -245,26 +271,18 @@ static irqreturn_t xen_arm_callback(int irq, void *arg)
|
|||||||
#define GRANT_TABLE_PHYSADDR 0
|
#define GRANT_TABLE_PHYSADDR 0
|
||||||
void __init xen_early_init(void)
|
void __init xen_early_init(void)
|
||||||
{
|
{
|
||||||
int len;
|
of_scan_flat_dt(fdt_find_hyper_node, NULL);
|
||||||
const char *s = NULL;
|
if (!hyper_node.found) {
|
||||||
const char *version = NULL;
|
|
||||||
const char *xen_prefix = "xen,xen-";
|
|
||||||
|
|
||||||
xen_node = of_find_compatible_node(NULL, NULL, "xen,xen");
|
|
||||||
if (!xen_node) {
|
|
||||||
pr_debug("No Xen support\n");
|
pr_debug("No Xen support\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
s = of_get_property(xen_node, "compatible", &len);
|
|
||||||
if (strlen(xen_prefix) + 3 < len &&
|
if (hyper_node.version == NULL) {
|
||||||
!strncmp(xen_prefix, s, strlen(xen_prefix)))
|
|
||||||
version = s + strlen(xen_prefix);
|
|
||||||
if (version == NULL) {
|
|
||||||
pr_debug("Xen version not found\n");
|
pr_debug("Xen version not found\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pr_info("Xen %s support found\n", version);
|
pr_info("Xen %s support found\n", hyper_node.version);
|
||||||
|
|
||||||
xen_domain_type = XEN_HVM_DOMAIN;
|
xen_domain_type = XEN_HVM_DOMAIN;
|
||||||
|
|
||||||
@ -305,6 +323,14 @@ static void __init xen_acpi_guest_init(void)
|
|||||||
|
|
||||||
static void __init xen_dt_guest_init(void)
|
static void __init xen_dt_guest_init(void)
|
||||||
{
|
{
|
||||||
|
struct device_node *xen_node;
|
||||||
|
|
||||||
|
xen_node = of_find_compatible_node(NULL, NULL, "xen,xen");
|
||||||
|
if (!xen_node) {
|
||||||
|
pr_err("Xen support was detected before, but it has disappeared\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
xen_events_irq = irq_of_parse_and_map(xen_node, 0);
|
xen_events_irq = irq_of_parse_and_map(xen_node, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,6 +257,7 @@ void __init setup_arch(char **cmdline_p)
|
|||||||
*/
|
*/
|
||||||
cpu_uninstall_idmap();
|
cpu_uninstall_idmap();
|
||||||
|
|
||||||
|
xen_early_init();
|
||||||
efi_init();
|
efi_init();
|
||||||
arm64_memblock_init();
|
arm64_memblock_init();
|
||||||
|
|
||||||
@ -281,8 +282,6 @@ void __init setup_arch(char **cmdline_p)
|
|||||||
else
|
else
|
||||||
psci_acpi_init();
|
psci_acpi_init();
|
||||||
|
|
||||||
xen_early_init();
|
|
||||||
|
|
||||||
cpu_read_bootcpu_ops();
|
cpu_read_bootcpu_ops();
|
||||||
smp_init_cpus();
|
smp_init_cpus();
|
||||||
smp_build_mpidr_hash();
|
smp_build_mpidr_hash();
|
||||||
|
Loading…
Reference in New Issue
Block a user