Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 541efb76 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'for-linus-4.9-rc0-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip

Pull xen updates from David Vrabel:
 "xen features and fixes for 4.9:

   - switch to new CPU hotplug mechanism

   - support driver_override in pciback

   - require vector callback for HVM guests (the alternate mechanism via
     the platform device has been broken for ages)"

* tag 'for-linus-4.9-rc0-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip:
  xen/x86: Update topology map for PV VCPUs
  xen/x86: Initialize per_cpu(xen_vcpu, 0) a little earlier
  xen/pciback: support driver_override
  xen/pciback: avoid multiple entries in slot list
  xen/pciback: simplify pcistub device handling
  xen: Remove event channel notification through Xen PCI platform device
  xen/events: Convert to hotplug state machine
  xen/x86: Convert to hotplug state machine
  x86/xen: add missing \n at end of printk warning message
  xen/grant-table: Use kmalloc_array() in arch_gnttab_valloc()
  xen: Make VPMU init message look less scary
  xen: rename xen_pmu_init() in sys-hypervisor.c
  hotplug: Prevent alloc/free of irq descriptors during cpu up/down (again)
  xen/x86: Move irq allocation from Xen smp_op.cpu_up()
parents 6218590b a6a198bc
Loading
Loading
Loading
Loading
+0 −11
Original line number Diff line number Diff line
@@ -20,15 +20,4 @@ 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 */
+1 −1
Original line number Diff line number Diff line
@@ -456,7 +456,7 @@ void __init xen_msi_init(void)

int __init pci_xen_hvm_init(void)
{
	if (!xen_have_vector_callback || !xen_feature(XENFEAT_hvm_pirqs))
	if (!xen_feature(XENFEAT_hvm_pirqs))
		return 0;

#ifdef CONFIG_ACPI
+68 −26
Original line number Diff line number Diff line
@@ -137,8 +137,10 @@ struct shared_info xen_dummy_shared_info;
void *xen_initial_gdt;

RESERVE_BRK(shared_info_page_brk, PAGE_SIZE);
__read_mostly int xen_have_vector_callback;
EXPORT_SYMBOL_GPL(xen_have_vector_callback);

static int xen_cpu_up_prepare(unsigned int cpu);
static int xen_cpu_up_online(unsigned int cpu);
static int xen_cpu_dead(unsigned int cpu);

/*
 * Point at some empty memory to start with. We map the real shared_info
@@ -1519,10 +1521,7 @@ static void __init xen_pvh_early_guest_init(void)
	if (!xen_feature(XENFEAT_auto_translated_physmap))
		return;

	if (!xen_feature(XENFEAT_hvm_callback_vector))
		return;

	xen_have_vector_callback = 1;
	BUG_ON(!xen_feature(XENFEAT_hvm_callback_vector));

	xen_pvh_early_cpu_init(0, false);
	xen_pvh_set_cr_flags(0);
@@ -1538,6 +1537,24 @@ static void __init xen_dom0_set_legacy_features(void)
	x86_platform.legacy.rtc = 1;
}

static int xen_cpuhp_setup(void)
{
	int rc;

	rc = cpuhp_setup_state_nocalls(CPUHP_XEN_PREPARE,
				       "XEN_HVM_GUEST_PREPARE",
				       xen_cpu_up_prepare, xen_cpu_dead);
	if (rc >= 0) {
		rc = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
					       "XEN_HVM_GUEST_ONLINE",
					       xen_cpu_up_online, NULL);
		if (rc < 0)
			cpuhp_remove_state_nocalls(CPUHP_XEN_PREPARE);
	}

	return rc >= 0 ? 0 : rc;
}

/* First C function to be called on Xen boot */
asmlinkage __visible void __init xen_start_kernel(void)
{
@@ -1639,6 +1656,8 @@ asmlinkage __visible void __init xen_start_kernel(void)
	   possible map and a non-dummy shared_info. */
	per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0];

	WARN_ON(xen_cpuhp_setup());

	local_irq_disable();
	early_boot_irqs_disabled = true;

@@ -1819,31 +1838,54 @@ static void __init init_hvm_pv_info(void)
	xen_domain_type = XEN_HVM_DOMAIN;
}

