From 243848fc018cb98c2a70c39fe1f93eb266c79835 Mon Sep 17 00:00:00 2001 From: Shannon Zhao Date: Thu, 7 Apr 2016 20:03:19 +0800 Subject: xen/grant-table: Move xlated_setup_gnttab_pages to common place Move xlated_setup_gnttab_pages to common place, so it can be reused by ARM to setup grant table. Rename it to xen_xlate_map_ballooned_pages. Signed-off-by: Shannon Zhao Reviewed-by: Stefano Stabellini Reviewed-by: Julien Grall Tested-by: Julien Grall --- include/xen/xen-ops.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h index 86abe07b20ec..072be1c29917 100644 --- a/include/xen/xen-ops.h +++ b/include/xen/xen-ops.h @@ -85,6 +85,8 @@ int xen_xlate_remap_gfn_array(struct vm_area_struct *vma, struct page **pages); int xen_xlate_unmap_gfn_range(struct vm_area_struct *vma, int nr, struct page **pages); +int xen_xlate_map_ballooned_pages(xen_pfn_t **pfns, void **vaddr, + unsigned long nr_grant_frames); bool xen_running_on_version_or_later(unsigned int major, unsigned int minor); -- cgit v1.3-14-g43fede From 712a5b77cb5a1d3028a8c202f4f839802a03f19f Mon Sep 17 00:00:00 2001 From: Shannon Zhao Date: Thu, 7 Apr 2016 20:03:22 +0800 Subject: xen: memory : Add new XENMAPSPACE type XENMAPSPACE_dev_mmio Add a new type of Xen map space for Dom0 to map device's MMIO region. Signed-off-by: Shannon Zhao Reviewed-by: Julien Grall Tested-by: Julien Grall --- include/xen/interface/memory.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/xen/interface/memory.h b/include/xen/interface/memory.h index 2ecfe4f700d9..9aa8988cb340 100644 --- a/include/xen/interface/memory.h +++ b/include/xen/interface/memory.h @@ -160,6 +160,7 @@ DEFINE_GUEST_HANDLE_STRUCT(xen_machphys_mapping_t); #define XENMAPSPACE_gmfn_foreign 4 /* GMFN from another dom, * XENMEM_add_to_physmap_range only. */ +#define XENMAPSPACE_dev_mmio 5 /* device mmio region */ /* * Sets the GPFN at which a particular page appears in the specified guest's -- cgit v1.3-14-g43fede From b6f0bcc23fa9cb32752cbf263d4014a21f132f92 Mon Sep 17 00:00:00 2001 From: Shannon Zhao Date: Thu, 7 Apr 2016 20:03:25 +0800 Subject: Xen: public/hvm: sync changes of HVM_PARAM_CALLBACK_VIA ABI from Xen Sync the changes of HVM_PARAM_CALLBACK_VIA ABI introduced by Xen commit (public/hvm: export the HVM_PARAM_CALLBACK_VIA ABI in the API). Signed-off-by: Shannon Zhao Acked-by: Stefano Stabellini Tested-by: Julien Grall --- include/xen/interface/hvm/params.h | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/xen/interface/hvm/params.h b/include/xen/interface/hvm/params.h index a6c79911e729..70ad20834e13 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 -- cgit v1.3-14-g43fede From 383ff518a79fe3dcece579b9d30be77b219d10f8 Mon Sep 17 00:00:00 2001 From: Shannon Zhao Date: Thu, 7 Apr 2016 20:03:26 +0800 Subject: xen/hvm/params: Add a new delivery type for event-channel in HVM_PARAM_CALLBACK_IRQ This new delivery type which is for ARM shares the same value with HVM_PARAM_CALLBACK_TYPE_VECTOR which is for x86. val[15:8] is flag: val[7:0] is a PPI. To the flag, bit 8 stands the interrupt mode is edge(1) or level(0) and bit 9 stands the interrupt polarity is active low(1) or high(0). Signed-off-by: Shannon Zhao Acked-by: Stefano Stabellini Reviewed-by: Julien Grall Tested-by: Julien Grall --- include/xen/interface/hvm/params.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'include') diff --git a/include/xen/interface/hvm/params.h b/include/xen/interface/hvm/params.h index 70ad20834e13..4d61fc58d99d 100644 --- a/include/xen/interface/hvm/params.h +++ b/include/xen/interface/hvm/params.h @@ -47,11 +47,24 @@ * Domain = val[47:32], Bus = val[31:16] DevFn = val[15:8], IntX = val[1:0] */ +#if defined(__i386__) || defined(__x86_64__) #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. */ +#elif defined(__arm__) || defined(__aarch64__) +#define HVM_PARAM_CALLBACK_TYPE_PPI 2 +/* + * val[55:16] needs to be zero. + * val[15:8] is interrupt flag of the PPI used by event-channel: + * bit 8: the PPI is edge(1) or level(0) triggered + * bit 9: the PPI is active low(1) or high(0) + * val[7:0] is a PPI number used by event-channel. + * This is only used by ARM/ARM64 and masking/eoi the interrupt associated to + * the notification is handled by the interrupt controller. + */ +#endif #define HVM_PARAM_STORE_PFN 1 #define HVM_PARAM_STORE_EVTCHN 2 -- cgit v1.3-14-g43fede From a62ed500307bfaf4c1a818b69f7c1e7df1039a16 Mon Sep 17 00:00:00 2001 From: Shannon Zhao Date: Thu, 7 Apr 2016 20:03:31 +0800 Subject: XEN: EFI: Move x86 specific codes to architecture directory 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 Reviewed-by: Stefano Stabellini Tested-by: Julien Grall Signed-off-by: Stefano Stabellini --- arch/x86/xen/efi.c | 111 ++++++++++++++++++++++++++++++++ drivers/xen/efi.c | 173 ++++++++++---------------------------------------- include/xen/xen-ops.h | 30 ++++++--- 3 files changed, 167 insertions(+), 147 deletions(-) (limited to 'include') diff --git a/arch/x86/xen/efi.c b/arch/x86/xen/efi.c index be14cc3e48d5..3be012115853 100644 --- a/arch/x86/xen/efi.c +++ b/arch/x86/xen/efi.c @@ -20,10 +20,121 @@ #include #include +#include #include +#include #include #include +#include + +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. */ + .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 e9d2135445c1..22f71ffd3406 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,111 +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. */ - .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 072be1c29917..3491582bf50a 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 -- cgit v1.3-14-g43fede From 9c6098685a1d5df72da61ff7838ebb1524796869 Mon Sep 17 00:00:00 2001 From: Shannon Zhao Date: Thu, 7 Apr 2016 20:03:33 +0800 Subject: FDT: Add a helper to get the subnode by given name 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 Signed-off-by: Shannon Zhao Acked-by: Stefano Stabellini Acked-by: Rob Herring Tested-by: Julien Grall --- drivers/of/fdt.c | 13 +++++++++++++ include/linux/of_fdt.h | 2 ++ 2 files changed, 15 insertions(+) (limited to 'include') diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 33daffc4392c..0e02947a8a7a 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -743,6 +743,19 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node, return rc; } +/** + * 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 */ diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h index 901ec01c9fba..26c3302ae58f 100644 --- a/include/linux/of_fdt.h +++ b/include/linux/of_fdt.h @@ -53,6 +53,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); -- cgit v1.3-14-g43fede From ecb23dc6f2eff0ce64dd60351a81f376f13b12cc Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Fri, 20 May 2016 09:26:48 +0200 Subject: xen: add steal_clock support on x86 The pv_time_ops structure contains a function pointer for the "steal_clock" functionality used only by KVM and Xen on ARM. Xen on x86 uses its own mechanism to account for the "stolen" time a thread wasn't able to run due to hypervisor scheduling. Add support in Xen arch independent time handling for this feature by moving it out of the arm arch into drivers/xen and remove the x86 Xen hack. Signed-off-by: Juergen Gross Reviewed-by: Boris Ostrovsky Reviewed-by: Stefano Stabellini Signed-off-by: David Vrabel --- arch/arm/xen/enlighten.c | 18 ++---------------- arch/x86/xen/time.c | 44 ++------------------------------------------ drivers/xen/time.c | 20 ++++++++++++++++++++ include/linux/kernel_stat.h | 1 - include/xen/xen-ops.h | 1 + kernel/sched/cputime.c | 10 ---------- 6 files changed, 25 insertions(+), 69 deletions(-) (limited to 'include') diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c index d4f36eba3499..47acb3613f40 100644 --- a/arch/arm/xen/enlighten.c +++ b/arch/arm/xen/enlighten.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -86,19 +85,6 @@ int xen_unmap_domain_gfn_range(struct vm_area_struct *vma, } EXPORT_SYMBOL_GPL(xen_unmap_domain_gfn_range); -static unsigned long long xen_stolen_accounting(int cpu) -{ - struct vcpu_runstate_info state; - - BUG_ON(cpu != smp_processor_id()); - - xen_get_runstate_snapshot(&state); - - WARN_ON(state.state != RUNSTATE_running); - - return state.time[RUNSTATE_runnable] + state.time[RUNSTATE_offline]; -} - static void xen_read_wallclock(struct timespec64 *ts) { u32 version; @@ -432,8 +418,8 @@ static int __init xen_guest_init(void) register_cpu_notifier(&xen_cpu_notifier); - pv_time_ops.steal_clock = xen_stolen_accounting; - static_key_slow_inc(¶virt_steal_enabled); + xen_time_setup_guest(); + if (xen_initial_domain()) pvclock_gtod_register_notifier(&xen_pvclock_gtod_notifier); diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c index 6deba5bc7e34..c31006f0f37f 100644 --- a/arch/x86/xen/time.c +++ b/arch/x86/xen/time.c @@ -11,8 +11,6 @@ #include #include #include -#include -#include #include #include #include @@ -31,44 +29,6 @@ /* Xen may fire a timer up to this many ns early */ #define TIMER_SLOP 100000 -#define NS_PER_TICK (1000000000LL / HZ) - -/* snapshots of runstate info */ -static DEFINE_PER_CPU(struct vcpu_runstate_info, xen_runstate_snapshot); - -/* unused ns of stolen time */ -static DEFINE_PER_CPU(u64, xen_residual_stolen); - -static void do_stolen_accounting(void) -{ - struct vcpu_runstate_info state; - struct vcpu_runstate_info *snap; - s64 runnable, offline, stolen; - cputime_t ticks; - - xen_get_runstate_snapshot(&state); - - WARN_ON(state.state != RUNSTATE_running); - - snap = this_cpu_ptr(&xen_runstate_snapshot); - - /* work out how much time the VCPU has not been runn*ing* */ - runnable = state.time[RUNSTATE_runnable] - snap->time[RUNSTATE_runnable]; - offline = state.time[RUNSTATE_offline] - snap->time[RUNSTATE_offline]; - - *snap = state; - - /* Add the appropriate number of ticks of stolen time, - including any left-overs from last time. */ - stolen = runnable + offline + __this_cpu_read(xen_residual_stolen); - - if (stolen < 0) - stolen = 0; - - ticks = iter_div_u64_rem(stolen, NS_PER_TICK, &stolen); - __this_cpu_write(xen_residual_stolen, stolen); - account_steal_ticks(ticks); -} /* Get the TSC speed from Xen */ static unsigned long xen_tsc_khz(void) @@ -335,8 +295,6 @@ static irqreturn_t xen_timer_interrupt(int irq, void *dev_id) ret = IRQ_HANDLED; } - do_stolen_accounting(); - return ret; } @@ -431,6 +389,8 @@ static void __init xen_time_init(void) xen_setup_timer(cpu); xen_setup_cpu_clockevents(); + xen_time_setup_guest(); + if (xen_initial_domain()) pvclock_gtod_register_notifier(&xen_pvclock_gtod_notifier); } diff --git a/drivers/xen/time.c b/drivers/xen/time.c index 71078425c9ea..2257b6663766 100644 --- a/drivers/xen/time.c +++ b/drivers/xen/time.c @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -75,6 +76,15 @@ bool xen_vcpu_stolen(int vcpu) return per_cpu(xen_runstate, vcpu).state == RUNSTATE_runnable; } +static u64 xen_steal_clock(int cpu) +{ + struct vcpu_runstate_info state; + + BUG_ON(cpu != smp_processor_id()); + xen_get_runstate_snapshot(&state); + return state.time[RUNSTATE_runnable] + state.time[RUNSTATE_offline]; +} + void xen_setup_runstate_info(int cpu) { struct vcpu_register_runstate_memory_area area; @@ -86,3 +96,13 @@ void xen_setup_runstate_info(int cpu) BUG(); } +void __init xen_time_setup_guest(void) +{ + pv_time_ops.steal_clock = xen_steal_clock; + + static_key_slow_inc(¶virt_steal_enabled); + /* + * We can't set paravirt_steal_rq_enabled as this would require the + * capability to read another cpu's runstate info. + */ +} diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h index 25a822f6f000..44fda64ad434 100644 --- a/include/linux/kernel_stat.h +++ b/include/linux/kernel_stat.h @@ -92,7 +92,6 @@ static inline void account_process_tick(struct task_struct *tsk, int user) extern void account_process_tick(struct task_struct *, int user); #endif -extern void account_steal_ticks(unsigned long ticks); extern void account_idle_ticks(unsigned long ticks); #endif /* _LINUX_KERNEL_STAT_H */ diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h index 3491582bf50a..355275bad2cf 100644 --- a/include/xen/xen-ops.h +++ b/include/xen/xen-ops.h @@ -21,6 +21,7 @@ void xen_resume_notifier_unregister(struct notifier_block *nb); bool xen_vcpu_stolen(int vcpu); void xen_setup_runstate_info(int cpu); +void xen_time_setup_guest(void); void xen_get_runstate_snapshot(struct vcpu_runstate_info *res); int xen_setup_shutdown_event(void); diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c index 75f98c5498d5..8c4c6dcc052c 100644 --- a/kernel/sched/cputime.c +++ b/kernel/sched/cputime.c @@ -489,16 +489,6 @@ void account_process_tick(struct task_struct *p, int user_tick) account_idle_time(cputime_one_jiffy); } -/* - * Account multiple ticks of steal time. - * @p: the process from which the cpu time has been stolen - * @ticks: number of stolen ticks - */ -void account_steal_ticks(unsigned long ticks) -{ - account_steal_time(jiffies_to_cputime(ticks)); -} - /* * Account multiple ticks of idle time. * @ticks: number of stolen ticks -- cgit v1.3-14-g43fede From 7ba8dba95cb227eb6c270b1aa77f942e45f5e47c Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Wed, 6 Jul 2016 07:00:28 +0200 Subject: xen: update xen headers Update some Xen headers to be able to use new functionality. Signed-off-by: Juergen Gross Reviewed-by: Boris Ostrovsky Reviewed-by: Stefano Stabellini Signed-off-by: David Vrabel --- include/xen/interface/vcpu.h | 24 +++++++++++++++--------- include/xen/interface/xen.h | 17 ++++++++++++++++- 2 files changed, 31 insertions(+), 10 deletions(-) (limited to 'include') diff --git a/include/xen/interface/vcpu.h b/include/xen/interface/vcpu.h index b05288ce3991..98188c87f5c1 100644 --- a/include/xen/interface/vcpu.h +++ b/include/xen/interface/vcpu.h @@ -75,15 +75,21 @@ */ #define VCPUOP_get_runstate_info 4 struct vcpu_runstate_info { - /* VCPU's current state (RUNSTATE_*). */ - int state; - /* When was current state entered (system time, ns)? */ - uint64_t state_entry_time; - /* - * Time spent in each RUNSTATE_* (ns). The sum of these times is - * guaranteed not to drift from system time. - */ - uint64_t time[4]; + /* VCPU's current state (RUNSTATE_*). */ + int state; + /* When was current state entered (system time, ns)? */ + uint64_t state_entry_time; + /* + * Update indicator set in state_entry_time: + * When activated via VMASST_TYPE_runstate_update_flag, set during + * updates in guest memory mapped copy of vcpu_runstate_info. + */ +#define XEN_RUNSTATE_UPDATE (1ULL << 63) + /* + * Time spent in each RUNSTATE_* (ns). The sum of these times is + * guaranteed not to drift from system time. + */ + uint64_t time[4]; }; DEFINE_GUEST_HANDLE_STRUCT(vcpu_runstate_info); diff --git a/include/xen/interface/xen.h b/include/xen/interface/xen.h index d1331121c0bd..1b0d189cd3d3 100644 --- a/include/xen/interface/xen.h +++ b/include/xen/interface/xen.h @@ -413,7 +413,22 @@ DEFINE_GUEST_HANDLE_STRUCT(mmuext_op); /* x86/PAE guests: support PDPTs above 4GB. */ #define VMASST_TYPE_pae_extended_cr3 3 -#define MAX_VMASST_TYPE 3 +/* + * x86 guests: Sane behaviour for virtual iopl + * - virtual iopl updated from do_iret() hypercalls. + * - virtual iopl reported in bounce frames. + * - guest kernels assumed to be level 0 for the purpose of iopl checks. + */ +#define VMASST_TYPE_architectural_iopl 4 + +/* + * All guests: activate update indicator in vcpu_runstate_info + * Enable setting the XEN_RUNSTATE_UPDATE flag in guest memory mapped + * vcpu_runstate_info during updates of the runstate information. + */ +#define VMASST_TYPE_runstate_update_flag 5 + +#define MAX_VMASST_TYPE 5 #ifndef __ASSEMBLY__ -- cgit v1.3-14-g43fede From fbc872c38c8fed31948c85683b5326ee5ab9fccc Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Mon, 11 Jul 2016 15:45:51 +0100 Subject: xen/evtchn: add IOCTL_EVTCHN_RESTRICT IOCTL_EVTCHN_RESTRICT limits the file descriptor to being able to bind to interdomain event channels from a specific domain. Event channels that are already bound continue to work for sending and receiving notifications. This is useful as part of deprivileging a user space PV backend or device model (QEMU). e.g., Once the device model as bound to the ioreq server event channels it can restrict the file handle so an exploited DM cannot use it to create or bind to arbitrary event channels. Signed-off-by: David Vrabel Reviewed-by: Boris Ostrovsky --- drivers/xen/evtchn.c | 40 ++++++++++++++++++++++++++++++++++++++++ include/uapi/xen/evtchn.h | 15 +++++++++++++++ 2 files changed, 55 insertions(+) (limited to 'include') diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c index f4edd6df3df2..7efd1cb9bb40 100644 --- a/drivers/xen/evtchn.c +++ b/drivers/xen/evtchn.c @@ -73,8 +73,12 @@ struct per_user_data { wait_queue_head_t evtchn_wait; struct fasync_struct *evtchn_async_queue; const char *name; + + domid_t restrict_domid; }; +#define UNRESTRICTED_DOMID ((domid_t)-1) + struct user_evtchn { struct rb_node node; struct per_user_data *user; @@ -443,6 +447,10 @@ static long evtchn_ioctl(struct file *file, struct ioctl_evtchn_bind_virq bind; struct evtchn_bind_virq bind_virq; + rc = -EACCES; + if (u->restrict_domid != UNRESTRICTED_DOMID) + break; + rc = -EFAULT; if (copy_from_user(&bind, uarg, sizeof(bind))) break; @@ -468,6 +476,11 @@ static long evtchn_ioctl(struct file *file, if (copy_from_user(&bind, uarg, sizeof(bind))) break; + rc = -EACCES; + if (u->restrict_domid != UNRESTRICTED_DOMID && + u->restrict_domid != bind.remote_domain) + break; + bind_interdomain.remote_dom = bind.remote_domain; bind_interdomain.remote_port = bind.remote_port; rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain, @@ -485,6 +498,10 @@ static long evtchn_ioctl(struct file *file, struct ioctl_evtchn_bind_unbound_port bind; struct evtchn_alloc_unbound alloc_unbound; + rc = -EACCES; + if (u->restrict_domid != UNRESTRICTED_DOMID) + break; + rc = -EFAULT; if (copy_from_user(&bind, uarg, sizeof(bind))) break; @@ -553,6 +570,27 @@ static long evtchn_ioctl(struct file *file, break; } + case IOCTL_EVTCHN_RESTRICT_DOMID: { + struct ioctl_evtchn_restrict_domid ierd; + + rc = -EACCES; + if (u->restrict_domid != UNRESTRICTED_DOMID) + break; + + rc = -EFAULT; + if (copy_from_user(&ierd, uarg, sizeof(ierd))) + break; + + rc = -EINVAL; + if (ierd.domid == 0 || ierd.domid >= DOMID_FIRST_RESERVED) + break; + + u->restrict_domid = ierd.domid; + rc = 0; + + break; + } + default: rc = -ENOSYS; break; @@ -601,6 +639,8 @@ static int evtchn_open(struct inode *inode, struct file *filp) mutex_init(&u->ring_cons_mutex); spin_lock_init(&u->ring_prod_lock); + u->restrict_domid = UNRESTRICTED_DOMID; + filp->private_data = u; return nonseekable_open(inode, filp); diff --git a/include/uapi/xen/evtchn.h b/include/uapi/xen/evtchn.h index 14e833ee4e0b..cb4aa4bb905e 100644 --- a/include/uapi/xen/evtchn.h +++ b/include/uapi/xen/evtchn.h @@ -85,4 +85,19 @@ struct ioctl_evtchn_notify { #define IOCTL_EVTCHN_RESET \ _IOC(_IOC_NONE, 'E', 5, 0) +/* + * Restrict this file descriptor so that it can only be used to bind + * new interdomain events from one domain. + * + * Once a file descriptor has been restricted it cannot be + * de-restricted, and must be closed and re-opened. Event channels + * which were bound before restricting remain bound afterwards, and + * can be notified as usual. + */ +#define IOCTL_EVTCHN_RESTRICT_DOMID \ + _IOC(_IOC_NONE, 'E', 6, sizeof(struct ioctl_evtchn_restrict_domid)) +struct ioctl_evtchn_restrict_domid { + domid_t domid; +}; + #endif /* __LINUX_PUBLIC_EVTCHN_H__ */ -- cgit v1.3-14-g43fede From 88e957d6e47f1232ad15b21e54a44f1147ea8c1b Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Thu, 30 Jun 2016 17:56:37 +0200 Subject: xen: introduce xen_vcpu_id mapping It may happen that Xen's and Linux's ideas of vCPU id diverge. In particular, when we crash on a secondary vCPU we may want to do kdump and unlike plain kexec where we do migrate_to_reboot_cpu() we try booting on the vCPU which crashed. This doesn't work very well for PVHVM guests as we have a number of hypercalls where we pass vCPU id as a parameter. These hypercalls either fail or do something unexpected. To solve the issue introduce percpu xen_vcpu_id mapping. ARM and PV guests get direct mapping for now. Boot CPU for PVHVM guest gets its id from CPUID. With secondary CPUs it is a bit more trickier. Currently, we initialize IPI vectors before these CPUs boot so we can't use CPUID. Use ACPI ids from MADT instead. Signed-off-by: Vitaly Kuznetsov Signed-off-by: David Vrabel --- arch/arm/xen/enlighten.c | 10 ++++++++++ arch/x86/xen/enlighten.c | 23 ++++++++++++++++++++++- include/xen/xen-ops.h | 6 ++++++ 3 files changed, 38 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c index 2f4c3aa540eb..72cf06bf43f2 100644 --- a/arch/arm/xen/enlighten.c +++ b/arch/arm/xen/enlighten.c @@ -49,6 +49,10 @@ struct shared_info *HYPERVISOR_shared_info = (void *)&xen_dummy_shared_info; DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu); static struct vcpu_info __percpu *xen_vcpu_info; +/* Linux <-> Xen vCPU id mapping */ +DEFINE_PER_CPU(int, xen_vcpu_id) = -1; +EXPORT_PER_CPU_SYMBOL(xen_vcpu_id); + /* These are unused until we support booting "pre-ballooned" */ unsigned long xen_released_pages; struct xen_memory_region xen_extra_mem[XEN_EXTRA_MEM_MAX_REGIONS] __initdata; @@ -167,6 +171,9 @@ static void xen_percpu_init(void) pr_info("Xen: initializing cpu%d\n", cpu); vcpup = per_cpu_ptr(xen_vcpu_info, cpu); + /* Direct vCPU id mapping for ARM guests. */ + per_cpu(xen_vcpu_id, cpu) = cpu; + info.mfn = virt_to_gfn(vcpup); info.offset = xen_offset_in_page(vcpup); @@ -388,6 +395,9 @@ static int __init xen_guest_init(void) if (xen_vcpu_info == NULL) return -ENOMEM; + /* Direct vCPU id mapping for ARM guests. */ + per_cpu(xen_vcpu_id, 0) = 0; + xen_auto_xlat_grant_frames.count = gnttab_max_grant_frames(); if (xen_xlate_map_ballooned_pages(&xen_auto_xlat_grant_frames.pfn, &xen_auto_xlat_grant_frames.vaddr, diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index ee7d71ec762f..d093949c94e0 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -118,6 +119,10 @@ DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu); */ DEFINE_PER_CPU(struct vcpu_info, xen_vcpu_info); +/* Linux <-> Xen vCPU id mapping */ +DEFINE_PER_CPU(int, xen_vcpu_id) = -1; +EXPORT_PER_CPU_SYMBOL(xen_vcpu_id); + enum xen_domain_type xen_domain_type = XEN_NATIVE; EXPORT_SYMBOL_GPL(xen_domain_type); @@ -1137,8 +1142,11 @@ void xen_setup_vcpu_info_placement(void) { int cpu; - for_each_possible_cpu(cpu) + for_each_possible_cpu(cpu) { + /* Set up direct vCPU id mapping for PV guests. */ + per_cpu(xen_vcpu_id, cpu) = cpu; xen_vcpu_setup(cpu); + } /* xen_vcpu_setup managed to place the vcpu_info within the * percpu area for all cpus, so make use of it. Note that for @@ -1729,6 +1737,9 @@ asmlinkage __visible void __init xen_start_kernel(void) #endif xen_raw_console_write("about to get started...\n"); + /* Let's presume PV guests always boot on vCPU with id 0. */ + per_cpu(xen_vcpu_id, 0) = 0; + xen_setup_runstate_info(0); xen_efi_init(); @@ -1797,6 +1808,12 @@ static void __init init_hvm_pv_info(void) xen_setup_features(); + cpuid(base + 4, &eax, &ebx, &ecx, &edx); + if (eax & XEN_HVM_CPUID_VCPU_ID_PRESENT) + this_cpu_write(xen_vcpu_id, ebx); + else + this_cpu_write(xen_vcpu_id, smp_processor_id()); + pv_info.name = "Xen HVM"; xen_domain_type = XEN_HVM_DOMAIN; @@ -1808,6 +1825,10 @@ static int xen_hvm_cpu_notify(struct notifier_block *self, unsigned long action, int cpu = (long)hcpu; switch (action) { case CPU_UP_PREPARE: + if (cpu_acpi_id(cpu) != U32_MAX) + per_cpu(xen_vcpu_id, cpu) = cpu_acpi_id(cpu); + else + per_cpu(xen_vcpu_id, cpu) = cpu; xen_vcpu_setup(cpu); if (xen_have_vector_callback) { if (xen_feature(XENFEAT_hvm_safe_pvclock)) diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h index 355275bad2cf..c9c532d56623 100644 --- a/include/xen/xen-ops.h +++ b/include/xen/xen-ops.h @@ -9,6 +9,12 @@ DECLARE_PER_CPU(struct vcpu_info *, xen_vcpu); +DECLARE_PER_CPU(int, xen_vcpu_id); +static inline int xen_vcpu_nr(int cpu) +{ + return per_cpu(xen_vcpu_id, cpu); +} + void xen_arch_pre_suspend(void); void xen_arch_post_suspend(int suspend_cancelled); -- cgit v1.3-14-g43fede From d34c30cc1fa80f509500ff192ea6bc7d30671061 Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Tue, 26 Jul 2016 14:15:11 +0200 Subject: xen: add static initialization of steal_clock op to xen_time_ops pv_time_ops might be overwritten with xen_time_ops after the steal_clock operation has been initialized already. To prevent calling a now uninitialized function pointer add the steal_clock static initialization to xen_time_ops. Signed-off-by: Juergen Gross Signed-off-by: David Vrabel --- arch/x86/xen/time.c | 1 + drivers/xen/time.c | 2 +- include/xen/xen-ops.h | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c index fd7cd6f29b68..67356d29d74d 100644 --- a/arch/x86/xen/time.c +++ b/arch/x86/xen/time.c @@ -364,6 +364,7 @@ void xen_timer_resume(void) static const struct pv_time_ops xen_time_ops __initconst = { .sched_clock = xen_clocksource_read, + .steal_clock = xen_steal_clock, }; static void __init xen_time_init(void) diff --git a/drivers/xen/time.c b/drivers/xen/time.c index 48c3f6983067..ac5f23fcafc2 100644 --- a/drivers/xen/time.c +++ b/drivers/xen/time.c @@ -80,7 +80,7 @@ bool xen_vcpu_stolen(int vcpu) return per_cpu(xen_runstate, vcpu).state == RUNSTATE_runnable; } -static u64 xen_steal_clock(int cpu) +u64 xen_steal_clock(int cpu) { struct vcpu_runstate_info state; diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h index c9c532d56623..9a37c541822f 100644 --- a/include/xen/xen-ops.h +++ b/include/xen/xen-ops.h @@ -29,6 +29,7 @@ bool xen_vcpu_stolen(int vcpu); void xen_setup_runstate_info(int cpu); void xen_time_setup_guest(void); void xen_get_runstate_snapshot(struct vcpu_runstate_info *res); +u64 xen_steal_clock(int cpu); int xen_setup_shutdown_event(void); -- cgit v1.3-14-g43fede