Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1349886 > unrolled thread
| Started by | Shannon Zhao <zhaoshenglong@huawei.com> |
|---|---|
| First post | 2016-03-04 07:50 +0100 |
| Last post | 2016-03-04 07:50 +0100 |
| Articles | 12 — 2 participants |
Back to article view | Back to linux.kernel
[PATCH v5 00/17] Add ACPI support for Xen Dom0 on ARM64 Shannon Zhao <zhaoshenglong@huawei.com> - 2016-03-04 07:50 +0100
[PATCH v5 14/17] XEN: EFI: Move x86 specific codes to architecture directory Shannon Zhao <zhaoshenglong@huawei.com> - 2016-03-04 07:50 +0100
[PATCH v5 03/17] Xen: xlate: Use page_to_xen_pfn instead of page_to_pfn Shannon Zhao <zhaoshenglong@huawei.com> - 2016-03-04 07:50 +0100
[PATCH v5 08/17] Xen: public/hvm: sync changes of HVM_PARAM_CALLBACK_VIA ABI from Xen Shannon Zhao <zhaoshenglong@huawei.com> - 2016-03-04 07:50 +0100
[PATCH v5 13/17] ARM: Xen: Document UEFI support on Xen ARM virtual platforms Shannon Zhao <zhaoshenglong@huawei.com> - 2016-03-04 07:50 +0100
[PATCH v5 11/17] ARM: XEN: Move xen_early_init() before efi_init() Shannon Zhao <zhaoshenglong@huawei.com> - 2016-03-04 07:50 +0100
[PATCH v5 17/17] Xen: EFI: Parse DT parameters for Xen specific UEFI Shannon Zhao <zhaoshenglong@huawei.com> - 2016-03-04 07:50 +0100
[PATCH v5 15/17] ARM64: XEN: Add a function to initialize Xen specific UEFI runtime services Shannon Zhao <zhaoshenglong@huawei.com> - 2016-03-04 07:50 +0100
[PATCH v5 07/17] Xen: ARM: Add support for mapping AMBA device mmio Shannon Zhao <zhaoshenglong@huawei.com> - 2016-03-04 07:50 +0100
[PATCH v5 16/17] FDT: Add a helper to get the subnode by given name Shannon Zhao <zhaoshenglong@huawei.com> - 2016-03-04 07:50 +0100
Re: [PATCH v5 16/17] FDT: Add a helper to get the subnode by given name Stefano Stabellini <stefano.stabellini@eu.citrix.com> - 2016-03-04 13:30 +0100
[PATCH v5 10/17] arm/xen: Get event-channel irq through HVM_PARAM when booting with ACPI Shannon Zhao <zhaoshenglong@huawei.com> - 2016-03-04 07:50 +0100
| From | Shannon Zhao <zhaoshenglong@huawei.com> |
|---|---|
| Date | 2016-03-04 07:50 +0100 |
| Subject | [PATCH v5 00/17] Add ACPI support for Xen Dom0 on ARM64 |
| Message-ID | <r8Rz3-2wY-3@gated-at.bofh.it> |
From: Shannon Zhao <shannon.zhao@linaro.org>
This patch set adds ACPI support for Xen Dom0 on ARM64. The relevant Xen
ACPI on ARM64 design document could be found from [1].
This patch set adds a new FDT node "uefi" under /hypervisor to pass UEFI
information. Introduce a bus notifier of AMBA and Platform bus to map
the new added device's MMIO space. Make Xen domain use
xlated_setup_gnttab_pages to setup grant table and a new hypercall to
get event-channel irq.
Regarding the initialization flow of Linux kernel, it needs to move
xen_early_init() before efi_init(). Then xen_early_init() will check
whether it runs on Xen through the /hypervisor node and efi_init() will
call a new function fdt_find_xen_uefi_params(), to parse those
xen,uefi-* parameters just like the existing efi_get_fdt_params().
And in arm64_enable_runtime_services() it will check whether it runs on
Xen and call another new function xen_efi_runtime_setup() to setup
runtime service instead of efi_native_runtime_setup(). The
xen_efi_runtime_setup() will assign the runtime function pointers with
the functions of driver/xen/efi.c.
And since we pass a /hypervisor node and a /chosen node to Dom0, it
needs to check whether the DTS only contains a /hypervisor node and a
/chosen node in acpi_boot_table_init().
Patches are tested on FVP base model.
Thanks,
Shannon
[1] http://lists.xen.org/archives/html/xen-devel/2015-11/msg00488.html
Changes since v4:
* rebase on linux master
* move the check acpi_device_should_be_hidden into
acpi_bus_type_and_status (patch 1)
* use existing function fdt_subnode_offset (patch 16)
Changes since v3:
* rebase on linux master
* print a warning when there is no SPCR table
* rephase the commit message of PATCH 3
* rephase the words of PATCH 13
* use strcmp and factor the function in PATCH 16
* Add several ACKs and RBs, thanks a lot
Changes since v2:
* Use 0 to check if it should ignore the UART
* Fix the use of page_to_xen_pfn
* Factor ACPI and DT parts in xen_guest_init
* Check "uefi" node by full path
* Fix the statement of Documentation/devicetree/bindings/arm/xen.txt
Changes since v1:
* Rebase on linux mainline and wallclock patch from Stefano
* Refactor AMBA and platform device MMIO map to one file
* Use EFI_PARAVIRT to check if it supports XEN EFI
* Refactor Xen EFI codes
* Address other comments
Shannon Zhao (17):
Xen: ACPI: Hide UART used by Xen
xen/grant-table: Move xlated_setup_gnttab_pages to common place
Xen: xlate: Use page_to_xen_pfn instead of page_to_pfn
arm/xen: Use xen_xlate_map_ballooned_pages to setup grant table
xen: memory : Add new XENMAPSPACE type XENMAPSPACE_dev_mmio
Xen: ARM: Add support for mapping platform device mmio
Xen: ARM: Add support for mapping AMBA device mmio
Xen: public/hvm: sync changes of HVM_PARAM_CALLBACK_VIA ABI from Xen
xen/hvm/params: Add a new delivery type for event-channel in
HVM_PARAM_CALLBACK_IRQ
arm/xen: Get event-channel irq through HVM_PARAM when booting with
ACPI
ARM: XEN: Move xen_early_init() before efi_init()
ARM64: ACPI: Check if it runs on Xen to enable or disable ACPI
ARM: Xen: Document UEFI support on Xen ARM virtual platforms
XEN: EFI: Move x86 specific codes to architecture directory
ARM64: XEN: Add a function to initialize Xen specific UEFI runtime
services
FDT: Add a helper to get the subnode by given name
Xen: EFI: Parse DT parameters for Xen specific UEFI
Documentation/devicetree/bindings/arm/xen.txt | 33 +++++
arch/arm/include/asm/xen/xen-ops.h | 6 +
arch/arm/xen/Makefile | 1 +
arch/arm/xen/efi.c | 40 ++++++
arch/arm/xen/enlighten.c | 109 +++++++++++----
arch/arm64/include/asm/xen/xen-ops.h | 6 +
arch/arm64/kernel/acpi.c | 12 +-
arch/arm64/kernel/setup.c | 2 +-
arch/arm64/xen/Makefile | 1 +
arch/x86/xen/efi.c | 112 ++++++++++++++++
arch/x86/xen/grant-table.c | 57 +-------
drivers/acpi/scan.c | 68 ++++++++++
drivers/firmware/efi/arm-runtime.c | 17 ++-
drivers/firmware/efi/efi.c | 45 ++++++-
drivers/of/fdt.c | 13 ++
drivers/xen/Kconfig | 2 +-
drivers/xen/Makefile | 1 +
drivers/xen/arm-device.c | 184 ++++++++++++++++++++++++++
drivers/xen/efi.c | 174 +++++-------------------
drivers/xen/xlate_mmu.c | 67 ++++++++++
include/linux/of_fdt.h | 2 +
include/xen/interface/hvm/params.h | 37 +++++-
include/xen/interface/memory.h | 1 +
include/xen/xen-ops.h | 32 +++--
24 files changed, 775 insertions(+), 247 deletions(-)
create mode 100644 arch/arm/include/asm/xen/xen-ops.h
create mode 100644 arch/arm/xen/efi.c
create mode 100644 arch/arm64/include/asm/xen/xen-ops.h
create mode 100644 drivers/xen/arm-device.c
--
2.0.4
[toc] | [next] | [standalone]
| From | Shannon Zhao <zhaoshenglong@huawei.com> |
|---|---|
| Date | 2016-03-04 07:50 +0100 |
| Subject | [PATCH v5 14/17] XEN: EFI: Move x86 specific codes to architecture directory |
| Message-ID | <r8RIJ-2AC-3@gated-at.bofh.it> |
| In reply to | #1349886 |
From: Shannon Zhao <shannon.zhao@linaro.org>
Move x86 specific codes to architecture directory and export those EFI
runtime service functions. This will be useful for initializing runtime
service on ARM later.
Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
arch/x86/xen/efi.c | 112 ++++++++++++++++++++++++++++++++
drivers/xen/efi.c | 174 ++++++++++----------------------------------------
include/xen/xen-ops.h | 30 ++++++---
3 files changed, 168 insertions(+), 148 deletions(-)
diff --git a/arch/x86/xen/efi.c b/arch/x86/xen/efi.c
index be14cc3..86527f1 100644
--- a/arch/x86/xen/efi.c
+++ b/arch/x86/xen/efi.c
@@ -20,10 +20,122 @@
#include <linux/init.h>
#include <linux/string.h>
+#include <xen/xen.h>
#include <xen/xen-ops.h>
+#include <xen/interface/platform.h>
#include <asm/page.h>
#include <asm/setup.h>
+#include <asm/xen/hypercall.h>
+
+static efi_char16_t vendor[100] __initdata;
+
+static efi_system_table_t efi_systab_xen __initdata = {
+ .hdr = {
+ .signature = EFI_SYSTEM_TABLE_SIGNATURE,
+ .revision = 0, /* Initialized later. */
+ .headersize = 0, /* Ignored by Linux Kernel. */
+ .crc32 = 0, /* Ignored by Linux Kernel. */
+ .reserved = 0
+ },
+ .fw_vendor = EFI_INVALID_TABLE_ADDR, /* Initialized later. */
+ .fw_revision = 0, /* Initialized later. */
+ .con_in_handle = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+ .con_in = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+ .con_out_handle = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+ .con_out = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+ .stderr_handle = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+ .stderr = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
+ .runtime = (efi_runtime_services_t *)EFI_INVALID_TABLE_ADDR,
+ /* Not used under Xen. */
+ .boottime = (efi_boot_services_t *)EFI_INVALID_TABLE_ADDR,
+ /* Not used under Xen. */
+ .nr_tables = 0, /* Initialized later. */
+ .tables = EFI_INVALID_TABLE_ADDR /* Initialized later. */
+};
+
+static const struct efi efi_xen __initconst = {
+ .systab = NULL, /* Initialized later. */
+ .runtime_version = 0, /* Initialized later. */
+ .mps = EFI_INVALID_TABLE_ADDR,
+ .acpi = EFI_INVALID_TABLE_ADDR,
+ .acpi20 = EFI_INVALID_TABLE_ADDR,
+ .smbios = EFI_INVALID_TABLE_ADDR,
+ .smbios3 = EFI_INVALID_TABLE_ADDR,
+ .sal_systab = EFI_INVALID_TABLE_ADDR,
+ .boot_info = EFI_INVALID_TABLE_ADDR,
+ .hcdp = EFI_INVALID_TABLE_ADDR,
+ .uga = EFI_INVALID_TABLE_ADDR,
+ .uv_systab = EFI_INVALID_TABLE_ADDR,
+ .fw_vendor = EFI_INVALID_TABLE_ADDR,
+ .runtime = EFI_INVALID_TABLE_ADDR,
+ .config_table = EFI_INVALID_TABLE_ADDR,
+ .get_time = xen_efi_get_time,
+ .set_time = xen_efi_set_time,
+ .get_wakeup_time = xen_efi_get_wakeup_time,
+ .set_wakeup_time = xen_efi_set_wakeup_time,
+ .get_variable = xen_efi_get_variable,
+ .get_next_variable = xen_efi_get_next_variable,
+ .set_variable = xen_efi_set_variable,
+ .query_variable_info = xen_efi_query_variable_info,
+ .update_capsule = xen_efi_update_capsule,
+ .query_capsule_caps = xen_efi_query_capsule_caps,
+ .get_next_high_mono_count = xen_efi_get_next_high_mono_count,
+ .reset_system = NULL, /* Functionality provided by Xen. */
+ .set_virtual_address_map = NULL, /* Not used under Xen. */
+ .memmap = NULL, /* Not used under Xen. */
+ .flags = 0 /* Initialized later. */
+};
+
+static efi_system_table_t __init *xen_efi_probe(void)
+{
+ struct xen_platform_op op = {
+ .cmd = XENPF_firmware_info,
+ .u.firmware_info = {
+ .type = XEN_FW_EFI_INFO,
+ .index = XEN_FW_EFI_CONFIG_TABLE
+ }
+ };
+ union xenpf_efi_info *info = &op.u.firmware_info.u.efi_info;
+
+ if (!xen_initial_domain() || HYPERVISOR_platform_op(&op) < 0)
+ return NULL;
+
+ /* Here we know that Xen runs on EFI platform. */
+
+ efi = efi_xen;
+
+ efi_systab_xen.tables = info->cfg.addr;
+ efi_systab_xen.nr_tables = info->cfg.nent;
+
+ op.cmd = XENPF_firmware_info;
+ op.u.firmware_info.type = XEN_FW_EFI_INFO;
+ op.u.firmware_info.index = XEN_FW_EFI_VENDOR;
+ info->vendor.bufsz = sizeof(vendor);
+ set_xen_guest_handle(info->vendor.name, vendor);
+
+ if (HYPERVISOR_platform_op(&op) == 0) {
+ efi_systab_xen.fw_vendor = __pa_symbol(vendor);
+ efi_systab_xen.fw_revision = info->vendor.revision;
+ } else
+ efi_systab_xen.fw_vendor = __pa_symbol(L"UNKNOWN");
+
+ op.cmd = XENPF_firmware_info;
+ op.u.firmware_info.type = XEN_FW_EFI_INFO;
+ op.u.firmware_info.index = XEN_FW_EFI_VERSION;
+
+ if (HYPERVISOR_platform_op(&op) == 0)
+ efi_systab_xen.hdr.revision = info->version;
+
+ op.cmd = XENPF_firmware_info;
+ op.u.firmware_info.type = XEN_FW_EFI_INFO;
+ op.u.firmware_info.index = XEN_FW_EFI_RT_VERSION;
+
+ if (HYPERVISOR_platform_op(&op) == 0)
+ efi.runtime_version = info->version;
+
+ return &efi_systab_xen;
+}
void __init xen_efi_init(void)
{
diff --git a/drivers/xen/efi.c b/drivers/xen/efi.c
index be7e56a..22f71ff 100644
--- a/drivers/xen/efi.c
+++ b/drivers/xen/efi.c
@@ -38,7 +38,7 @@
#define efi_data(op) (op.u.efi_runtime_call)
-static efi_status_t xen_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
+efi_status_t xen_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
{
struct xen_platform_op op = INIT_EFI_OP(get_time);
@@ -59,8 +59,9 @@ static efi_status_t xen_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
return efi_data(op).status;
}
+EXPORT_SYMBOL_GPL(xen_efi_get_time);
-static efi_status_t xen_efi_set_time(efi_time_t *tm)
+efi_status_t xen_efi_set_time(efi_time_t *tm)
{
struct xen_platform_op op = INIT_EFI_OP(set_time);
@@ -72,10 +73,10 @@ static efi_status_t xen_efi_set_time(efi_time_t *tm)
return efi_data(op).status;
}
+EXPORT_SYMBOL_GPL(xen_efi_set_time);
-static efi_status_t xen_efi_get_wakeup_time(efi_bool_t *enabled,
- efi_bool_t *pending,
- efi_time_t *tm)
+efi_status_t xen_efi_get_wakeup_time(efi_bool_t *enabled, efi_bool_t *pending,
+ efi_time_t *tm)
{
struct xen_platform_op op = INIT_EFI_OP(get_wakeup_time);
@@ -95,8 +96,9 @@ static efi_status_t xen_efi_get_wakeup_time(efi_bool_t *enabled,
return efi_data(op).status;
}
+EXPORT_SYMBOL_GPL(xen_efi_get_wakeup_time);
-static efi_status_t xen_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
+efi_status_t xen_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
{
struct xen_platform_op op = INIT_EFI_OP(set_wakeup_time);
@@ -113,12 +115,11 @@ static efi_status_t xen_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
return efi_data(op).status;
}
+EXPORT_SYMBOL_GPL(xen_efi_set_wakeup_time);
-static efi_status_t xen_efi_get_variable(efi_char16_t *name,
- efi_guid_t *vendor,
- u32 *attr,
- unsigned long *data_size,
- void *data)
+efi_status_t xen_efi_get_variable(efi_char16_t *name, efi_guid_t *vendor,
+ u32 *attr, unsigned long *data_size,
+ void *data)
{
struct xen_platform_op op = INIT_EFI_OP(get_variable);
@@ -138,10 +139,11 @@ static efi_status_t xen_efi_get_variable(efi_char16_t *name,
return efi_data(op).status;
}
+EXPORT_SYMBOL_GPL(xen_efi_get_variable);
-static efi_status_t xen_efi_get_next_variable(unsigned long *name_size,
- efi_char16_t *name,
- efi_guid_t *vendor)
+efi_status_t xen_efi_get_next_variable(unsigned long *name_size,
+ efi_char16_t *name,
+ efi_guid_t *vendor)
{
struct xen_platform_op op = INIT_EFI_OP(get_next_variable_name);
@@ -161,12 +163,11 @@ static efi_status_t xen_efi_get_next_variable(unsigned long *name_size,
return efi_data(op).status;
}
+EXPORT_SYMBOL_GPL(xen_efi_get_next_variable);
-static efi_status_t xen_efi_set_variable(efi_char16_t *name,
- efi_guid_t *vendor,
- u32 attr,
- unsigned long data_size,
- void *data)
+efi_status_t xen_efi_set_variable(efi_char16_t *name, efi_guid_t *vendor,
+ u32 attr, unsigned long data_size,
+ void *data)
{
struct xen_platform_op op = INIT_EFI_OP(set_variable);
@@ -183,11 +184,11 @@ static efi_status_t xen_efi_set_variable(efi_char16_t *name,
return efi_data(op).status;
}
+EXPORT_SYMBOL_GPL(xen_efi_set_variable);
-static efi_status_t xen_efi_query_variable_info(u32 attr,
- u64 *storage_space,
- u64 *remaining_space,
- u64 *max_variable_size)
+efi_status_t xen_efi_query_variable_info(u32 attr, u64 *storage_space,
+ u64 *remaining_space,
+ u64 *max_variable_size)
{
struct xen_platform_op op = INIT_EFI_OP(query_variable_info);
@@ -205,8 +206,9 @@ static efi_status_t xen_efi_query_variable_info(u32 attr,
return efi_data(op).status;
}
+EXPORT_SYMBOL_GPL(xen_efi_query_variable_info);
-static efi_status_t xen_efi_get_next_high_mono_count(u32 *count)
+efi_status_t xen_efi_get_next_high_mono_count(u32 *count)
{
struct xen_platform_op op = INIT_EFI_OP(get_next_high_monotonic_count);
@@ -217,10 +219,10 @@ static efi_status_t xen_efi_get_next_high_mono_count(u32 *count)
return efi_data(op).status;
}
+EXPORT_SYMBOL_GPL(xen_efi_get_next_high_mono_count);
-static efi_status_t xen_efi_update_capsule(efi_capsule_header_t **capsules,
- unsigned long count,
- unsigned long sg_list)
+efi_status_t xen_efi_update_capsule(efi_capsule_header_t **capsules,
+ unsigned long count, unsigned long sg_list)
{
struct xen_platform_op op = INIT_EFI_OP(update_capsule);
@@ -237,11 +239,11 @@ static efi_status_t xen_efi_update_capsule(efi_capsule_header_t **capsules,
return efi_data(op).status;
}
+EXPORT_SYMBOL_GPL(xen_efi_update_capsule);
-static efi_status_t xen_efi_query_capsule_caps(efi_capsule_header_t **capsules,
- unsigned long count,
- u64 *max_size,
- int *reset_type)
+efi_status_t xen_efi_query_capsule_caps(efi_capsule_header_t **capsules,
+ unsigned long count, u64 *max_size,
+ int *reset_type)
{
struct xen_platform_op op = INIT_EFI_OP(query_capsule_capabilities);
@@ -260,112 +262,4 @@ static efi_status_t xen_efi_query_capsule_caps(efi_capsule_header_t **capsules,
return efi_data(op).status;
}
-
-static efi_char16_t vendor[100] __initdata;
-
-static efi_system_table_t efi_systab_xen __initdata = {
- .hdr = {
- .signature = EFI_SYSTEM_TABLE_SIGNATURE,
- .revision = 0, /* Initialized later. */
- .headersize = 0, /* Ignored by Linux Kernel. */
- .crc32 = 0, /* Ignored by Linux Kernel. */
- .reserved = 0
- },
- .fw_vendor = EFI_INVALID_TABLE_ADDR, /* Initialized later. */
- .fw_revision = 0, /* Initialized later. */
- .con_in_handle = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
- .con_in = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
- .con_out_handle = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
- .con_out = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
- .stderr_handle = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
- .stderr = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
- .runtime = (efi_runtime_services_t *)EFI_INVALID_TABLE_ADDR,
- /* Not used under Xen. */
- .boottime = (efi_boot_services_t *)EFI_INVALID_TABLE_ADDR,
- /* Not used under Xen. */
- .nr_tables = 0, /* Initialized later. */
- .tables = EFI_INVALID_TABLE_ADDR /* Initialized later. */
-};
-
-static const struct efi efi_xen __initconst = {
- .systab = NULL, /* Initialized later. */
- .runtime_version = 0, /* Initialized later. */
- .mps = EFI_INVALID_TABLE_ADDR,
- .acpi = EFI_INVALID_TABLE_ADDR,
- .acpi20 = EFI_INVALID_TABLE_ADDR,
- .smbios = EFI_INVALID_TABLE_ADDR,
- .smbios3 = EFI_INVALID_TABLE_ADDR,
- .sal_systab = EFI_INVALID_TABLE_ADDR,
- .boot_info = EFI_INVALID_TABLE_ADDR,
- .hcdp = EFI_INVALID_TABLE_ADDR,
- .uga = EFI_INVALID_TABLE_ADDR,
- .uv_systab = EFI_INVALID_TABLE_ADDR,
- .fw_vendor = EFI_INVALID_TABLE_ADDR,
- .runtime = EFI_INVALID_TABLE_ADDR,
- .config_table = EFI_INVALID_TABLE_ADDR,
- .get_time = xen_efi_get_time,
- .set_time = xen_efi_set_time,
- .get_wakeup_time = xen_efi_get_wakeup_time,
- .set_wakeup_time = xen_efi_set_wakeup_time,
- .get_variable = xen_efi_get_variable,
- .get_next_variable = xen_efi_get_next_variable,
- .set_variable = xen_efi_set_variable,
- .query_variable_info = xen_efi_query_variable_info,
- .update_capsule = xen_efi_update_capsule,
- .query_capsule_caps = xen_efi_query_capsule_caps,
- .get_next_high_mono_count = xen_efi_get_next_high_mono_count,
- .reset_system = NULL, /* Functionality provided by Xen. */
- .set_virtual_address_map = NULL, /* Not used under Xen. */
- .memmap = NULL, /* Not used under Xen. */
- .flags = 0 /* Initialized later. */
-};
-
-efi_system_table_t __init *xen_efi_probe(void)
-{
- struct xen_platform_op op = {
- .cmd = XENPF_firmware_info,
- .u.firmware_info = {
- .type = XEN_FW_EFI_INFO,
- .index = XEN_FW_EFI_CONFIG_TABLE
- }
- };
- union xenpf_efi_info *info = &op.u.firmware_info.u.efi_info;
-
- if (!xen_initial_domain() || HYPERVISOR_platform_op(&op) < 0)
- return NULL;
-
- /* Here we know that Xen runs on EFI platform. */
-
- efi = efi_xen;
-
- efi_systab_xen.tables = info->cfg.addr;
- efi_systab_xen.nr_tables = info->cfg.nent;
-
- op.cmd = XENPF_firmware_info;
- op.u.firmware_info.type = XEN_FW_EFI_INFO;
- op.u.firmware_info.index = XEN_FW_EFI_VENDOR;
- info->vendor.bufsz = sizeof(vendor);
- set_xen_guest_handle(info->vendor.name, vendor);
-
- if (HYPERVISOR_platform_op(&op) == 0) {
- efi_systab_xen.fw_vendor = __pa_symbol(vendor);
- efi_systab_xen.fw_revision = info->vendor.revision;
- } else
- efi_systab_xen.fw_vendor = __pa_symbol(L"UNKNOWN");
-
- op.cmd = XENPF_firmware_info;
- op.u.firmware_info.type = XEN_FW_EFI_INFO;
- op.u.firmware_info.index = XEN_FW_EFI_VERSION;
-
- if (HYPERVISOR_platform_op(&op) == 0)
- efi_systab_xen.hdr.revision = info->version;
-
- op.cmd = XENPF_firmware_info;
- op.u.firmware_info.type = XEN_FW_EFI_INFO;
- op.u.firmware_info.index = XEN_FW_EFI_RT_VERSION;
-
- if (HYPERVISOR_platform_op(&op) == 0)
- efi.runtime_version = info->version;
-
- return &efi_systab_xen;
-}
+EXPORT_SYMBOL_GPL(xen_efi_query_capsule_caps);
diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h
index 072be1c..3491582 100644
--- a/include/xen/xen-ops.h
+++ b/include/xen/xen-ops.h
@@ -90,14 +90,28 @@ int xen_xlate_map_ballooned_pages(xen_pfn_t **pfns, void **vaddr,
bool xen_running_on_version_or_later(unsigned int major, unsigned int minor);
-#ifdef CONFIG_XEN_EFI
-extern efi_system_table_t *xen_efi_probe(void);
-#else
-static inline efi_system_table_t __init *xen_efi_probe(void)
-{
- return NULL;
-}
-#endif
+efi_status_t xen_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc);
+efi_status_t xen_efi_set_time(efi_time_t *tm);
+efi_status_t xen_efi_get_wakeup_time(efi_bool_t *enabled, efi_bool_t *pending,
+ efi_time_t *tm);
+efi_status_t xen_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm);
+efi_status_t xen_efi_get_variable(efi_char16_t *name, efi_guid_t *vendor,
+ u32 *attr, unsigned long *data_size,
+ void *data);
+efi_status_t xen_efi_get_next_variable(unsigned long *name_size,
+ efi_char16_t *name, efi_guid_t *vendor);
+efi_status_t xen_efi_set_variable(efi_char16_t *name, efi_guid_t *vendor,
+ u32 attr, unsigned long data_size,
+ void *data);
+efi_status_t xen_efi_query_variable_info(u32 attr, u64 *storage_space,
+ u64 *remaining_space,
+ u64 *max_variable_size);
+efi_status_t xen_efi_get_next_high_mono_count(u32 *count);
+efi_status_t xen_efi_update_capsule(efi_capsule_header_t **capsules,
+ unsigned long count, unsigned long sg_list);
+efi_status_t xen_efi_query_capsule_caps(efi_capsule_header_t **capsules,
+ unsigned long count, u64 *max_size,
+ int *reset_type);
#ifdef CONFIG_PREEMPT
--
2.0.4
[toc] | [prev] | [next] | [standalone]
| From | Shannon Zhao <zhaoshenglong@huawei.com> |
|---|---|
| Date | 2016-03-04 07:50 +0100 |
| Subject | [PATCH v5 03/17] Xen: xlate: Use page_to_xen_pfn instead of page_to_pfn |
| Message-ID | <r8RIJ-2AC-5@gated-at.bofh.it> |
| In reply to | #1349886 |
From: Shannon Zhao <shannon.zhao@linaro.org>
Make xen_xlate_map_ballooned_pages work with 64K pages. In that case
Kernel pages are 64K in size but Xen pages remain 4K in size. Xen pfns
refer to 4K pages.
Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
drivers/xen/xlate_mmu.c | 26 ++++++++++++++++----------
1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/drivers/xen/xlate_mmu.c b/drivers/xen/xlate_mmu.c
index 9692656..28f728b 100644
--- a/drivers/xen/xlate_mmu.c
+++ b/drivers/xen/xlate_mmu.c
@@ -207,9 +207,12 @@ int __init xen_xlate_map_ballooned_pages(xen_pfn_t **gfns, void **virt,
void *vaddr;
int rc;
unsigned int i;
+ unsigned long nr_pages;
+ xen_pfn_t xen_pfn = 0;
BUG_ON(nr_grant_frames == 0);
- pages = kcalloc(nr_grant_frames, sizeof(pages[0]), GFP_KERNEL);
+ nr_pages = DIV_ROUND_UP(nr_grant_frames, XEN_PFN_PER_PAGE);
+ pages = kcalloc(nr_pages, sizeof(pages[0]), GFP_KERNEL);
if (!pages)
return -ENOMEM;
@@ -218,22 +221,25 @@ int __init xen_xlate_map_ballooned_pages(xen_pfn_t **gfns, void **virt,
kfree(pages);
return -ENOMEM;
}
- rc = alloc_xenballooned_pages(nr_grant_frames, pages);
+ rc = alloc_xenballooned_pages(nr_pages, pages);
if (rc) {
- pr_warn("%s Couldn't balloon alloc %ld pfns rc:%d\n", __func__,
- nr_grant_frames, rc);
+ pr_warn("%s Couldn't balloon alloc %ld pages rc:%d\n", __func__,
+ nr_pages, rc);
kfree(pages);
kfree(pfns);
return rc;
}
- for (i = 0; i < nr_grant_frames; i++)
- pfns[i] = page_to_pfn(pages[i]);
+ for (i = 0; i < nr_grant_frames; i++) {
+ if ((i % XEN_PFN_PER_PAGE) == 0)
+ xen_pfn = page_to_xen_pfn(pages[i / XEN_PFN_PER_PAGE]);
+ pfns[i] = pfn_to_gfn(xen_pfn++);
+ }
- vaddr = vmap(pages, nr_grant_frames, 0, PAGE_KERNEL);
+ vaddr = vmap(pages, nr_pages, 0, PAGE_KERNEL);
if (!vaddr) {
- pr_warn("%s Couldn't map %ld pfns rc:%d\n", __func__,
- nr_grant_frames, rc);
- free_xenballooned_pages(nr_grant_frames, pages);
+ pr_warn("%s Couldn't map %ld pages rc:%d\n", __func__,
+ nr_pages, rc);
+ free_xenballooned_pages(nr_pages, pages);
kfree(pages);
kfree(pfns);
return -ENOMEM;
--
2.0.4
[toc] | [prev] | [next] | [standalone]
| From | Shannon Zhao <zhaoshenglong@huawei.com> |
|---|---|
| Date | 2016-03-04 07:50 +0100 |
| Subject | [PATCH v5 08/17] Xen: public/hvm: sync changes of HVM_PARAM_CALLBACK_VIA ABI from Xen |
| Message-ID | <r8RIK-2AC-7@gated-at.bofh.it> |
| In reply to | #1349886 |
From: Shannon Zhao <shannon.zhao@linaro.org>
Sync the changes of HVM_PARAM_CALLBACK_VIA ABI introduced by
Xen commit <ca5c54b6ff05> (public/hvm: export the HVM_PARAM_CALLBACK_VIA
ABI in the API).
Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
include/xen/interface/hvm/params.h | 27 +++++++++++++++++++++------
1 file changed, 21 insertions(+), 6 deletions(-)
diff --git a/include/xen/interface/hvm/params.h b/include/xen/interface/hvm/params.h
index a6c7991..70ad208 100644
--- a/include/xen/interface/hvm/params.h
+++ b/include/xen/interface/hvm/params.h
@@ -27,16 +27,31 @@
* Parameter space for HVMOP_{set,get}_param.
*/
+#define HVM_PARAM_CALLBACK_IRQ 0
/*
* How should CPU0 event-channel notifications be delivered?
- * val[63:56] == 0: val[55:0] is a delivery GSI (Global System Interrupt).
- * val[63:56] == 1: val[55:0] is a delivery PCI INTx line, as follows:
- * Domain = val[47:32], Bus = val[31:16],
- * DevFn = val[15: 8], IntX = val[ 1: 0]
- * val[63:56] == 2: val[7:0] is a vector number.
+ *
* If val == 0 then CPU0 event-channel notifications are not delivered.
+ * If val != 0, val[63:56] encodes the type, as follows:
+ */
+
+#define HVM_PARAM_CALLBACK_TYPE_GSI 0
+/*
+ * val[55:0] is a delivery GSI. GSI 0 cannot be used, as it aliases val == 0,
+ * and disables all notifications.
+ */
+
+#define HVM_PARAM_CALLBACK_TYPE_PCI_INTX 1
+/*
+ * val[55:0] is a delivery PCI INTx line:
+ * Domain = val[47:32], Bus = val[31:16] DevFn = val[15:8], IntX = val[1:0]
+ */
+
+#define HVM_PARAM_CALLBACK_TYPE_VECTOR 2
+/*
+ * val[7:0] is a vector number. Check for XENFEAT_hvm_callback_vector to know
+ * if this delivery method is available.
*/
-#define HVM_PARAM_CALLBACK_IRQ 0
#define HVM_PARAM_STORE_PFN 1
#define HVM_PARAM_STORE_EVTCHN 2
--
2.0.4
[toc] | [prev] | [next] | [standalone]
| From | Shannon Zhao <zhaoshenglong@huawei.com> |
|---|---|
| Date | 2016-03-04 07:50 +0100 |
| Subject | [PATCH v5 13/17] ARM: Xen: Document UEFI support on Xen ARM virtual platforms |
| Message-ID | <r8RIK-2AC-11@gated-at.bofh.it> |
| In reply to | #1349886 |
From: Shannon Zhao <shannon.zhao@linaro.org>
Add a "uefi" node under /hypervisor node in FDT, then Linux kernel could
scan this to get the UEFI information.
Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Acked-by: Rob Herring <robh@kernel.org>
Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
CC: Rob Herring <robh@kernel.org>
---
Documentation/devicetree/bindings/arm/xen.txt | 33 +++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/xen.txt b/Documentation/devicetree/bindings/arm/xen.txt
index 0f7b9c2..6f83f76 100644
--- a/Documentation/devicetree/bindings/arm/xen.txt
+++ b/Documentation/devicetree/bindings/arm/xen.txt
@@ -15,6 +15,26 @@ the following properties:
- interrupts: the interrupt used by Xen to inject event notifications.
A GIC node is also required.
+To support UEFI on Xen ARM virtual platforms, Xen populates the FDT "uefi" node
+under /hypervisor with following parameters:
+
+________________________________________________________________________________
+Name | Size | Description
+================================================================================
+xen,uefi-system-table | 64-bit | Guest physical address of the UEFI System
+ | | Table.
+--------------------------------------------------------------------------------
+xen,uefi-mmap-start | 64-bit | Guest physical address of the UEFI memory
+ | | map.
+--------------------------------------------------------------------------------
+xen,uefi-mmap-size | 32-bit | Size in bytes of the UEFI memory map
+ | | pointed to in previous entry.
+--------------------------------------------------------------------------------
+xen,uefi-mmap-desc-size | 32-bit | Size in bytes of each entry in the UEFI
+ | | memory map.
+--------------------------------------------------------------------------------
+xen,uefi-mmap-desc-ver | 32-bit | Version of the mmap descriptor format.
+--------------------------------------------------------------------------------
Example (assuming #address-cells = <2> and #size-cells = <2>):
@@ -22,4 +42,17 @@ hypervisor {
compatible = "xen,xen-4.3", "xen,xen";
reg = <0 0xb0000000 0 0x20000>;
interrupts = <1 15 0xf08>;
+ uefi {
+ xen,uefi-system-table = <0xXXXXXXXX>;
+ xen,uefi-mmap-start = <0xXXXXXXXX>;
+ xen,uefi-mmap-size = <0xXXXXXXXX>;
+ xen,uefi-mmap-desc-size = <0xXXXXXXXX>;
+ xen,uefi-mmap-desc-ver = <0xXXXXXXXX>;
+ };
};
+
+The format and meaning of the "xen,uefi-*" parameters are similar to those in
+Documentation/arm/uefi.txt, which are provided by the regular UEFI stub. However
+they differ because they are provided by the Xen hypervisor, together with a set
+of UEFI runtime services implemented via hypercalls, see
+http://xenbits.xen.org/docs/unstable/hypercall/x86_64/include,public,platform.h.html.
--
2.0.4
[toc] | [prev] | [next] | [standalone]
| From | Shannon Zhao <zhaoshenglong@huawei.com> |
|---|---|
| Date | 2016-03-04 07:50 +0100 |
| Subject | [PATCH v5 11/17] ARM: XEN: Move xen_early_init() before efi_init() |
| Message-ID | <r8RIK-2AC-19@gated-at.bofh.it> |
| In reply to | #1349886 |
From: Shannon Zhao <shannon.zhao@linaro.org>
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.
Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
arch/arm/xen/enlighten.c | 56 ++++++++++++++++++++++++++++++++++-------------
arch/arm64/kernel/setup.c | 2 +-
2 files changed, 42 insertions(+), 16 deletions(-)
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index 807a93e..0e542b8 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -20,6 +20,7 @@
#include <linux/irqreturn.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_fdt.h>
#include <linux/of_irq.h>
#include <linux/of_address.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 __initdata struct device_node *xen_node;
-
int xen_remap_domain_gfn_array(struct vm_area_struct *vma,
unsigned long addr,
xen_pfn_t *gfn, int nr,
@@ -238,6 +237,33 @@ static irqreturn_t xen_arm_callback(int irq, void *arg)
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
* 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
void __init xen_early_init(void)
{
- int len;
- const char *s = NULL;
- const char *version = NULL;
- const char *xen_prefix = "xen,xen-";
-
- xen_node = of_find_compatible_node(NULL, NULL, "xen,xen");
- if (!xen_node) {
+ of_scan_flat_dt(fdt_find_hyper_node, NULL);
+ if (!hyper_node.found) {
pr_debug("No Xen support\n");
return;
}
- s = of_get_property(xen_node, "compatible", &len);
- if (strlen(xen_prefix) + 3 < len &&
- !strncmp(xen_prefix, s, strlen(xen_prefix)))
- version = s + strlen(xen_prefix);
- if (version == NULL) {
+
+ if (hyper_node.version == NULL) {
pr_debug("Xen version not found\n");
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;
@@ -305,6 +323,14 @@ static void __init xen_acpi_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);
}
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 8119479..a4a2878 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -313,6 +313,7 @@ void __init setup_arch(char **cmdline_p)
*/
local_async_enable();
+ xen_early_init();
efi_init();
arm64_memblock_init();
@@ -334,7 +335,6 @@ void __init setup_arch(char **cmdline_p)
} else {
psci_acpi_init();
}
- xen_early_init();
cpu_read_bootcpu_ops();
smp_init_cpus();
--
2.0.4
[toc] | [prev] | [next] | [standalone]
| From | Shannon Zhao <zhaoshenglong@huawei.com> |
|---|---|
| Date | 2016-03-04 07:50 +0100 |
| Subject | [PATCH v5 17/17] Xen: EFI: Parse DT parameters for Xen specific UEFI |
| Message-ID | <r8RIK-2AC-13@gated-at.bofh.it> |
| In reply to | #1349886 |
From: Shannon Zhao <shannon.zhao@linaro.org>
Add a new function to parse DT parameters for Xen specific UEFI just
like the way for normal UEFI. Then it could reuse the existing codes.
If Xen supports EFI, initialize runtime services.
Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Reviewed-by: Matt Fleming <matt@codeblueprint.co.uk>
Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
CC: Matt Fleming <matt@codeblueprint.co.uk>
---
arch/arm/xen/enlighten.c | 6 +++++
drivers/firmware/efi/arm-runtime.c | 17 +++++++++-----
drivers/firmware/efi/efi.c | 45 ++++++++++++++++++++++++++++++++------
3 files changed, 56 insertions(+), 12 deletions(-)
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index 0e542b8..026b5a7 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -261,6 +261,12 @@ static int __init fdt_find_hyper_node(unsigned long node, const char *uname,
!strncmp(hyper_node.prefix, s, strlen(hyper_node.prefix)))
hyper_node.version = s + strlen(hyper_node.prefix);
+ if (IS_ENABLED(CONFIG_XEN_EFI)) {
+ /* Check if Xen supports EFI */
+ if (of_get_flat_dt_subnode_by_name(node, "uefi") > 0)
+ set_bit(EFI_PARAVIRT, &efi.flags);
+ }
+
return 0;
}
diff --git a/drivers/firmware/efi/arm-runtime.c b/drivers/firmware/efi/arm-runtime.c
index 6ae21e4..ac609b9 100644
--- a/drivers/firmware/efi/arm-runtime.c
+++ b/drivers/firmware/efi/arm-runtime.c
@@ -27,6 +27,7 @@
#include <asm/mmu.h>
#include <asm/pgalloc.h>
#include <asm/pgtable.h>
+#include <asm/xen/xen-ops.h>
extern u64 efi_system_table;
@@ -107,13 +108,19 @@ static int __init arm_enable_runtime_services(void)
}
set_bit(EFI_SYSTEM_TABLES, &efi.flags);
- if (!efi_virtmap_init()) {
- pr_err("No UEFI virtual mapping was installed -- runtime services will not be available\n");
- return -ENOMEM;
+ if (IS_ENABLED(CONFIG_XEN_EFI) && efi_enabled(EFI_PARAVIRT)) {
+ /* Set up runtime services function pointers for Xen Dom0 */
+ xen_efi_runtime_setup();
+ } else {
+ if (!efi_virtmap_init()) {
+ pr_err("No UEFI virtual mapping was installed -- runtime services will not be available\n");
+ return -ENOMEM;
+ }
+
+ /* Set up runtime services function pointers */
+ efi_native_runtime_setup();
}
- /* Set up runtime services function pointers */
- efi_native_runtime_setup();
set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
efi.runtime_version = efi.systab->hdr.revision;
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 2cd37da..1328cb7 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -500,12 +500,14 @@ device_initcall(efi_load_efivars);
FIELD_SIZEOF(struct efi_fdt_params, field) \
}
-static __initdata struct {
+struct params {
const char name[32];
const char propname[32];
int offset;
int size;
-} dt_params[] = {
+};
+
+static struct params fdt_params[] __initdata = {
UEFI_PARAM("System Table", "linux,uefi-system-table", system_table),
UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap),
UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size),
@@ -513,24 +515,45 @@ static __initdata struct {
UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver)
};
+static struct params xen_fdt_params[] __initdata = {
+ UEFI_PARAM("System Table", "xen,uefi-system-table", system_table),
+ UEFI_PARAM("MemMap Address", "xen,uefi-mmap-start", mmap),
+ UEFI_PARAM("MemMap Size", "xen,uefi-mmap-size", mmap_size),
+ UEFI_PARAM("MemMap Desc. Size", "xen,uefi-mmap-desc-size", desc_size),
+ UEFI_PARAM("MemMap Desc. Version", "xen,uefi-mmap-desc-ver", desc_ver)
+};
+
struct param_info {
int found;
void *params;
+ struct params *dt_params;
+ int size;
};
static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
int depth, void *data)
{
struct param_info *info = data;
+ struct params *dt_params = info->dt_params;
const void *prop;
void *dest;
u64 val;
- int i, len;
+ int i, len, offset;
- if (depth != 1 || strcmp(uname, "chosen") != 0)
- return 0;
+ if (efi_enabled(EFI_PARAVIRT)) {
+ if (depth != 1 || strcmp(uname, "hypervisor") != 0)
+ return 0;
- for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
+ offset = of_get_flat_dt_subnode_by_name(node, "uefi");
+ if (offset < 0)
+ return 0;
+ node = offset;
+ } else {
+ if (depth != 1 || strcmp(uname, "chosen") != 0)
+ return 0;
+ }
+
+ for (i = 0; i < info->size; i++) {
prop = of_get_flat_dt_prop(node, dt_params[i].propname, &len);
if (!prop)
return 0;
@@ -561,12 +584,20 @@ int __init efi_get_fdt_params(struct efi_fdt_params *params)
info.found = 0;
info.params = params;
+ if (efi_enabled(EFI_PARAVIRT)) {
+ info.dt_params = xen_fdt_params;
+ info.size = ARRAY_SIZE(xen_fdt_params);
+ } else {
+ info.dt_params = fdt_params;
+ info.size = ARRAY_SIZE(fdt_params);
+ }
+
ret = of_scan_flat_dt(fdt_find_uefi_params, &info);
if (!info.found)
pr_info("UEFI not found.\n");
else if (!ret)
pr_err("Can't find '%s' in device tree!\n",
- dt_params[info.found].name);
+ info.dt_params[info.found].name);
return ret;
}
--
2.0.4
[toc] | [prev] | [next] | [standalone]
| From | Shannon Zhao <zhaoshenglong@huawei.com> |
|---|---|
| Date | 2016-03-04 07:50 +0100 |
| Subject | [PATCH v5 15/17] ARM64: XEN: Add a function to initialize Xen specific UEFI runtime services |
| Message-ID | <r8RIK-2AC-17@gated-at.bofh.it> |
| In reply to | #1349886 |
From: Shannon Zhao <shannon.zhao@linaro.org>
When running on Xen hypervisor, runtime services are supported through
hypercall. Add a Xen specific function to initialize runtime services.
Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
arch/arm/include/asm/xen/xen-ops.h | 6 ++++++
arch/arm/xen/Makefile | 1 +
arch/arm/xen/efi.c | 40 ++++++++++++++++++++++++++++++++++++
arch/arm64/include/asm/xen/xen-ops.h | 6 ++++++
arch/arm64/xen/Makefile | 1 +
drivers/xen/Kconfig | 2 +-
6 files changed, 55 insertions(+), 1 deletion(-)
create mode 100644 arch/arm/include/asm/xen/xen-ops.h
create mode 100644 arch/arm/xen/efi.c
create mode 100644 arch/arm64/include/asm/xen/xen-ops.h
diff --git a/arch/arm/include/asm/xen/xen-ops.h b/arch/arm/include/asm/xen/xen-ops.h
new file mode 100644
index 0000000..ec154e7
--- /dev/null
+++ b/arch/arm/include/asm/xen/xen-ops.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_XEN_OPS_H
+#define _ASM_XEN_OPS_H
+
+void xen_efi_runtime_setup(void);
+
+#endif /* _ASM_XEN_OPS_H */
diff --git a/arch/arm/xen/Makefile b/arch/arm/xen/Makefile
index 1296952..2279521 100644
--- a/arch/arm/xen/Makefile
+++ b/arch/arm/xen/Makefile
@@ -1 +1,2 @@
obj-y := enlighten.o hypercall.o grant-table.o p2m.o mm.o
+obj-$(CONFIG_XEN_EFI) += efi.o
diff --git a/arch/arm/xen/efi.c b/arch/arm/xen/efi.c
new file mode 100644
index 0000000..16db419
--- /dev/null
+++ b/arch/arm/xen/efi.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015, Linaro Limited, Shannon Zhao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/efi.h>
+#include <xen/xen-ops.h>
+#include <asm/xen/xen-ops.h>
+
+/* Set XEN EFI runtime services function pointers. Other fields of struct efi,
+ * e.g. efi.systab, will be set like normal EFI.
+ */
+void __init xen_efi_runtime_setup(void)
+{
+ efi.get_time = xen_efi_get_time;
+ efi.set_time = xen_efi_set_time;
+ efi.get_wakeup_time = xen_efi_get_wakeup_time;
+ efi.set_wakeup_time = xen_efi_set_wakeup_time;
+ efi.get_variable = xen_efi_get_variable;
+ efi.get_next_variable = xen_efi_get_next_variable;
+ efi.set_variable = xen_efi_set_variable;
+ efi.query_variable_info = xen_efi_query_variable_info;
+ efi.update_capsule = xen_efi_update_capsule;
+ efi.query_capsule_caps = xen_efi_query_capsule_caps;
+ efi.get_next_high_mono_count = xen_efi_get_next_high_mono_count;
+ efi.reset_system = NULL; /* Functionality provided by Xen. */
+}
+EXPORT_SYMBOL_GPL(xen_efi_runtime_setup);
diff --git a/arch/arm64/include/asm/xen/xen-ops.h b/arch/arm64/include/asm/xen/xen-ops.h
new file mode 100644
index 0000000..ec154e7
--- /dev/null
+++ b/arch/arm64/include/asm/xen/xen-ops.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_XEN_OPS_H
+#define _ASM_XEN_OPS_H
+
+void xen_efi_runtime_setup(void);
+
+#endif /* _ASM_XEN_OPS_H */
diff --git a/arch/arm64/xen/Makefile b/arch/arm64/xen/Makefile
index 74a8d87..8ff8aa9 100644
--- a/arch/arm64/xen/Makefile
+++ b/arch/arm64/xen/Makefile
@@ -1,2 +1,3 @@
xen-arm-y += $(addprefix ../../arm/xen/, enlighten.o grant-table.o p2m.o mm.o)
obj-y := xen-arm.o hypercall.o
+obj-$(CONFIG_XEN_EFI) += $(addprefix ../../arm/xen/, efi.o)
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
index 73708ac..d50571c 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -268,7 +268,7 @@ config XEN_HAVE_PVMMU
config XEN_EFI
def_bool y
- depends on X86_64 && EFI
+ depends on (ARM || ARM64 || X86_64) && EFI
config XEN_AUTO_XLATE
def_bool y
--
2.0.4
[toc] | [prev] | [next] | [standalone]
| From | Shannon Zhao <zhaoshenglong@huawei.com> |
|---|---|
| Date | 2016-03-04 07:50 +0100 |
| Subject | [PATCH v5 07/17] Xen: ARM: Add support for mapping AMBA device mmio |
| Message-ID | <r8RIK-2AC-15@gated-at.bofh.it> |
| In reply to | #1349886 |
From: Shannon Zhao <shannon.zhao@linaro.org>
Add a bus_notifier for AMBA bus device in order to map the device
mmio regions when DOM0 booting with ACPI.
Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
drivers/xen/arm-device.c | 43 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/drivers/xen/arm-device.c b/drivers/xen/arm-device.c
index 76e26e5..3854043 100644
--- a/drivers/xen/arm-device.c
+++ b/drivers/xen/arm-device.c
@@ -139,3 +139,46 @@ static int __init register_xen_platform_notifier(void)
}
arch_initcall(register_xen_platform_notifier);
+
+#ifdef CONFIG_ARM_AMBA
+#include <linux/amba/bus.h>
+
+static int xen_amba_notifier(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct amba_device *adev = to_amba_device(data);
+ int r = 0;
+
+ switch (action) {
+ case BUS_NOTIFY_ADD_DEVICE:
+ r = xen_map_device_mmio(&adev->res, 1);
+ break;
+ case BUS_NOTIFY_DEL_DEVICE:
+ r = xen_unmap_device_mmio(&adev->res, 1);
+ break;
+ default:
+ return NOTIFY_DONE;
+ }
+ if (r)
+ dev_err(&adev->dev, "AMBA: Failed to %s device %s MMIO!\n",
+ action == BUS_NOTIFY_ADD_DEVICE ? "map" :
+ (action == BUS_NOTIFY_DEL_DEVICE ? "unmap" : "?"),
+ adev->dev.init_name);
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block amba_device_nb = {
+ .notifier_call = xen_amba_notifier,
+};
+
+static int __init register_xen_amba_notifier(void)
+{
+ if (!xen_initial_domain() || acpi_disabled)
+ return 0;
+
+ return bus_register_notifier(&amba_bustype, &amba_device_nb);
+}
+
+arch_initcall(register_xen_amba_notifier);
+#endif
--
2.0.4
[toc] | [prev] | [next] | [standalone]
| From | Shannon Zhao <zhaoshenglong@huawei.com> |
|---|---|
| Date | 2016-03-04 07:50 +0100 |
| Subject | [PATCH v5 16/17] FDT: Add a helper to get the subnode by given name |
| Message-ID | <r8RIK-2AC-21@gated-at.bofh.it> |
| In reply to | #1349886 |
From: Shannon Zhao <shannon.zhao@linaro.org>
Sometimes it needs to check if there is a subnode of given node in FDT
by given name. Introduce this helper to get the subnode if it exists.
CC: Rob Herring <robh@kernel.org>
Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
---
drivers/of/fdt.c | 13 +++++++++++++
include/linux/of_fdt.h | 2 ++
2 files changed, 15 insertions(+)
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 655f79d..09001db 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -645,6 +645,19 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node,
}
/**
+ * of_get_flat_dt_subnode_by_name - get the subnode by given name
+ *
+ * @node: the parent node
+ * @uname: the name of subnode
+ * @return offset of the subnode, or -FDT_ERR_NOTFOUND if there is none
+ */
+
+int of_get_flat_dt_subnode_by_name(unsigned long node, const char *uname)
+{
+ return fdt_subnode_offset(initial_boot_params, node, uname);
+}
+
+/**
* of_get_flat_dt_root - find the root node in the flat blob
*/
unsigned long __init of_get_flat_dt_root(void)
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
index df9ef38..fc28162 100644
--- a/include/linux/of_fdt.h
+++ b/include/linux/of_fdt.h
@@ -52,6 +52,8 @@ extern char __dtb_end[];
extern int of_scan_flat_dt(int (*it)(unsigned long node, const char *uname,
int depth, void *data),
void *data);
+extern int of_get_flat_dt_subnode_by_name(unsigned long node,
+ const char *uname);
extern const void *of_get_flat_dt_prop(unsigned long node, const char *name,
int *size);
extern int of_flat_dt_is_compatible(unsigned long node, const char *name);
--
2.0.4
[toc] | [prev] | [next] | [standalone]
| From | Stefano Stabellini <stefano.stabellini@eu.citrix.com> |
|---|---|
| Date | 2016-03-04 13:30 +0100 |
| Subject | Re: [PATCH v5 16/17] FDT: Add a helper to get the subnode by given name |
| Message-ID | <r8X1M-6Gg-15@gated-at.bofh.it> |
| In reply to | #1349897 |
On Fri, 4 Mar 2016, Shannon Zhao wrote:
> From: Shannon Zhao <shannon.zhao@linaro.org>
>
> Sometimes it needs to check if there is a subnode of given node in FDT
> by given name. Introduce this helper to get the subnode if it exists.
>
> CC: Rob Herring <robh@kernel.org>
> Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> drivers/of/fdt.c | 13 +++++++++++++
> include/linux/of_fdt.h | 2 ++
> 2 files changed, 15 insertions(+)
>
> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index 655f79d..09001db 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -645,6 +645,19 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node,
> }
>
> /**
> + * of_get_flat_dt_subnode_by_name - get the subnode by given name
> + *
> + * @node: the parent node
> + * @uname: the name of subnode
> + * @return offset of the subnode, or -FDT_ERR_NOTFOUND if there is none
> + */
> +
> +int of_get_flat_dt_subnode_by_name(unsigned long node, const char *uname)
> +{
> + return fdt_subnode_offset(initial_boot_params, node, uname);
> +}
> +
> +/**
> * of_get_flat_dt_root - find the root node in the flat blob
> */
> unsigned long __init of_get_flat_dt_root(void)
> diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
> index df9ef38..fc28162 100644
> --- a/include/linux/of_fdt.h
> +++ b/include/linux/of_fdt.h
> @@ -52,6 +52,8 @@ extern char __dtb_end[];
> extern int of_scan_flat_dt(int (*it)(unsigned long node, const char *uname,
> int depth, void *data),
> void *data);
> +extern int of_get_flat_dt_subnode_by_name(unsigned long node,
> + const char *uname);
> extern const void *of_get_flat_dt_prop(unsigned long node, const char *name,
> int *size);
> extern int of_flat_dt_is_compatible(unsigned long node, const char *name);
> --
> 2.0.4
>
>
[toc] | [prev] | [next] | [standalone]
| From | Shannon Zhao <zhaoshenglong@huawei.com> |
|---|---|
| Date | 2016-03-04 07:50 +0100 |
| Subject | [PATCH v5 10/17] arm/xen: Get event-channel irq through HVM_PARAM when booting with ACPI |
| Message-ID | <r8RIK-2AC-23@gated-at.bofh.it> |
| In reply to | #1349886 |
From: Shannon Zhao <shannon.zhao@linaro.org>
When booting with ACPI, it could get the event-channel irq through
HVM_PARAM_CALLBACK_IRQ.
Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
arch/arm/xen/enlighten.c | 36 +++++++++++++++++++++++++++++++++++-
1 file changed, 35 insertions(+), 1 deletion(-)
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index d94f726..807a93e 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -30,6 +30,7 @@
#include <linux/time64.h>
#include <linux/timekeeping.h>
#include <linux/timekeeper_internal.h>
+#include <linux/acpi.h>
#include <linux/mm.h>
@@ -278,6 +279,35 @@ void __init xen_early_init(void)
add_preferred_console("hvc", 0, NULL);
}
+static void __init xen_acpi_guest_init(void)
+{
+#ifdef CONFIG_ACPI
+ struct xen_hvm_param a;
+ int interrupt, trigger, polarity;
+
+ a.domid = DOMID_SELF;
+ a.index = HVM_PARAM_CALLBACK_IRQ;
+ xen_events_irq = 0;
+
+ if (!HYPERVISOR_hvm_op(HVMOP_get_param, &a)) {
+ if ((a.value >> 56) == HVM_PARAM_CALLBACK_TYPE_EVENT) {
+ interrupt = a.value & 0xff;
+ trigger = ((a.value >> 8) & 0x1) ? ACPI_EDGE_SENSITIVE
+ : ACPI_LEVEL_SENSITIVE;
+ polarity = ((a.value >> 8) & 0x2) ? ACPI_ACTIVE_LOW
+ : ACPI_ACTIVE_HIGH;
+ xen_events_irq = acpi_register_gsi(NULL, interrupt,
+ trigger, polarity);
+ }
+ }
+#endif
+}
+
+static void __init xen_dt_guest_init(void)
+{
+ xen_events_irq = irq_of_parse_and_map(xen_node, 0);
+}
+
static int __init xen_guest_init(void)
{
struct xen_add_to_physmap xatp;
@@ -286,7 +316,11 @@ static int __init xen_guest_init(void)
if (!xen_domain())
return 0;
- xen_events_irq = irq_of_parse_and_map(xen_node, 0);
+ if (!acpi_disabled)
+ xen_acpi_guest_init();
+ else
+ xen_dt_guest_init();
+
if (!xen_events_irq) {
pr_err("Xen event channel interrupt not found\n");
return -ENODEV;
--
2.0.4
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web