static int xen_hvm_cpu_notify(struct notifier_block *self, unsigned long action,
			      void *hcpu)
static int xen_cpu_up_prepare(unsigned int cpu)
{
	int cpu = (long)hcpu;
	switch (action) {
	case CPU_UP_PREPARE:
	int rc;

	if (xen_hvm_domain()) {
		/*
		 * This can happen if CPU was offlined earlier and
		 * offlining timed out in common_cpu_die().
		 */
		if (cpu_report_state(cpu) == CPU_DEAD_FROZEN) {
			xen_smp_intr_free(cpu);
			xen_uninit_lock_cpu(cpu);
		}

		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))
	}

	if (xen_pv_domain() || xen_feature(XENFEAT_hvm_safe_pvclock))
		xen_setup_timer(cpu);

	rc = xen_smp_intr_init(cpu);
	if (rc) {
		WARN(1, "xen_smp_intr_init() for CPU %d failed: %d\n",
		     cpu, rc);
		return rc;
	}
		break;
	default:
		break;
	return 0;
}
	return NOTIFY_OK;

static int xen_cpu_dead(unsigned int cpu)
{
	xen_smp_intr_free(cpu);

	if (xen_pv_domain() || xen_feature(XENFEAT_hvm_safe_pvclock))
		xen_teardown_timer(cpu);

	return 0;
}

static struct notifier_block xen_hvm_cpu_notifier = {
	.notifier_call	= xen_hvm_cpu_notify,
};
static int xen_cpu_up_online(unsigned int cpu)
{
	xen_init_lock_cpu(cpu);
	return 0;
}

#ifdef CONFIG_KEXEC_CORE
static void xen_hvm_shutdown(void)
@@ -1871,10 +1913,10 @@ static void __init xen_hvm_guest_init(void)

	xen_panic_handler_init();

	if (xen_feature(XENFEAT_hvm_callback_vector))
		xen_have_vector_callback = 1;
	BUG_ON(!xen_feature(XENFEAT_hvm_callback_vector));

	xen_hvm_smp_init();
	register_cpu_notifier(&xen_hvm_cpu_notifier);
	WARN_ON(xen_cpuhp_setup());
	xen_unplug_emulated_devices();
	x86_init.irqs.intr_init = xen_init_IRQ;
	xen_hvm_init_time_ops();
@@ -1910,7 +1952,7 @@ bool xen_hvm_need_lapic(void)
		return false;
	if (!xen_hvm_domain())
		return false;
	if (xen_feature(XENFEAT_hvm_pirqs) && xen_have_vector_callback)
	if (xen_feature(XENFEAT_hvm_pirqs))
		return false;
	return true;
}
+1 −1
Original line number Diff line number Diff line
@@ -89,7 +89,7 @@ void arch_gnttab_unmap(void *shared, unsigned long nr_gframes)

static int arch_gnttab_valloc(struct gnttab_vm_area *area, unsigned nr_frames)
{
	area->ptes = kmalloc(sizeof(pte_t *) * nr_frames, GFP_KERNEL);
	area->ptes = kmalloc_array(nr_frames, sizeof(*area->ptes), GFP_KERNEL);
	if (area->ptes == NULL)
		return -ENOMEM;

+1 −1
Original line number Diff line number Diff line
@@ -61,7 +61,7 @@ static int check_platform_magic(void)
		}
		break;
	default:
		printk(KERN_WARNING "Xen Platform PCI: unknown I/O protocol version");
		printk(KERN_WARNING "Xen Platform PCI: unknown I/O protocol version\n");
		return XEN_PLATFORM_ERR_PROTOCOL;
	}

Loading