Commit f6702681 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-linus-4.3b-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip

Pull xen bug fixes from David Vrabel:

 - Fix VM save performance regression with x86 PV guests

 - Make kexec work in x86 PVHVM guests (if Xen has the soft-reset ABI)

 - Other minor fixes.

* tag 'for-linus-4.3b-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip:
  x86/xen/p2m: hint at the last populated P2M entry
  x86/xen: Do not clip xen_e820_map to xen_e820_map_entries when sanitizing map
  x86/xen: Support kexec/kdump in HVM guests by doing a soft reset
  xen/x86: Don't try to write syscall-related MSRs for PV guests
  xen: use correct type for HYPERVISOR_memory_op()
parents 3ec20e2e 98dd166e
...@@ -336,10 +336,10 @@ HYPERVISOR_update_descriptor(u64 ma, u64 desc) ...@@ -336,10 +336,10 @@ HYPERVISOR_update_descriptor(u64 ma, u64 desc)
return _hypercall4(int, update_descriptor, ma, ma>>32, desc, desc>>32); return _hypercall4(int, update_descriptor, ma, ma>>32, desc, desc>>32);
} }
static inline int static inline long
HYPERVISOR_memory_op(unsigned int cmd, void *arg) HYPERVISOR_memory_op(unsigned int cmd, void *arg)
{ {
return _hypercall2(int, memory_op, cmd, arg); return _hypercall2(long, memory_op, cmd, arg);
} }
static inline int static inline int
......
...@@ -33,6 +33,10 @@ ...@@ -33,6 +33,10 @@
#include <linux/memblock.h> #include <linux/memblock.h>
#include <linux/edd.h> #include <linux/edd.h>
#ifdef CONFIG_KEXEC_CORE
#include <linux/kexec.h>
#endif
#include <xen/xen.h> #include <xen/xen.h>
#include <xen/events.h> #include <xen/events.h>
#include <xen/interface/xen.h> #include <xen/interface/xen.h>
...@@ -1077,6 +1081,7 @@ static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high) ...@@ -1077,6 +1081,7 @@ static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high)
/* Fast syscall setup is all done in hypercalls, so /* Fast syscall setup is all done in hypercalls, so
these are all ignored. Stub them out here to stop these are all ignored. Stub them out here to stop
Xen console noise. */ Xen console noise. */
break;
default: default:
if (!pmu_msr_write(msr, low, high, &ret)) if (!pmu_msr_write(msr, low, high, &ret))
...@@ -1807,6 +1812,21 @@ static struct notifier_block xen_hvm_cpu_notifier = { ...@@ -1807,6 +1812,21 @@ static struct notifier_block xen_hvm_cpu_notifier = {
.notifier_call = xen_hvm_cpu_notify, .notifier_call = xen_hvm_cpu_notify,
}; };
#ifdef CONFIG_KEXEC_CORE
static void xen_hvm_shutdown(void)
{
native_machine_shutdown();
if (kexec_in_progress)
xen_reboot(SHUTDOWN_soft_reset);
}
static void xen_hvm_crash_shutdown(struct pt_regs *regs)
{
native_machine_crash_shutdown(regs);
xen_reboot(SHUTDOWN_soft_reset);
}
#endif
static void __init xen_hvm_guest_init(void) static void __init xen_hvm_guest_init(void)
{ {
if (xen_pv_domain()) if (xen_pv_domain())
...@@ -1826,6 +1846,10 @@ static void __init xen_hvm_guest_init(void) ...@@ -1826,6 +1846,10 @@ static void __init xen_hvm_guest_init(void)
x86_init.irqs.intr_init = xen_init_IRQ; x86_init.irqs.intr_init = xen_init_IRQ;
xen_hvm_init_time_ops(); xen_hvm_init_time_ops();
xen_hvm_init_mmu_ops(); xen_hvm_init_mmu_ops();
#ifdef CONFIG_KEXEC_CORE
machine_ops.shutdown = xen_hvm_shutdown;
machine_ops.crash_shutdown = xen_hvm_crash_shutdown;
#endif
} }
#endif #endif
......
...@@ -112,6 +112,15 @@ static unsigned long *p2m_identity; ...@@ -112,6 +112,15 @@ static unsigned long *p2m_identity;
static pte_t *p2m_missing_pte; static pte_t *p2m_missing_pte;
static pte_t *p2m_identity_pte; static pte_t *p2m_identity_pte;
/*
* Hint at last populated PFN.
*
* Used to set HYPERVISOR_shared_info->arch.max_pfn so the toolstack
* can avoid scanning the whole P2M (which may be sized to account for
* hotplugged memory).
*/
static unsigned long xen_p2m_last_pfn;
static inline unsigned p2m_top_index(unsigned long pfn) static inline unsigned p2m_top_index(unsigned long pfn)
{ {
BUG_ON(pfn >= MAX_P2M_PFN); BUG_ON(pfn >= MAX_P2M_PFN);
...@@ -270,7 +279,7 @@ void xen_setup_mfn_list_list(void) ...@@ -270,7 +279,7 @@ void xen_setup_mfn_list_list(void)
else else
HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list = HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
virt_to_mfn(p2m_top_mfn); virt_to_mfn(p2m_top_mfn);
HYPERVISOR_shared_info->arch.max_pfn = xen_max_p2m_pfn; HYPERVISOR_shared_info->arch.max_pfn = xen_p2m_last_pfn;
HYPERVISOR_shared_info->arch.p2m_generation = 0; HYPERVISOR_shared_info->arch.p2m_generation = 0;
HYPERVISOR_shared_info->arch.p2m_vaddr = (unsigned long)xen_p2m_addr; HYPERVISOR_shared_info->arch.p2m_vaddr = (unsigned long)xen_p2m_addr;
HYPERVISOR_shared_info->arch.p2m_cr3 = HYPERVISOR_shared_info->arch.p2m_cr3 =
...@@ -406,6 +415,8 @@ void __init xen_vmalloc_p2m_tree(void) ...@@ -406,6 +415,8 @@ void __init xen_vmalloc_p2m_tree(void)
static struct vm_struct vm; static struct vm_struct vm;
unsigned long p2m_limit; unsigned long p2m_limit;
xen_p2m_last_pfn = xen_max_p2m_pfn;
p2m_limit = (phys_addr_t)P2M_LIMIT * 1024 * 1024 * 1024 / PAGE_SIZE; p2m_limit = (phys_addr_t)P2M_LIMIT * 1024 * 1024 * 1024 / PAGE_SIZE;
vm.flags = VM_ALLOC; vm.flags = VM_ALLOC;
vm.size = ALIGN(sizeof(unsigned long) * max(xen_max_p2m_pfn, p2m_limit), vm.size = ALIGN(sizeof(unsigned long) * max(xen_max_p2m_pfn, p2m_limit),
...@@ -608,6 +619,12 @@ static bool alloc_p2m(unsigned long pfn) ...@@ -608,6 +619,12 @@ static bool alloc_p2m(unsigned long pfn)
free_p2m_page(p2m); free_p2m_page(p2m);
} }
/* Expanded the p2m? */
if (pfn > xen_p2m_last_pfn) {
xen_p2m_last_pfn = pfn;
HYPERVISOR_shared_info->arch.max_pfn = xen_p2m_last_pfn;
}
return true; return true;
} }
......
...@@ -548,7 +548,7 @@ static unsigned long __init xen_get_max_pages(void) ...@@ -548,7 +548,7 @@ static unsigned long __init xen_get_max_pages(void)
{ {
unsigned long max_pages, limit; unsigned long max_pages, limit;
domid_t domid = DOMID_SELF; domid_t domid = DOMID_SELF;
int ret; long ret;
limit = xen_get_pages_limit(); limit = xen_get_pages_limit();
max_pages = limit; max_pages = limit;
...@@ -798,7 +798,7 @@ char * __init xen_memory_setup(void) ...@@ -798,7 +798,7 @@ char * __init xen_memory_setup(void)
xen_ignore_unusable(); xen_ignore_unusable();
/* Make sure the Xen-supplied memory map is well-ordered. */ /* Make sure the Xen-supplied memory map is well-ordered. */
sanitize_e820_map(xen_e820_map, xen_e820_map_entries, sanitize_e820_map(xen_e820_map, ARRAY_SIZE(xen_e820_map),
&xen_e820_map_entries); &xen_e820_map_entries);
max_pages = xen_get_max_pages(); max_pages = xen_get_max_pages();
......
...@@ -107,5 +107,13 @@ struct sched_watchdog { ...@@ -107,5 +107,13 @@ struct sched_watchdog {
#define SHUTDOWN_suspend 2 /* Clean up, save suspend info, kill. */ #define SHUTDOWN_suspend 2 /* Clean up, save suspend info, kill. */
#define SHUTDOWN_crash 3 /* Tell controller we've crashed. */ #define SHUTDOWN_crash 3 /* Tell controller we've crashed. */
#define SHUTDOWN_watchdog 4 /* Restart because watchdog time expired. */ #define SHUTDOWN_watchdog 4 /* Restart because watchdog time expired. */
/*
* Domain asked to perform 'soft reset' for it. The expected behavior is to
* reset internal Xen state for the domain returning it to the point where it
* was created but leaving the domain's memory contents and vCPU contexts
* intact. This will allow the domain to start over and set up all Xen specific
* interfaces again.
*/
#define SHUTDOWN_soft_reset 5
#endif /* __XEN_PUBLIC_SCHED_H__ */ #endif /* __XEN_PUBLIC_SCHED_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment