From 4fee9ad84e9648a3cb07586501d283d3aef9f923 Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Tue, 14 Mar 2017 18:35:53 +0100 Subject: xen/balloon: decorate PV-only parts with #ifdef CONFIG_XEN_PV Balloon driver uses several PV-only concepts (xen_start_info, xen_extra_mem,..) and it seems the simpliest solution to make HVM-only build happy is to decorate these parts with #ifdefs. Signed-off-by: Vitaly Kuznetsov Reviewed-by: Juergen Gross Signed-off-by: Juergen Gross --- drivers/xen/balloon.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index a6d4378eb8d9..50dcb68d8070 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c @@ -709,6 +709,7 @@ void free_xenballooned_pages(int nr_pages, struct page **pages) } EXPORT_SYMBOL(free_xenballooned_pages); +#ifdef CONFIG_XEN_PV static void __init balloon_add_region(unsigned long start_pfn, unsigned long pages) { @@ -732,19 +733,22 @@ static void __init balloon_add_region(unsigned long start_pfn, balloon_stats.total_pages += extra_pfn_end - start_pfn; } +#endif static int __init balloon_init(void) { - int i; - if (!xen_domain()) return -ENODEV; pr_info("Initialising balloon driver\n"); +#ifdef CONFIG_XEN_PV balloon_stats.current_pages = xen_pv_domain() ? min(xen_start_info->nr_pages - xen_released_pages, max_pfn) : get_num_physpages(); +#else + balloon_stats.current_pages = get_num_physpages(); +#endif balloon_stats.target_pages = balloon_stats.current_pages; balloon_stats.balloon_low = 0; balloon_stats.balloon_high = 0; @@ -761,14 +765,20 @@ static int __init balloon_init(void) register_sysctl_table(xen_root); #endif - /* - * Initialize the balloon with pages from the extra memory - * regions (see arch/x86/xen/setup.c). - */ - for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) - if (xen_extra_mem[i].n_pfns) - balloon_add_region(xen_extra_mem[i].start_pfn, - xen_extra_mem[i].n_pfns); +#ifdef CONFIG_XEN_PV + { + int i; + + /* + * Initialize the balloon with pages from the extra memory + * regions (see arch/x86/xen/setup.c). + */ + for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) + if (xen_extra_mem[i].n_pfns) + balloon_add_region(xen_extra_mem[i].start_pfn, + xen_extra_mem[i].n_pfns); + } +#endif return 0; } -- cgit v1.2.3-70-g09d2 From d5ff5061c35448525fcb38950f06af6b9ae12c04 Mon Sep 17 00:00:00 2001 From: Stefano Stabellini Date: Thu, 13 Apr 2017 14:04:22 -0700 Subject: xen/arm,arm64: rename __generic_dma_ops to xen_get_dma_ops Now that __generic_dma_ops is a xen specific function, rename it to xen_get_dma_ops. Change all the call sites appropriately. Signed-off-by: Stefano Stabellini Reviewed-by: Boris Ostrovsky Acked-by: Konrad Rzeszutek Wilk CC: linux@armlinux.org.uk CC: catalin.marinas@arm.com CC: will.deacon@arm.com CC: boris.ostrovsky@oracle.com CC: jgross@suse.com CC: Julien Grall --- drivers/xen/swiotlb-xen.c | 8 ++++---- include/xen/arm/page-coherent.h | 20 ++++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c index e8cef1ad0fe3..8dab0d3dc172 100644 --- a/drivers/xen/swiotlb-xen.c +++ b/drivers/xen/swiotlb-xen.c @@ -693,8 +693,8 @@ xen_swiotlb_dma_mmap(struct device *dev, struct vm_area_struct *vma, unsigned long attrs) { #if defined(CONFIG_ARM) || defined(CONFIG_ARM64) - if (__generic_dma_ops(dev)->mmap) - return __generic_dma_ops(dev)->mmap(dev, vma, cpu_addr, + if (xen_get_dma_ops(dev)->mmap) + return xen_get_dma_ops(dev)->mmap(dev, vma, cpu_addr, dma_addr, size, attrs); #endif return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size); @@ -711,7 +711,7 @@ xen_swiotlb_get_sgtable(struct device *dev, struct sg_table *sgt, unsigned long attrs) { #if defined(CONFIG_ARM) || defined(CONFIG_ARM64) - if (__generic_dma_ops(dev)->get_sgtable) { + if (xen_get_dma_ops(dev)->get_sgtable) { #if 0 /* * This check verifies that the page belongs to the current domain and @@ -721,7 +721,7 @@ xen_swiotlb_get_sgtable(struct device *dev, struct sg_table *sgt, unsigned long bfn = PHYS_PFN(dma_to_phys(dev, handle)); BUG_ON (!page_is_ram(bfn)); #endif - return __generic_dma_ops(dev)->get_sgtable(dev, sgt, cpu_addr, + return xen_get_dma_ops(dev)->get_sgtable(dev, sgt, cpu_addr, handle, size, attrs); } #endif diff --git a/include/xen/arm/page-coherent.h b/include/xen/arm/page-coherent.h index b0a2bfc8d647..b1b4ecdf329a 100644 --- a/include/xen/arm/page-coherent.h +++ b/include/xen/arm/page-coherent.h @@ -5,7 +5,7 @@ #include #include -static inline const struct dma_map_ops *__generic_dma_ops(struct device *dev) +static inline const struct dma_map_ops *xen_get_dma_ops(struct device *dev) { if (dev && dev->archdata.dev_dma_ops) return dev->archdata.dev_dma_ops; @@ -27,13 +27,13 @@ void __xen_dma_sync_single_for_device(struct device *hwdev, static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size, dma_addr_t *dma_handle, gfp_t flags, unsigned long attrs) { - return __generic_dma_ops(hwdev)->alloc(hwdev, size, dma_handle, flags, attrs); + return xen_get_dma_ops(hwdev)->alloc(hwdev, size, dma_handle, flags, attrs); } static inline void xen_free_coherent_pages(struct device *hwdev, size_t size, void *cpu_addr, dma_addr_t dma_handle, unsigned long attrs) { - __generic_dma_ops(hwdev)->free(hwdev, size, cpu_addr, dma_handle, attrs); + xen_get_dma_ops(hwdev)->free(hwdev, size, cpu_addr, dma_handle, attrs); } static inline void xen_dma_map_page(struct device *hwdev, struct page *page, @@ -57,7 +57,7 @@ static inline void xen_dma_map_page(struct device *hwdev, struct page *page, * specific function. */ if (local) - __generic_dma_ops(hwdev)->map_page(hwdev, page, offset, size, dir, attrs); + xen_get_dma_ops(hwdev)->map_page(hwdev, page, offset, size, dir, attrs); else __xen_dma_map_page(hwdev, page, dev_addr, offset, size, dir, attrs); } @@ -75,8 +75,8 @@ static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle, * specific function. */ if (pfn_valid(pfn)) { - if (__generic_dma_ops(hwdev)->unmap_page) - __generic_dma_ops(hwdev)->unmap_page(hwdev, handle, size, dir, attrs); + if (xen_get_dma_ops(hwdev)->unmap_page) + xen_get_dma_ops(hwdev)->unmap_page(hwdev, handle, size, dir, attrs); } else __xen_dma_unmap_page(hwdev, handle, size, dir, attrs); } @@ -86,8 +86,8 @@ static inline void xen_dma_sync_single_for_cpu(struct device *hwdev, { unsigned long pfn = PFN_DOWN(handle); if (pfn_valid(pfn)) { - if (__generic_dma_ops(hwdev)->sync_single_for_cpu) - __generic_dma_ops(hwdev)->sync_single_for_cpu(hwdev, handle, size, dir); + if (xen_get_dma_ops(hwdev)->sync_single_for_cpu) + xen_get_dma_ops(hwdev)->sync_single_for_cpu(hwdev, handle, size, dir); } else __xen_dma_sync_single_for_cpu(hwdev, handle, size, dir); } @@ -97,8 +97,8 @@ static inline void xen_dma_sync_single_for_device(struct device *hwdev, { unsigned long pfn = PFN_DOWN(handle); if (pfn_valid(pfn)) { - if (__generic_dma_ops(hwdev)->sync_single_for_device) - __generic_dma_ops(hwdev)->sync_single_for_device(hwdev, handle, size, dir); + if (xen_get_dma_ops(hwdev)->sync_single_for_device) + xen_get_dma_ops(hwdev)->sync_single_for_device(hwdev, handle, size, dir); } else __xen_dma_sync_single_for_device(hwdev, handle, size, dir); } -- cgit v1.2.3-70-g09d2 From 6483e3135a693548874429db901c0544d3a9b4cd Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Sat, 22 Apr 2017 09:21:13 +0800 Subject: xen/scsifront: use offset_in_page() macro Use offset_in_page() macro instead of open-coding. Signed-off-by: Geliang Tang Reviewed-by: Juergen Gross Signed-off-by: Juergen Gross --- drivers/scsi/xen-scsifront.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/xen-scsifront.c b/drivers/scsi/xen-scsifront.c index 9aa1fe1fc939..a6a8b60d4902 100644 --- a/drivers/scsi/xen-scsifront.c +++ b/drivers/scsi/xen-scsifront.c @@ -434,7 +434,7 @@ static int map_data_for_request(struct vscsifrnt_info *info, if (seg_grants) { page = virt_to_page(seg); - off = (unsigned long)seg & ~PAGE_MASK; + off = offset_in_page(seg); len = sizeof(struct scsiif_request_segment) * data_grants; while (len > 0) { bytes = min_t(unsigned int, len, PAGE_SIZE - off); -- cgit v1.2.3-70-g09d2 From 84d582d236dc1f9085e741affc72e9ba061a67c2 Mon Sep 17 00:00:00 2001 From: Boris Ostrovsky Date: Mon, 24 Apr 2017 15:04:53 -0400 Subject: xen: Revert commits da72ff5bfcb0 and 72a9b186292d Recent discussion (http://marc.info/?l=xen-devel&m=149192184523741) established that commit 72a9b186292d ("xen: Remove event channel notification through Xen PCI platform device") (and thus commit da72ff5bfcb0 ("partially revert "xen: Remove event channel notification through Xen PCI platform device"")) are unnecessary and, in fact, prevent HVM guests from booting on Xen releases prior to 4.0 Therefore we revert both of those commits. The summary of that discussion is below: Here is the brief summary of the current situation: Before the offending commit (72a9b186292): 1) INTx does not work because of the reset_watches path. 2) The reset_watches path is only taken if you have Xen > 4.0 3) The Linux Kernel by default will use vector inject if the hypervisor support. So even INTx does not work no body running the kernel with Xen > 4.0 would notice. Unless he explicitly disabled this feature either in the kernel or in Xen (and this can only be disabled by modifying the code, not user-supported way to do it). After the offending commit (+ partial revert): 1) INTx is no longer support for HVM (only for PV guests). 2) Any HVM guest The kernel will not boot on Xen < 4.0 which does not have vector injection support. Since the only other mode supported is INTx which. So based on this summary, I think before commit (72a9b186292) we were in much better position from a user point of view. Signed-off-by: Boris Ostrovsky Reviewed-by: Juergen Gross Signed-off-by: Juergen Gross --- arch/x86/include/asm/xen/events.h | 11 +++++++++++ arch/x86/pci/xen.c | 2 +- arch/x86/xen/enlighten_hvm.c | 12 ++++++++---- arch/x86/xen/smp_hvm.c | 5 +++++ arch/x86/xen/time.c | 8 ++++++++ drivers/xen/events/events_base.c | 25 +++++++++++++++++-------- drivers/xen/platform-pci.c | 14 ++++---------- 7 files changed, 54 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/arch/x86/include/asm/xen/events.h b/arch/x86/include/asm/xen/events.h index 608a79d5a466..e6911caf5bbf 100644 --- a/arch/x86/include/asm/xen/events.h +++ b/arch/x86/include/asm/xen/events.h @@ -20,4 +20,15 @@ static inline int xen_irqs_disabled(struct pt_regs *regs) /* No need for a barrier -- XCHG is a barrier on x86. */ #define xchg_xen_ulong(ptr, val) xchg((ptr), (val)) +extern int xen_have_vector_callback; + +/* + * Events delivered via platform PCI interrupts are always + * routed to vcpu 0 and hence cannot be rebound. + */ +static inline bool xen_support_evtchn_rebind(void) +{ + return (!xen_hvm_domain() || xen_have_vector_callback); +} + #endif /* _ASM_X86_XEN_EVENTS_H */ diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index 292ab0364a89..c4b3646bd04c 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -447,7 +447,7 @@ void __init xen_msi_init(void) int __init pci_xen_hvm_init(void) { - if (!xen_feature(XENFEAT_hvm_pirqs)) + if (!xen_have_vector_callback || !xen_feature(XENFEAT_hvm_pirqs)) return 0; #ifdef CONFIG_ACPI diff --git a/arch/x86/xen/enlighten_hvm.c b/arch/x86/xen/enlighten_hvm.c index 72df54a481d6..078c512b8720 100644 --- a/arch/x86/xen/enlighten_hvm.c +++ b/arch/x86/xen/enlighten_hvm.c @@ -18,6 +18,9 @@ #include "mmu.h" #include "smp.h" +__read_mostly int xen_have_vector_callback; +EXPORT_SYMBOL_GPL(xen_have_vector_callback); + void __ref xen_hvm_init_shared_info(void) { int cpu; @@ -123,7 +126,7 @@ static int xen_cpu_up_prepare_hvm(unsigned int cpu) per_cpu(xen_vcpu_id, cpu) = cpu; xen_vcpu_setup(cpu); - if (xen_feature(XENFEAT_hvm_safe_pvclock)) + if (xen_have_vector_callback && xen_feature(XENFEAT_hvm_safe_pvclock)) xen_setup_timer(cpu); rc = xen_smp_intr_init(cpu); @@ -139,7 +142,7 @@ static int xen_cpu_dead_hvm(unsigned int cpu) { xen_smp_intr_free(cpu); - if (xen_feature(XENFEAT_hvm_safe_pvclock)) + if (xen_have_vector_callback && xen_feature(XENFEAT_hvm_safe_pvclock)) xen_teardown_timer(cpu); return 0; @@ -156,7 +159,8 @@ static void __init xen_hvm_guest_init(void) xen_panic_handler_init(); - BUG_ON(!xen_feature(XENFEAT_hvm_callback_vector)); + if (xen_feature(XENFEAT_hvm_callback_vector)) + xen_have_vector_callback = 1; xen_hvm_smp_init(); WARN_ON(xen_cpuhp_setup(xen_cpu_up_prepare_hvm, xen_cpu_dead_hvm)); @@ -189,7 +193,7 @@ bool xen_hvm_need_lapic(void) return false; if (!xen_hvm_domain()) return false; - if (xen_feature(XENFEAT_hvm_pirqs)) + if (xen_feature(XENFEAT_hvm_pirqs) && xen_have_vector_callback) return false; return true; } diff --git a/arch/x86/xen/smp_hvm.c b/arch/x86/xen/smp_hvm.c index 8bed434cd7d7..f18561bbf5c9 100644 --- a/arch/x86/xen/smp_hvm.c +++ b/arch/x86/xen/smp_hvm.c @@ -1,5 +1,7 @@ #include +#include + #include "xen-ops.h" #include "smp.h" @@ -49,6 +51,9 @@ static void xen_hvm_cpu_die(unsigned int cpu) void __init xen_hvm_smp_init(void) { + if (!xen_have_vector_callback) + return; + smp_ops.smp_prepare_cpus = xen_hvm_smp_prepare_cpus; smp_ops.smp_send_reschedule = xen_smp_send_reschedule; smp_ops.cpu_die = xen_hvm_cpu_die; diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c index 7a3089285c59..090c7eb4dca9 100644 --- a/arch/x86/xen/time.c +++ b/arch/x86/xen/time.c @@ -436,6 +436,14 @@ static void xen_hvm_setup_cpu_clockevents(void) void __init xen_hvm_init_time_ops(void) { + /* + * vector callback is needed otherwise we cannot receive interrupts + * on cpu > 0 and at this point we don't know how many cpus are + * available. + */ + if (!xen_have_vector_callback) + return; + if (!xen_feature(XENFEAT_hvm_safe_pvclock)) { printk(KERN_INFO "Xen doesn't support pvclock on HVM," "disable pv timer\n"); diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c index 6a53577772c9..b52852f38cff 100644 --- a/drivers/xen/events/events_base.c +++ b/drivers/xen/events/events_base.c @@ -1312,6 +1312,9 @@ static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu) if (!VALID_EVTCHN(evtchn)) return -1; + if (!xen_support_evtchn_rebind()) + return -1; + /* Send future instances of this interrupt to other vcpu. */ bind_vcpu.port = evtchn; bind_vcpu.vcpu = xen_vcpu_nr(tcpu); @@ -1646,14 +1649,20 @@ void xen_callback_vector(void) int rc; uint64_t callback_via; - callback_via = HVM_CALLBACK_VECTOR(HYPERVISOR_CALLBACK_VECTOR); - rc = xen_set_callback_via(callback_via); - BUG_ON(rc); - pr_info("Xen HVM callback vector for event delivery is enabled\n"); - /* in the restore case the vector has already been allocated */ - if (!test_bit(HYPERVISOR_CALLBACK_VECTOR, used_vectors)) - alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, - xen_hvm_callback_vector); + if (xen_have_vector_callback) { + callback_via = HVM_CALLBACK_VECTOR(HYPERVISOR_CALLBACK_VECTOR); + rc = xen_set_callback_via(callback_via); + if (rc) { + pr_err("Request for Xen HVM callback vector failed\n"); + xen_have_vector_callback = 0; + return; + } + pr_info("Xen HVM callback vector for event delivery is enabled\n"); + /* in the restore case the vector has already been allocated */ + if (!test_bit(HYPERVISOR_CALLBACK_VECTOR, used_vectors)) + alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, + xen_hvm_callback_vector); + } } #else void xen_callback_vector(void) {} diff --git a/drivers/xen/platform-pci.c b/drivers/xen/platform-pci.c index 2a165cc8a43c..1275df83070f 100644 --- a/drivers/xen/platform-pci.c +++ b/drivers/xen/platform-pci.c @@ -90,8 +90,10 @@ static int xen_allocate_irq(struct pci_dev *pdev) static int platform_pci_resume(struct pci_dev *pdev) { int err; - if (!xen_pv_domain()) + + if (xen_have_vector_callback) return 0; + err = xen_set_callback_via(callback_via); if (err) { dev_err(&pdev->dev, "platform_pci_resume failure!\n"); @@ -137,15 +139,7 @@ static int platform_pci_probe(struct pci_dev *pdev, platform_mmio = mmio_addr; platform_mmiolen = mmio_len; - - /* - * Xen HVM guests always use the vector callback mechanism. - * L1 Dom0 in a nested Xen environment is a PV guest inside in an - * HVM environment. It needs the platform-pci driver to get - * notifications from L0 Xen, but it cannot use the vector callback - * as it is not exported by L1 Xen. - */ - if (xen_pv_domain()) { + if (!xen_have_vector_callback) { ret = xen_allocate_irq(pdev); if (ret) { dev_warn(&pdev->dev, "request_irq failed err=%d\n", ret); -- cgit v1.2.3-70-g09d2 From e371fd7607999fabbd955b4d22c8e912594a7997 Mon Sep 17 00:00:00 2001 From: Julien Grall Date: Mon, 24 Apr 2017 18:58:39 +0100 Subject: xen: Implement EFI reset_system callback When rebooting DOM0 with ACPI on ARM64, the kernel is crashing with the stack trace [1]. This is happening because when EFI runtimes are enabled, the reset code (see machine_restart) will first try to use EFI restart method. However, the EFI restart code is expecting the reset_system callback to be always set. This is not the case for Xen and will lead to crash. The EFI restart helper is used in multiple places and some of them don't not have fallback (see machine_power_off). So implement reset_system callback as a call to xen_reboot when using EFI Xen. [ 36.999270] reboot: Restarting system [ 37.002921] Internal error: Attempting to execute userspace memory: 86000004 [#1] PREEMPT SMP [ 37.011460] Modules linked in: [ 37.014598] CPU: 0 PID: 1 Comm: systemd-shutdow Not tainted 4.11.0-rc1-00003-g1e248b60a39b-dirty #506 [ 37.023903] Hardware name: (null) (DT) [ 37.027734] task: ffff800902068000 task.stack: ffff800902064000 [ 37.033739] PC is at 0x0 [ 37.036359] LR is at efi_reboot+0x94/0xd0 [ 37.040438] pc : [<0000000000000000>] lr : [] pstate: 404001c5 [ 37.047920] sp : ffff800902067cf0 [ 37.051314] x29: ffff800902067cf0 x28: ffff800902068000 [ 37.056709] x27: ffff000008992000 x26: 000000000000008e [ 37.062104] x25: 0000000000000123 x24: 0000000000000015 [ 37.067499] x23: 0000000000000000 x22: ffff000008e6e250 [ 37.072894] x21: ffff000008e6e000 x20: 0000000000000000 [ 37.078289] x19: ffff000008e5d4c8 x18: 0000000000000010 [ 37.083684] x17: 0000ffffa7c27470 x16: 00000000deadbeef [ 37.089079] x15: 0000000000000006 x14: ffff000088f42bef [ 37.094474] x13: ffff000008f42bfd x12: ffff000008e706c0 [ 37.099870] x11: ffff000008e70000 x10: 0000000005f5e0ff [ 37.105265] x9 : ffff800902067a50 x8 : 6974726174736552 [ 37.110660] x7 : ffff000008cc6fb8 x6 : ffff000008cc6fb0 [ 37.116055] x5 : ffff000008c97dd8 x4 : 0000000000000000 [ 37.121453] x3 : 0000000000000000 x2 : 0000000000000000 [ 37.126845] x1 : 0000000000000000 x0 : 0000000000000000 [ 37.132239] [ 37.133808] Process systemd-shutdow (pid: 1, stack limit = 0xffff800902064000) [ 37.141118] Stack: (0xffff800902067cf0 to 0xffff800902068000) [ 37.146949] 7ce0: ffff800902067d40 ffff000008085334 [ 37.154869] 7d00: 0000000000000000 ffff000008f3b000 ffff800902067d40 ffff0000080852e0 [ 37.162787] 7d20: ffff000008cc6fb0 ffff000008cc6fb8 ffff000008c7f580 ffff000008c97dd8 [ 37.170706] 7d40: ffff800902067d60 ffff0000080e2c2c 0000000000000000 0000000001234567 [ 37.178624] 7d60: ffff800902067d80 ffff0000080e2ee8 0000000000000000 ffff0000080e2df4 [ 37.186544] 7d80: 0000000000000000 ffff0000080830f0 0000000000000000 00008008ff1c1000 [ 37.194462] 7da0: ffffffffffffffff 0000ffffa7c4b1cc 0000000000000000 0000000000000024 [ 37.202380] 7dc0: ffff800902067dd0 0000000000000005 0000fffff24743c8 0000000000000004 [ 37.210299] 7de0: 0000fffff2475f03 0000000000000010 0000fffff2474418 0000000000000005 [ 37.218218] 7e00: 0000fffff2474578 000000000000000a 0000aaaad6b722c0 0000000000000001 [ 37.226136] 7e20: 0000000000000123 0000000000000038 ffff800902067e50 ffff0000081e7294 [ 37.234055] 7e40: ffff800902067e60 ffff0000081e935c ffff800902067e60 ffff0000081e9388 [ 37.241973] 7e60: ffff800902067eb0 ffff0000081ea388 0000000000000000 00008008ff1c1000 [ 37.249892] 7e80: ffffffffffffffff 0000ffffa7c4a79c 0000000000000000 ffff000000020000 [ 37.257810] 7ea0: 0000010000000004 0000000000000000 0000000000000000 ffff0000080830f0 [ 37.265729] 7ec0: fffffffffee1dead 0000000028121969 0000000001234567 0000000000000000 [ 37.273651] 7ee0: ffffffffffffffff 8080000000800000 0000800000008080 feffa9a9d4ff2d66 [ 37.281567] 7f00: 000000000000008e feffa9a9d5b60e0f 7f7fffffffff7f7f 0101010101010101 [ 37.289485] 7f20: 0000000000000010 0000000000000008 000000000000003a 0000ffffa7ccf588 [ 37.297404] 7f40: 0000aaaad6b87d00 0000ffffa7c4b1b0 0000fffff2474be0 0000aaaad6b88000 [ 37.305326] 7f60: 0000fffff2474fb0 0000000001234567 0000000000000000 0000000000000000 [ 37.313240] 7f80: 0000000000000000 0000000000000001 0000aaaad6b70d4d 0000000000000000 [ 37.321159] 7fa0: 0000000000000001 0000fffff2474ea0 0000aaaad6b5e2e0 0000fffff2474e80 [ 37.329078] 7fc0: 0000ffffa7c4b1cc 0000000000000000 fffffffffee1dead 000000000000008e [ 37.336997] 7fe0: 0000000000000000 0000000000000000 9ce839cffee77eab fafdbf9f7ed57f2f [ 37.344911] Call trace: [ 37.347437] Exception stack(0xffff800902067b20 to 0xffff800902067c50) [ 37.353970] 7b20: ffff000008e5d4c8 0001000000000000 0000000080f82000 0000000000000000 [ 37.361883] 7b40: ffff800902067b60 ffff000008e17000 ffff000008f44c68 00000001081081b4 [ 37.369802] 7b60: ffff800902067bf0 ffff000008108478 0000000000000000 ffff000008c235b0 [ 37.377721] 7b80: ffff800902067ce0 0000000000000000 0000000000000000 0000000000000015 [ 37.385643] 7ba0: 0000000000000123 000000000000008e ffff000008992000 ffff800902068000 [ 37.393557] 7bc0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 [ 37.401477] 7be0: 0000000000000000 ffff000008c97dd8 ffff000008cc6fb0 ffff000008cc6fb8 [ 37.409396] 7c00: 6974726174736552 ffff800902067a50 0000000005f5e0ff ffff000008e70000 [ 37.417318] 7c20: ffff000008e706c0 ffff000008f42bfd ffff000088f42bef 0000000000000006 [ 37.425234] 7c40: 00000000deadbeef 0000ffffa7c27470 [ 37.430190] [< (null)>] (null) [ 37.434982] [] machine_restart+0x6c/0x70 [ 37.440550] [] kernel_restart+0x6c/0x78 [ 37.446030] [] SyS_reboot+0x130/0x228 [ 37.451337] [] el0_svc_naked+0x24/0x28 [ 37.456737] Code: bad PC value [ 37.459891] ---[ end trace 76e2fc17e050aecd ]--- Signed-off-by: Julien Grall -- Cc: Boris Ostrovsky Cc: Juergen Gross Cc: Thomas Gleixner Cc: Ingo Molnar Cc: "H. Peter Anvin" Cc: x86@kernel.org The x86 code has theoritically a similar issue, altought EFI does not seem to be the preferred method. I have only built test it on x86. This should also probably be fixed in stable tree. Changes in v2: - Implement xen_efi_reset_system using xen_reboot - Move xen_efi_reset_system in drivers/xen/efi.c Signed-off-by: Juergen Gross --- arch/arm/xen/efi.c | 2 +- arch/x86/xen/efi.c | 2 +- drivers/xen/efi.c | 18 ++++++++++++++++++ include/xen/xen-ops.h | 3 +++ 4 files changed, 23 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/arch/arm/xen/efi.c b/arch/arm/xen/efi.c index 16db419f9e90..b4d78959cadf 100644 --- a/arch/arm/xen/efi.c +++ b/arch/arm/xen/efi.c @@ -35,6 +35,6 @@ void __init xen_efi_runtime_setup(void) 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. */ + efi.reset_system = xen_efi_reset_system; } EXPORT_SYMBOL_GPL(xen_efi_runtime_setup); diff --git a/arch/x86/xen/efi.c b/arch/x86/xen/efi.c index 3be012115853..30bb2e80cfe7 100644 --- a/arch/x86/xen/efi.c +++ b/arch/x86/xen/efi.c @@ -81,7 +81,7 @@ static const struct efi efi_xen __initconst = { .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. */ + .reset_system = xen_efi_reset_system, .set_virtual_address_map = NULL, /* Not used under Xen. */ .flags = 0 /* Initialized later. */ }; diff --git a/drivers/xen/efi.c b/drivers/xen/efi.c index 22f71ffd3406..9243a9051078 100644 --- a/drivers/xen/efi.c +++ b/drivers/xen/efi.c @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -263,3 +264,20 @@ efi_status_t xen_efi_query_capsule_caps(efi_capsule_header_t **capsules, return efi_data(op).status; } EXPORT_SYMBOL_GPL(xen_efi_query_capsule_caps); + +void xen_efi_reset_system(int reset_type, efi_status_t status, + unsigned long data_size, efi_char16_t *data) +{ + switch (reset_type) { + case EFI_RESET_COLD: + case EFI_RESET_WARM: + xen_reboot(SHUTDOWN_reboot); + break; + case EFI_RESET_SHUTDOWN: + xen_reboot(SHUTDOWN_poweroff); + break; + default: + BUG(); + } +} +EXPORT_SYMBOL_GPL(xen_efi_reset_system); diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h index 5060805058a4..c44a2ee8c8f8 100644 --- a/include/xen/xen-ops.h +++ b/include/xen/xen-ops.h @@ -136,6 +136,9 @@ efi_status_t xen_efi_update_capsule(efi_capsule_header_t **capsules, efi_status_t xen_efi_query_capsule_caps(efi_capsule_header_t **capsules, unsigned long count, u64 *max_size, int *reset_type); +void xen_efi_reset_system(int reset_type, efi_status_t status, + unsigned long data_size, efi_char16_t *data); + #ifdef CONFIG_PREEMPT -- cgit v1.2.3-70-g09d2