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

Commit 896ea17d authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'stable/for-linus-3.8-rc0-tag' of...

Merge tag 'stable/for-linus-3.8-rc0-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen

Pull Xen updates from Konrad Rzeszutek Wilk:
 - Add necessary infrastructure to make balloon driver work under ARM.
 - Add /dev/xen/privcmd interfaces to work with ARM and PVH.
 - Improve Xen PCIBack wild-card parsing.
 - Add Xen ACPI PAD (Processor Aggregator) support - so can offline/
   online sockets depending on the power consumption.
 - PVHVM + kexec = use an E820_RESV region for the shared region so we
   don't overwrite said region during kexec reboot.
 - Cleanups, compile fixes.

Fix up some trivial conflicts due to the balloon driver now working on
ARM, and there were changes next to the previous work-arounds that are
now gone.

* tag 'stable/for-linus-3.8-rc0-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen:
  xen/PVonHVM: fix compile warning in init_hvm_pv_info
  xen: arm: implement remap interfaces needed for privcmd mappings.
  xen: correctly use xen_pfn_t in remap_domain_mfn_range.
  xen: arm: enable balloon driver
  xen: balloon: allow PVMMU interfaces to be compiled out
  xen: privcmd: support autotranslated physmap guests.
  xen: add pages parameter to xen_remap_domain_mfn_range
  xen/acpi: Move the xen_running_on_version_or_later function.
  xen/xenbus: Remove duplicate inclusion of asm/xen/hypervisor.h
  xen/acpi: Fix compile error by missing decleration for xen_domain.
  xen/acpi: revert pad config check in xen_check_mwait
  xen/acpi: ACPI PAD driver
  xen-pciback: reject out of range inputs
  xen-pciback: simplify and tighten parsing of device IDs
  xen PVonHVM: use E820_Reserved area for shared_info
parents c7708fac 6a7ed405
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ DEFINE_GUEST_HANDLE(void);
DEFINE_GUEST_HANDLE(uint64_t);
DEFINE_GUEST_HANDLE(uint32_t);
DEFINE_GUEST_HANDLE(xen_pfn_t);
DEFINE_GUEST_HANDLE(xen_ulong_t);

/* Maximum number of virtual CPUs in multi-processor guests. */
#define MAX_VIRT_CPUS 1
+102 −21
Original line number Diff line number Diff line
@@ -8,6 +8,8 @@
#include <xen/features.h>
#include <xen/platform_pci.h>
#include <xen/xenbus.h>
#include <xen/page.h>
#include <xen/xen-ops.h>
#include <asm/xen/hypervisor.h>
#include <asm/xen/hypercall.h>
#include <linux/interrupt.h>
@@ -17,6 +19,8 @@
#include <linux/of_irq.h>
#include <linux/of_address.h>

#include <linux/mm.h>

struct start_info _xen_start_info;
struct start_info *xen_start_info = &_xen_start_info;
EXPORT_SYMBOL_GPL(xen_start_info);
@@ -29,6 +33,10 @@ struct shared_info *HYPERVISOR_shared_info = (void *)&xen_dummy_shared_info;

DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu);

/* 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;

/* TODO: to be removed */
__read_mostly int xen_have_vector_callback;
EXPORT_SYMBOL_GPL(xen_have_vector_callback);
@@ -38,15 +46,106 @@ EXPORT_SYMBOL_GPL(xen_platform_pci_unplug);

static __read_mostly int xen_events_irq = -1;

/* map fgmfn of domid to lpfn in the current domain */
static int map_foreign_page(unsigned long lpfn, unsigned long fgmfn,
			    unsigned int domid)
{
	int rc;
	struct xen_add_to_physmap_range xatp = {
		.domid = DOMID_SELF,
		.foreign_domid = domid,
		.size = 1,
		.space = XENMAPSPACE_gmfn_foreign,
	};
	xen_ulong_t idx = fgmfn;
	xen_pfn_t gpfn = lpfn;

	set_xen_guest_handle(xatp.idxs, &idx);
	set_xen_guest_handle(xatp.gpfns, &gpfn);

	rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap_range, &xatp);
	if (rc) {
		pr_warn("Failed to map pfn to mfn rc:%d pfn:%lx mfn:%lx\n",
			rc, lpfn, fgmfn);
		return 1;
	}
	return 0;
}

struct remap_data {
	xen_pfn_t fgmfn; /* foreign domain's gmfn */
	pgprot_t prot;
	domid_t  domid;
	struct vm_area_struct *vma;
	int index;
	struct page **pages;
	struct xen_remap_mfn_info *info;
};

static int remap_pte_fn(pte_t *ptep, pgtable_t token, unsigned long addr,
			void *data)
{
	struct remap_data *info = data;
	struct page *page = info->pages[info->index++];
	unsigned long pfn = page_to_pfn(page);
	pte_t pte = pfn_pte(pfn, info->prot);

	if (map_foreign_page(pfn, info->fgmfn, info->domid))
		return -EFAULT;
	set_pte_at(info->vma->vm_mm, addr, ptep, pte);

	return 0;
}

int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
			       unsigned long addr,
			       unsigned long mfn, int nr,
			       pgprot_t prot, unsigned domid)
			       xen_pfn_t mfn, int nr,
			       pgprot_t prot, unsigned domid,
			       struct page **pages)
{
	return -ENOSYS;
	int err;
	struct remap_data data;

	/* TBD: Batching, current sole caller only does page at a time */
	if (nr > 1)
		return -EINVAL;

	data.fgmfn = mfn;
	data.prot = prot;
	data.domid = domid;
	data.vma = vma;
	data.index = 0;
	data.pages = pages;
	err = apply_to_page_range(vma->vm_mm, addr, nr << PAGE_SHIFT,
				  remap_pte_fn, &data);
	return err;
}
EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range);

int xen_unmap_domain_mfn_range(struct vm_area_struct *vma,
			       int nr, struct page **pages)
{
	int i;

	for (i = 0; i < nr; i++) {
		struct xen_remove_from_physmap xrp;
		unsigned long rc, pfn;

		pfn = page_to_pfn(pages[i]);

		xrp.domid = DOMID_SELF;
		xrp.gpfn = pfn;
		rc = HYPERVISOR_memory_op(XENMEM_remove_from_physmap, &xrp);
		if (rc) {
			pr_warn("Failed to unmap pfn:%lx rc:%ld\n",
				pfn, rc);
			return rc;
		}
	}
	return 0;
}
EXPORT_SYMBOL_GPL(xen_unmap_domain_mfn_range);

/*
 * see Documentation/devicetree/bindings/arm/xen.txt for the
 * documentation of the Xen Device Tree format.
@@ -149,24 +248,6 @@ static int __init xen_init_events(void)
}
postcore_initcall(xen_init_events);

/* XXX: only until balloon is properly working */
int alloc_xenballooned_pages(int nr_pages, struct page **pages, bool highmem)
{
	*pages = alloc_pages(highmem ? GFP_HIGHUSER : GFP_KERNEL,
			get_order(nr_pages));
	if (*pages == NULL)
		return -ENOMEM;
	return 0;
}
EXPORT_SYMBOL_GPL(alloc_xenballooned_pages);

void free_xenballooned_pages(int nr_pages, struct page **pages)
{
	kfree(*pages);
	*pages = NULL;
}
EXPORT_SYMBOL_GPL(free_xenballooned_pages);

/* In the hypervisor.S file. */
EXPORT_SYMBOL_GPL(HYPERVISOR_event_channel_op);
EXPORT_SYMBOL_GPL(HYPERVISOR_grant_table_op);
+1 −0
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ DEFINE_GUEST_HANDLE(void);
DEFINE_GUEST_HANDLE(uint64_t);
DEFINE_GUEST_HANDLE(uint32_t);
DEFINE_GUEST_HANDLE(xen_pfn_t);
DEFINE_GUEST_HANDLE(xen_ulong_t);
#endif

#ifndef HYPERVISOR_VIRT_START
+1 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ config XEN
	bool "Xen guest support"
	select PARAVIRT
	select PARAVIRT_CLOCK
	select XEN_HAVE_PVMMU
	depends on X86_64 || (X86_32 && X86_PAE && !X86_VISWS)
	depends on X86_TSC
	help
+77 −25
Original line number Diff line number Diff line
@@ -223,6 +223,21 @@ static void __init xen_banner(void)
	       version >> 16, version & 0xffff, extra.extraversion,
	       xen_feature(XENFEAT_mmu_pt_update_preserve_ad) ? " (preserve-AD)" : "");
}
/* Check if running on Xen version (major, minor) or later */
bool
xen_running_on_version_or_later(unsigned int major, unsigned int minor)
{
	unsigned int version;

	if (!xen_domain())
		return false;

	version = HYPERVISOR_xen_version(XENVER_version, NULL);
	if ((((version >> 16) == major) && ((version & 0xffff) >= minor)) ||
		((version >> 16) > major))
		return true;
	return false;
}

#define CPUID_THERM_POWER_LEAF 6
#define APERFMPERF_PRESENT 0
@@ -287,8 +302,7 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx,

static bool __init xen_check_mwait(void)
{
#if defined(CONFIG_ACPI) && !defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR) && \
	!defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR_MODULE)
#ifdef CONFIG_ACPI
	struct xen_platform_op op = {
		.cmd			= XENPF_set_processor_pminfo,
		.u.set_pminfo.id	= -1,
@@ -309,6 +323,13 @@ static bool __init xen_check_mwait(void)
	if (!xen_initial_domain())
		return false;

	/*
	 * When running under platform earlier than Xen4.2, do not expose
	 * mwait, to avoid the risk of loading native acpi pad driver
	 */
	if (!xen_running_on_version_or_later(4, 2))
		return false;

	ax = 1;
	cx = 0;

@@ -1495,51 +1516,72 @@ asmlinkage void __init xen_start_kernel(void)
#endif
}

void __ref xen_hvm_init_shared_info(void)
#ifdef CONFIG_XEN_PVHVM
#define HVM_SHARED_INFO_ADDR 0xFE700000UL
static struct shared_info *xen_hvm_shared_info;
static unsigned long xen_hvm_sip_phys;
static int xen_major, xen_minor;

static void xen_hvm_connect_shared_info(unsigned long pfn)
{
	int cpu;
	struct xen_add_to_physmap xatp;
	static struct shared_info *shared_info_page = 0;

	if (!shared_info_page)
		shared_info_page = (struct shared_info *)
			extend_brk(PAGE_SIZE, PAGE_SIZE);
	xatp.domid = DOMID_SELF;
	xatp.idx = 0;
	xatp.space = XENMAPSPACE_shared_info;
	xatp.gpfn = __pa(shared_info_page) >> PAGE_SHIFT;
	xatp.gpfn = pfn;
	if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
		BUG();

	HYPERVISOR_shared_info = (struct shared_info *)shared_info_page;
}
static void __init xen_hvm_set_shared_info(struct shared_info *sip)
{
	int cpu;

	HYPERVISOR_shared_info = sip;

	/* xen_vcpu is a pointer to the vcpu_info struct in the shared_info
	 * page, we use it in the event channel upcall and in some pvclock
	 * related functions. We don't need the vcpu_info placement
	 * optimizations because we don't use any pv_mmu or pv_irq op on
	 * HVM.
	 * When xen_hvm_init_shared_info is run at boot time only vcpu 0 is
	 * online but xen_hvm_init_shared_info is run at resume time too and
	 * in that case multiple vcpus might be online. */
	for_each_online_cpu(cpu) {
	 * HVM. */
	for_each_online_cpu(cpu)
		per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu];
}

/* Reconnect the shared_info pfn to a (new) mfn */
void xen_hvm_resume_shared_info(void)
{
	xen_hvm_connect_shared_info(xen_hvm_sip_phys >> PAGE_SHIFT);
}

/* Xen tools prior to Xen 4 do not provide a E820_Reserved area for guest usage.
 * On these old tools the shared info page will be placed in E820_Ram.
 * Xen 4 provides a E820_Reserved area at 0xFC000000, and this code expects
 * that nothing is mapped up to HVM_SHARED_INFO_ADDR.
 * Xen 4.3+ provides an explicit 1MB area at HVM_SHARED_INFO_ADDR which is used
 * here for the shared info page. */
static void __init xen_hvm_init_shared_info(void)
{
	if (xen_major < 4) {
		xen_hvm_shared_info = extend_brk(PAGE_SIZE, PAGE_SIZE);
		xen_hvm_sip_phys = __pa(xen_hvm_shared_info);
	} else {
		xen_hvm_sip_phys = HVM_SHARED_INFO_ADDR;
		set_fixmap(FIX_PARAVIRT_BOOTMAP, xen_hvm_sip_phys);
		xen_hvm_shared_info =
		(struct shared_info *)fix_to_virt(FIX_PARAVIRT_BOOTMAP);
	}
	xen_hvm_connect_shared_info(xen_hvm_sip_phys >> PAGE_SHIFT);
	xen_hvm_set_shared_info(xen_hvm_shared_info);
}

#ifdef CONFIG_XEN_PVHVM
static void __init init_hvm_pv_info(void)
{
	int major, minor;
	uint32_t eax, ebx, ecx, edx, pages, msr, base;
	uint32_t ecx, edx, pages, msr, base;
	u64 pfn;

	base = xen_cpuid_base();
	cpuid(base + 1, &eax, &ebx, &ecx, &edx);

	major = eax >> 16;
	minor = eax & 0xffff;
	printk(KERN_INFO "Xen version %d.%d.\n", major, minor);

	cpuid(base + 2, &pages, &msr, &ecx, &edx);

	pfn = __pa(hypercall_page);
@@ -1590,12 +1632,22 @@ static void __init xen_hvm_guest_init(void)

static bool __init xen_hvm_platform(void)
{
	uint32_t eax, ebx, ecx, edx, base;

	if (xen_pv_domain())
		return false;

	if (!xen_cpuid_base())
	base = xen_cpuid_base();
	if (!base)
		return false;

	cpuid(base + 1, &eax, &ebx, &ecx, &edx);

	xen_major = eax >> 16;
	xen_minor = eax & 0xffff;

	printk(KERN_INFO "Xen version %d.%d.\n", xen_major, xen_minor);

	return true;
}

Loading