]> Pileus Git - ~andy/linux/commitdiff
Merge branch 'x86/platform' of git://git.kernel.org/pub/scm/linux/kernel/git/tip...
authorKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Wed, 12 Sep 2012 15:14:33 +0000 (11:14 -0400)
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Wed, 12 Sep 2012 15:14:33 +0000 (11:14 -0400)
* 'x86/platform' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (9690 commits)
  x86: Document x86_init.paging.pagetable_init()
  x86: xen: Cleanup and remove x86_init.paging.pagetable_setup_done()
  x86: Move paging_init() call to x86_init.paging.pagetable_init()
  x86: Rename pagetable_setup_start() to pagetable_init()
  x86: Remove base argument from x86_init.paging.pagetable_setup_start
  Linux 3.6-rc5
  HID: tpkbd: work even if the new Lenovo Keyboard driver is not configured
  Remove user-triggerable BUG from mpol_to_str
  xen/pciback: Fix proper FLR steps.
  uml: fix compile error in deliver_alarm()
  dj: memory scribble in logi_dj
  Fix order of arguments to compat_put_time[spec|val]
  xen: Use correct masking in xen_swiotlb_alloc_coherent.
  xen: fix logical error in tlb flushing
  xen/p2m: Fix one-off error in checking the P2M tree directory.
  powerpc: Don't use __put_user() in patch_instruction
  powerpc: Make sure IPI handlers see data written by IPI senders
  powerpc: Restore correct DSCR in context switch
  powerpc: Fix DSCR inheritance in copy_thread()
  powerpc: Keep thread.dscr and thread.dscr_inherit in sync
  ...

27 files changed:
arch/ia64/include/asm/xen/interface.h
arch/x86/include/asm/xen/interface.h
arch/x86/xen/apic.c
arch/x86/xen/enlighten.c
arch/x86/xen/mmu.c
arch/x86/xen/pci-swiotlb-xen.c
arch/x86/xen/platform-pci-unplug.c
arch/x86/xen/xen-head.S
drivers/pci/xen-pcifront.c
drivers/tty/hvc/hvc_xen.c
drivers/xen/events.c
drivers/xen/gntdev.c
drivers/xen/grant-table.c
drivers/xen/privcmd.c
drivers/xen/swiotlb-xen.c
drivers/xen/sys-hypervisor.c
drivers/xen/tmem.c
drivers/xen/xenbus/xenbus_dev_backend.c
drivers/xen/xenbus/xenbus_probe.c
drivers/xen/xenbus/xenbus_probe_frontend.c
include/xen/interface/grant_table.h
include/xen/interface/memory.h
include/xen/interface/platform.h
include/xen/interface/version.h
include/xen/interface/xen.h
include/xen/privcmd.h
include/xen/swiotlb-xen.h

index 09d5f7fd9db164f28f0bd85ba7348af4834a2c00..3d52a5bbd857702c62baece0a658714a8b3c1632 100644 (file)
 #define set_xen_guest_handle(hnd, val) do { (hnd).p = val; } while (0)
 
 #ifndef __ASSEMBLY__
+/* Explicitly size integers that represent pfns in the public interface
+ * with Xen so that we could have one ABI that works for 32 and 64 bit
+ * guests. */
+typedef unsigned long xen_pfn_t;
 /* Guest handles for primitive C types. */
 __DEFINE_GUEST_HANDLE(uchar, unsigned char);
 __DEFINE_GUEST_HANDLE(uint, unsigned int);
@@ -79,7 +83,6 @@ DEFINE_GUEST_HANDLE(void);
 DEFINE_GUEST_HANDLE(uint64_t);
 DEFINE_GUEST_HANDLE(uint32_t);
 
-typedef unsigned long xen_pfn_t;
 DEFINE_GUEST_HANDLE(xen_pfn_t);
 #define PRI_xen_pfn    "lx"
 #endif
@@ -265,6 +268,8 @@ typedef struct xen_callback xen_callback_t;
 
 #endif /* !__ASSEMBLY__ */
 
+#include <asm/pvclock-abi.h>
+
 /* Size of the shared_info area (this is not related to page size).  */
 #define XSI_SHIFT                      14
 #define XSI_SIZE                       (1 << XSI_SHIFT)
index cbf0c9d50b92840565d7aaa719612ee12c6d8667..555f94d3637b3926f1357a3dafb611fcecf65a6c 100644 (file)
 #endif
 
 #ifndef __ASSEMBLY__
+/* Explicitly size integers that represent pfns in the public interface
+ * with Xen so that on ARM we can have one ABI that works for 32 and 64
+ * bit guests. */
+typedef unsigned long xen_pfn_t;
 /* Guest handles for primitive C types. */
 __DEFINE_GUEST_HANDLE(uchar, unsigned char);
 __DEFINE_GUEST_HANDLE(uint,  unsigned int);
@@ -57,6 +61,7 @@ DEFINE_GUEST_HANDLE(long);
 DEFINE_GUEST_HANDLE(void);
 DEFINE_GUEST_HANDLE(uint64_t);
 DEFINE_GUEST_HANDLE(uint32_t);
+DEFINE_GUEST_HANDLE(xen_pfn_t);
 #endif
 
 #ifndef HYPERVISOR_VIRT_START
@@ -121,6 +126,8 @@ struct arch_shared_info {
 #include "interface_64.h"
 #endif
 
+#include <asm/pvclock-abi.h>
+
 #ifndef __ASSEMBLY__
 /*
  * The following is all CPU context. Note that the fpu_ctxt block is filled
index ec57bd3818a4cdeb0c45d3c3b13cc7a79db85f9b..7005ced5d1ad7ab93a3862f269855da4cf9a9171 100644 (file)
@@ -6,8 +6,9 @@
 
 #include <xen/xen.h>
 #include <xen/interface/physdev.h>
+#include "xen-ops.h"
 
-unsigned int xen_io_apic_read(unsigned apic, unsigned reg)
+static unsigned int xen_io_apic_read(unsigned apic, unsigned reg)
 {
        struct physdev_apic apic_op;
        int ret;
index 9642d4a3860239f3203a2ff12dba5543a26ccf4f..2766746de27438be88c675955ea97c44ff6d7d91 100644 (file)
@@ -80,6 +80,8 @@
 #include "smp.h"
 #include "multicalls.h"
 
+#include <xen/events.h>
+
 EXPORT_SYMBOL_GPL(hypercall_page);
 
 DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu);
index 7a769b7526cb2d5209380d65836ba5b2449aecb2..dfc900471aef54f4cfc6847b21a7c170f88345e4 100644 (file)
@@ -2333,6 +2333,9 @@ int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
        unsigned long range;
        int err = 0;
 
+       if (xen_feature(XENFEAT_auto_translated_physmap))
+               return -EINVAL;
+
        prot = __pgprot(pgprot_val(prot) | _PAGE_IOMAP);
 
        BUG_ON(!((vma->vm_flags & (VM_PFNMAP | VM_RESERVED | VM_IO)) ==
@@ -2351,8 +2354,8 @@ int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
                if (err)
                        goto out;
 
-               err = -EFAULT;
-               if (HYPERVISOR_mmu_update(mmu_update, batch, NULL, domid) < 0)
+               err = HYPERVISOR_mmu_update(mmu_update, batch, NULL, domid);
+               if (err < 0)
                        goto out;
 
                nr -= batch;
index 967633ad98c48b262cf7739c7cdcdb7b8d79641a..1ab45941502d6ca71238ca2f33897dd3e75b496e 100644 (file)
@@ -8,6 +8,7 @@
 #include <xen/xen.h>
 #include <asm/iommu_table.h>
 
+#include <asm/xen/swiotlb-xen.h>
 int xen_swiotlb __read_mostly;
 
 static struct dma_map_ops xen_swiotlb_dma_ops = {
@@ -62,6 +63,6 @@ void __init pci_xen_swiotlb_init(void)
        }
 }
 IOMMU_INIT_FINISH(pci_xen_swiotlb_detect,
-                 0,
+                 NULL,
                  pci_xen_swiotlb_init,
-                 0);
+                 NULL);
index ffcf2615640b0bd1f8e3596dbaf4d07c49d5dc51..0a7852483ffef27583fb6c4b5b7c3684c5b3847c 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/module.h>
 
 #include <xen/platform_pci.h>
+#include "xen-ops.h"
 
 #define XEN_PLATFORM_ERR_MAGIC -1
 #define XEN_PLATFORM_ERR_PROTOCOL -2
index aaa7291c9259f55c0fc5ac0aab5f09ff788511a0..7faed5869e5bf215cafe4c0fdbe24ba38fcd66d0 100644 (file)
@@ -28,9 +28,61 @@ ENTRY(startup_xen)
        __FINIT
 
 .pushsection .text
-       .align PAGE_SIZE
+       .balign PAGE_SIZE
 ENTRY(hypercall_page)
-       .skip PAGE_SIZE
+#define NEXT_HYPERCALL(x) \
+       ENTRY(xen_hypercall_##x) \
+       .skip 32
+
+NEXT_HYPERCALL(set_trap_table)
+NEXT_HYPERCALL(mmu_update)
+NEXT_HYPERCALL(set_gdt)
+NEXT_HYPERCALL(stack_switch)
+NEXT_HYPERCALL(set_callbacks)
+NEXT_HYPERCALL(fpu_taskswitch)
+NEXT_HYPERCALL(sched_op_compat)
+NEXT_HYPERCALL(platform_op)
+NEXT_HYPERCALL(set_debugreg)
+NEXT_HYPERCALL(get_debugreg)
+NEXT_HYPERCALL(update_descriptor)
+NEXT_HYPERCALL(ni)
+NEXT_HYPERCALL(memory_op)
+NEXT_HYPERCALL(multicall)
+NEXT_HYPERCALL(update_va_mapping)
+NEXT_HYPERCALL(set_timer_op)
+NEXT_HYPERCALL(event_channel_op_compat)
+NEXT_HYPERCALL(xen_version)
+NEXT_HYPERCALL(console_io)
+NEXT_HYPERCALL(physdev_op_compat)
+NEXT_HYPERCALL(grant_table_op)
+NEXT_HYPERCALL(vm_assist)
+NEXT_HYPERCALL(update_va_mapping_otherdomain)
+NEXT_HYPERCALL(iret)
+NEXT_HYPERCALL(vcpu_op)
+NEXT_HYPERCALL(set_segment_base)
+NEXT_HYPERCALL(mmuext_op)
+NEXT_HYPERCALL(xsm_op)
+NEXT_HYPERCALL(nmi_op)
+NEXT_HYPERCALL(sched_op)
+NEXT_HYPERCALL(callback_op)
+NEXT_HYPERCALL(xenoprof_op)
+NEXT_HYPERCALL(event_channel_op)
+NEXT_HYPERCALL(physdev_op)
+NEXT_HYPERCALL(hvm_op)
+NEXT_HYPERCALL(sysctl)
+NEXT_HYPERCALL(domctl)
+NEXT_HYPERCALL(kexec_op)
+NEXT_HYPERCALL(tmem_op) /* 38 */
+ENTRY(xen_hypercall_rsvr)
+       .skip 320
+NEXT_HYPERCALL(mca) /* 48 */
+NEXT_HYPERCALL(arch_1)
+NEXT_HYPERCALL(arch_2)
+NEXT_HYPERCALL(arch_3)
+NEXT_HYPERCALL(arch_4)
+NEXT_HYPERCALL(arch_5)
+NEXT_HYPERCALL(arch_6)
+       .balign PAGE_SIZE
 .popsection
 
        ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS,       .asciz "linux")
index d6cc62cb4cf7465fe22cb643fbde7a3f79f88a29..a4d901def8f282dccc66cc2ba61929eb35428671 100644 (file)
@@ -236,7 +236,7 @@ static int pcifront_bus_write(struct pci_bus *bus, unsigned int devfn,
        return errno_to_pcibios_err(do_pci_op(pdev, &op));
 }
 
-struct pci_ops pcifront_bus_ops = {
+static struct pci_ops pcifront_bus_ops = {
        .read = pcifront_bus_read,
        .write = pcifront_bus_write,
 };
index 1e456dca4f60be02835d7503436fe8f26450c118..2944ff88fdc0b2ea9705850e080a755aca440a8d 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/console.h>
 #include <linux/delay.h>
 #include <linux/err.h>
+#include <linux/irq.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/list.h>
@@ -35,6 +36,7 @@
 #include <xen/page.h>
 #include <xen/events.h>
 #include <xen/interface/io/console.h>
+#include <xen/interface/sched.h>
 #include <xen/hvc-console.h>
 #include <xen/xenbus.h>
 
index 7595581d032cc9d9c5a7f04ee12b861dc76051ee..c60d1629c91601f366fef151a7d45f51736b1378 100644 (file)
@@ -373,11 +373,22 @@ static void unmask_evtchn(int port)
 {
        struct shared_info *s = HYPERVISOR_shared_info;
        unsigned int cpu = get_cpu();
+       int do_hypercall = 0, evtchn_pending = 0;
 
        BUG_ON(!irqs_disabled());
 
-       /* Slow path (hypercall) if this is a non-local port. */
-       if (unlikely(cpu != cpu_from_evtchn(port))) {
+       if (unlikely((cpu != cpu_from_evtchn(port))))
+               do_hypercall = 1;
+       else
+               evtchn_pending = sync_test_bit(port, &s->evtchn_pending[0]);
+
+       if (unlikely(evtchn_pending && xen_hvm_domain()))
+               do_hypercall = 1;
+
+       /* Slow path (hypercall) if this is a non-local port or if this is
+        * an hvm domain and an event is pending (hvm domains don't have
+        * their own implementation of irq_enable). */
+       if (do_hypercall) {
                struct evtchn_unmask unmask = { .port = port };
                (void)HYPERVISOR_event_channel_op(EVTCHNOP_unmask, &unmask);
        } else {
@@ -390,7 +401,7 @@ static void unmask_evtchn(int port)
                 * 'hw_resend_irq'. Just like a real IO-APIC we 'lose
                 * the interrupt edge' if the channel is masked.
                 */
-               if (sync_test_bit(port, &s->evtchn_pending[0]) &&
+               if (evtchn_pending &&
                    !sync_test_and_set_bit(port / BITS_PER_LONG,
                                           &vcpu_info->evtchn_pending_sel))
                        vcpu_info->evtchn_upcall_pending = 1;
@@ -831,6 +842,7 @@ int bind_evtchn_to_irq(unsigned int evtchn)
                struct irq_info *info = info_for_irq(irq);
                WARN_ON(info == NULL || info->type != IRQT_EVTCHN);
        }
+       irq_clear_status_flags(irq, IRQ_NOREQUEST|IRQ_NOAUTOEN);
 
 out:
        mutex_unlock(&irq_mapping_update_lock);
index 1ffd03bf8e10dcb6b015e3e0b94a2a460f0d0dcd..163b7e985ed043f14e7236c9c9ce8ad93ac2a720 100644 (file)
@@ -445,7 +445,7 @@ static void mn_release(struct mmu_notifier *mn,
        spin_unlock(&priv->lock);
 }
 
-struct mmu_notifier_ops gntdev_mmu_ops = {
+static struct mmu_notifier_ops gntdev_mmu_ops = {
        .release                = mn_release,
        .invalidate_page        = mn_invl_page,
        .invalidate_range_start = mn_invl_range_start,
index 0bfc1ef11259eccaa937eb8d0913e4e14e04832e..eea81cf8a2a505430169f0bd6e28e7c594f23110 100644 (file)
@@ -47,6 +47,7 @@
 #include <xen/interface/memory.h>
 #include <xen/hvc-console.h>
 #include <asm/xen/hypercall.h>
+#include <asm/xen/interface.h>
 
 #include <asm/pgtable.h>
 #include <asm/sync_bitops.h>
@@ -285,10 +286,9 @@ int gnttab_grant_foreign_access(domid_t domid, unsigned long frame,
 }
 EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access);
 
-void gnttab_update_subpage_entry_v2(grant_ref_t ref, domid_t domid,
-                                   unsigned long frame, int flags,
-                                   unsigned page_off,
-                                   unsigned length)
+static void gnttab_update_subpage_entry_v2(grant_ref_t ref, domid_t domid,
+                                          unsigned long frame, int flags,
+                                          unsigned page_off, unsigned length)
 {
        gnttab_shared.v2[ref].sub_page.frame = frame;
        gnttab_shared.v2[ref].sub_page.page_off = page_off;
@@ -345,9 +345,9 @@ bool gnttab_subpage_grants_available(void)
 }
 EXPORT_SYMBOL_GPL(gnttab_subpage_grants_available);
 
-void gnttab_update_trans_entry_v2(grant_ref_t ref, domid_t domid,
-                                 int flags, domid_t trans_domid,
-                                 grant_ref_t trans_gref)
+static void gnttab_update_trans_entry_v2(grant_ref_t ref, domid_t domid,
+                                        int flags, domid_t trans_domid,
+                                        grant_ref_t trans_gref)
 {
        gnttab_shared.v2[ref].transitive.trans_domid = trans_domid;
        gnttab_shared.v2[ref].transitive.gref = trans_gref;
index ccee0f16bcf8c10e994855a6efadff99b5b6bda1..ef6389580b8c78dd30a8c7738098c51b6ef3133a 100644 (file)
@@ -76,7 +76,7 @@ static void free_page_list(struct list_head *pages)
  */
 static int gather_array(struct list_head *pagelist,
                        unsigned nelem, size_t size,
-                       void __user *data)
+                       const void __user *data)
 {
        unsigned pageidx;
        void *pagedata;
@@ -246,61 +246,117 @@ struct mmap_batch_state {
        domid_t domain;
        unsigned long va;
        struct vm_area_struct *vma;
-       int err;
-
-       xen_pfn_t __user *user;
+       /* A tristate:
+        *      0 for no errors
+        *      1 if at least one error has happened (and no
+        *          -ENOENT errors have happened)
+        *      -ENOENT if at least 1 -ENOENT has happened.
+        */
+       int global_error;
+       /* An array for individual errors */
+       int *err;
+
+       /* User-space mfn array to store errors in the second pass for V1. */
+       xen_pfn_t __user *user_mfn;
 };
 
 static int mmap_batch_fn(void *data, void *state)
 {
        xen_pfn_t *mfnp = data;
        struct mmap_batch_state *st = state;
+       int ret;
+
+       ret = xen_remap_domain_mfn_range(st->vma, st->va & PAGE_MASK, *mfnp, 1,
+                                        st->vma->vm_page_prot, st->domain);
 
-       if (xen_remap_domain_mfn_range(st->vma, st->va & PAGE_MASK, *mfnp, 1,
-                                      st->vma->vm_page_prot, st->domain) < 0) {
-               *mfnp |= 0xf0000000U;
-               st->err++;
+       /* Store error code for second pass. */
+       *(st->err++) = ret;
+
+       /* And see if it affects the global_error. */
+       if (ret < 0) {
+               if (ret == -ENOENT)
+                       st->global_error = -ENOENT;
+               else {
+                       /* Record that at least one error has happened. */
+                       if (st->global_error == 0)
+                               st->global_error = 1;
+               }
        }
        st->va += PAGE_SIZE;
 
        return 0;
 }
 
-static int mmap_return_errors(void *data, void *state)
+static int mmap_return_errors_v1(void *data, void *state)
 {
        xen_pfn_t *mfnp = data;
        struct mmap_batch_state *st = state;
-
-       return put_user(*mfnp, st->user++);
+       int err = *(st->err++);
+
+       /*
+        * V1 encodes the error codes in the 32bit top nibble of the
+        * mfn (with its known limitations vis-a-vis 64 bit callers).
+        */
+       *mfnp |= (err == -ENOENT) ?
+                               PRIVCMD_MMAPBATCH_PAGED_ERROR :
+                               PRIVCMD_MMAPBATCH_MFN_ERROR;
+       return __put_user(*mfnp, st->user_mfn++);
 }
 
 static struct vm_operations_struct privcmd_vm_ops;
 
-static long privcmd_ioctl_mmap_batch(void __user *udata)
+static long privcmd_ioctl_mmap_batch(void __user *udata, int version)
 {
        int ret;
-       struct privcmd_mmapbatch m;
+       struct privcmd_mmapbatch_v2 m;
        struct mm_struct *mm = current->mm;
        struct vm_area_struct *vma;
        unsigned long nr_pages;
        LIST_HEAD(pagelist);
+       int *err_array = NULL;
        struct mmap_batch_state state;
 
        if (!xen_initial_domain())
                return -EPERM;
 
-       if (copy_from_user(&m, udata, sizeof(m)))
-               return -EFAULT;
+       switch (version) {
+       case 1:
+               if (copy_from_user(&m, udata, sizeof(struct privcmd_mmapbatch)))
+                       return -EFAULT;
+               /* Returns per-frame error in m.arr. */
+               m.err = NULL;
+               if (!access_ok(VERIFY_WRITE, m.arr, m.num * sizeof(*m.arr)))
+                       return -EFAULT;
+               break;
+       case 2:
+               if (copy_from_user(&m, udata, sizeof(struct privcmd_mmapbatch_v2)))
+                       return -EFAULT;
+               /* Returns per-frame error code in m.err. */
+               if (!access_ok(VERIFY_WRITE, m.err, m.num * (sizeof(*m.err))))
+                       return -EFAULT;
+               break;
+       default:
+               return -EINVAL;
+       }
 
        nr_pages = m.num;
        if ((m.num <= 0) || (nr_pages > (LONG_MAX >> PAGE_SHIFT)))
                return -EINVAL;
 
-       ret = gather_array(&pagelist, m.num, sizeof(xen_pfn_t),
-                          m.arr);
+       ret = gather_array(&pagelist, m.num, sizeof(xen_pfn_t), m.arr);
 
-       if (ret || list_empty(&pagelist))
+       if (ret)
                goto out;
+       if (list_empty(&pagelist)) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       err_array = kcalloc(m.num, sizeof(int), GFP_KERNEL);
+       if (err_array == NULL) {
+               ret = -ENOMEM;
+               goto out;
+       }
 
        down_write(&mm->mmap_sem);
 
@@ -315,24 +371,37 @@ static long privcmd_ioctl_mmap_batch(void __user *udata)
                goto out;
        }
 
-       state.domain = m.dom;
-       state.vma = vma;
-       state.va = m.addr;
-       state.err = 0;
+       state.domain        = m.dom;
+       state.vma           = vma;
+       state.va            = m.addr;
+       state.global_error  = 0;
+       state.err           = err_array;
 
-       ret = traverse_pages(m.num, sizeof(xen_pfn_t),
-                            &pagelist, mmap_batch_fn, &state);
+       /* mmap_batch_fn guarantees ret == 0 */
+       BUG_ON(traverse_pages(m.num, sizeof(xen_pfn_t),
+                            &pagelist, mmap_batch_fn, &state));
 
        up_write(&mm->mmap_sem);
 
-       if (state.err > 0) {
-               state.user = m.arr;
+       if (state.global_error && (version == 1)) {
+               /* Write back errors in second pass. */
+               state.user_mfn = (xen_pfn_t *)m.arr;
+               state.err      = err_array;
                ret = traverse_pages(m.num, sizeof(xen_pfn_t),
-                              &pagelist,
-                              mmap_return_errors, &state);
+                                    &pagelist, mmap_return_errors_v1, &state);
+       } else if (version == 2) {
+               ret = __copy_to_user(m.err, err_array, m.num * sizeof(int));
+               if (ret)
+                       ret = -EFAULT;
        }
 
+       /* If we have not had any EFAULT-like global errors then set the global
+        * error to -ENOENT if necessary. */
+       if ((ret == 0) && (state.global_error == -ENOENT))
+               ret = -ENOENT;
+
 out:
+       kfree(err_array);
        free_page_list(&pagelist);
 
        return ret;
@@ -354,7 +423,11 @@ static long privcmd_ioctl(struct file *file,
                break;
 
        case IOCTL_PRIVCMD_MMAPBATCH:
-               ret = privcmd_ioctl_mmap_batch(udata);
+               ret = privcmd_ioctl_mmap_batch(udata, 1);
+               break;
+
+       case IOCTL_PRIVCMD_MMAPBATCH_V2:
+               ret = privcmd_ioctl_mmap_batch(udata, 2);
                break;
 
        default:
@@ -380,10 +453,6 @@ static struct vm_operations_struct privcmd_vm_ops = {
 
 static int privcmd_mmap(struct file *file, struct vm_area_struct *vma)
 {
-       /* Unsupported for auto-translate guests. */
-       if (xen_feature(XENFEAT_auto_translated_physmap))
-               return -ENOSYS;
-
        /* DONTCOPY is essential for Xen because copy_page_range doesn't know
         * how to recreate these mappings */
        vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY | VM_PFNMAP;
index 4d519488d3045355672b8f48e3c1e2eb4ac64864..2e74dba6a04d184844e3104b164a5175f2c83ac3 100644 (file)
@@ -52,7 +52,7 @@ static unsigned long xen_io_tlb_nslabs;
  * Quick lookup value of the bus address of the IOTLB.
  */
 
-u64 start_dma_addr;
+static u64 start_dma_addr;
 
 static dma_addr_t xen_phys_to_bus(phys_addr_t paddr)
 {
@@ -466,14 +466,6 @@ xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
 }
 EXPORT_SYMBOL_GPL(xen_swiotlb_map_sg_attrs);
 
-int
-xen_swiotlb_map_sg(struct device *hwdev, struct scatterlist *sgl, int nelems,
-                  enum dma_data_direction dir)
-{
-       return xen_swiotlb_map_sg_attrs(hwdev, sgl, nelems, dir, NULL);
-}
-EXPORT_SYMBOL_GPL(xen_swiotlb_map_sg);
-
 /*
  * Unmap a set of streaming mode DMA translations.  Again, cpu read rules
  * concerning calls here are the same as for swiotlb_unmap_page() above.
@@ -494,14 +486,6 @@ xen_swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
 }
 EXPORT_SYMBOL_GPL(xen_swiotlb_unmap_sg_attrs);
 
-void
-xen_swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sgl, int nelems,
-                    enum dma_data_direction dir)
-{
-       return xen_swiotlb_unmap_sg_attrs(hwdev, sgl, nelems, dir, NULL);
-}
-EXPORT_SYMBOL_GPL(xen_swiotlb_unmap_sg);
-
 /*
  * Make physical memory consistent for a set of streaming mode DMA translations
  * after a transfer.
index fdb6d229c9bbf5e59198189f95e70502116a6ca2..5e5ad7e2885832f64f2131aa43aead50548cae0a 100644 (file)
@@ -114,7 +114,7 @@ static void xen_sysfs_version_destroy(void)
 
 /* UUID */
 
-static ssize_t uuid_show(struct hyp_sysfs_attr *attr, char *buffer)
+static ssize_t uuid_show_fallback(struct hyp_sysfs_attr *attr, char *buffer)
 {
        char *vm, *val;
        int ret;
@@ -135,6 +135,17 @@ static ssize_t uuid_show(struct hyp_sysfs_attr *attr, char *buffer)
        return ret;
 }
 
+static ssize_t uuid_show(struct hyp_sysfs_attr *attr, char *buffer)
+{
+       xen_domain_handle_t uuid;
+       int ret;
+       ret = HYPERVISOR_xen_version(XENVER_guest_handle, uuid);
+       if (ret)
+               return uuid_show_fallback(attr, buffer);
+       ret = sprintf(buffer, "%pU\n", uuid);
+       return ret;
+}
+
 HYPERVISOR_ATTR_RO(uuid);
 
 static int __init xen_sysfs_uuid_init(void)
index 89f264c67420c2448f9fe029e8193fa438369ae8..144564e5eb29e1ef59200fd079647656195280c8 100644 (file)
@@ -21,6 +21,7 @@
 #include <asm/xen/hypercall.h>
 #include <asm/xen/page.h>
 #include <asm/xen/hypervisor.h>
+#include <xen/tmem.h>
 
 #define TMEM_CONTROL               0
 #define TMEM_NEW_POOL              1
index be738c43104bea15dfca7422055d2f0cd79ecf9f..d730008007624b4227780457a96c77f8662c248e 100644 (file)
@@ -107,7 +107,7 @@ static int xenbus_backend_mmap(struct file *file, struct vm_area_struct *vma)
        return 0;
 }
 
-const struct file_operations xenbus_backend_fops = {
+static const struct file_operations xenbus_backend_fops = {
        .open = xenbus_backend_open,
        .mmap = xenbus_backend_mmap,
        .unlocked_ioctl = xenbus_backend_ioctl,
index b793723e724de767ad7cf9abac808548d78a21ba..91d3d6544a7b1955b2a13510d463814c94a69199 100644 (file)
@@ -324,8 +324,8 @@ static int cmp_dev(struct device *dev, void *data)
        return 0;
 }
 
-struct xenbus_device *xenbus_device_find(const char *nodename,
-                                        struct bus_type *bus)
+static struct xenbus_device *xenbus_device_find(const char *nodename,
+                                               struct bus_type *bus)
 {
        struct xb_find_info info = { .dev = NULL, .nodename = nodename };
 
index a31b54d488398675fc01eaa2878f0a21ec49fe46..3159a37d966d57755b6bd6d0d2a19379309c7e6e 100644 (file)
@@ -21,6 +21,7 @@
 #include <xen/xenbus.h>
 #include <xen/events.h>
 #include <xen/page.h>
+#include <xen/xen.h>
 
 #include <xen/platform_pci.h>
 
index a17d84433e6a1ab54e660fc4f25493a180ce15f2..7da811bdd5584b92089eeec672c54ab40381535d 100644 (file)
@@ -338,7 +338,7 @@ DEFINE_GUEST_HANDLE_STRUCT(gnttab_dump_table);
 #define GNTTABOP_transfer                4
 struct gnttab_transfer {
     /* IN parameters. */
-    unsigned long mfn;
+    xen_pfn_t mfn;
     domid_t       domid;
     grant_ref_t   ref;
     /* OUT parameters. */
@@ -375,7 +375,7 @@ struct gnttab_copy {
        struct {
                union {
                        grant_ref_t ref;
-                       unsigned long   gmfn;
+                       xen_pfn_t   gmfn;
                } u;
                domid_t  domid;
                uint16_t offset;
index eac3ce1537190228ba8dc74f0398d8e6e4795572..d8e33a93ea4d4483d69ea256c5abb99b16862a8c 100644 (file)
@@ -31,7 +31,7 @@ struct xen_memory_reservation {
      *   OUT: GMFN bases of extents that were allocated
      *   (NB. This command also updates the mach_to_phys translation table)
      */
-    GUEST_HANDLE(ulong) extent_start;
+    GUEST_HANDLE(xen_pfn_t) extent_start;
 
     /* Number of extents, and size/alignment of each (2^extent_order pages). */
     unsigned long  nr_extents;
@@ -130,7 +130,7 @@ struct xen_machphys_mfn_list {
      * any large discontiguities in the machine address space, 2MB gaps in
      * the machphys table will be represented by an MFN base of zero.
      */
-    GUEST_HANDLE(ulong) extent_start;
+    GUEST_HANDLE(xen_pfn_t) extent_start;
 
     /*
      * Number of extents written to the above array. This will be smaller
@@ -163,6 +163,9 @@ struct xen_add_to_physmap {
     /* Which domain to change the mapping for. */
     domid_t domid;
 
+    /* Number of pages to go through for gmfn_range */
+    uint16_t    size;
+
     /* Source mapping space. */
 #define XENMAPSPACE_shared_info 0 /* shared info page */
 #define XENMAPSPACE_grant_table 1 /* grant table page */
@@ -172,7 +175,7 @@ struct xen_add_to_physmap {
     unsigned long idx;
 
     /* GPFN where the source mapping page should appear. */
-    unsigned long gpfn;
+    xen_pfn_t gpfn;
 };
 DEFINE_GUEST_HANDLE_STRUCT(xen_add_to_physmap);
 
index 61fa66160983882ff5c26eccb9b7fc01ce0c2130..a3275a850e5412083f61e2f4af2a986573afcd80 100644 (file)
@@ -54,7 +54,7 @@ DEFINE_GUEST_HANDLE_STRUCT(xenpf_settime_t);
 #define XENPF_add_memtype         31
 struct xenpf_add_memtype {
        /* IN variables. */
-       unsigned long mfn;
+       xen_pfn_t mfn;
        uint64_t nr_mfns;
        uint32_t type;
        /* OUT variables. */
@@ -84,7 +84,7 @@ struct xenpf_read_memtype {
        /* IN variables. */
        uint32_t reg;
        /* OUT variables. */
-       unsigned long mfn;
+       xen_pfn_t mfn;
        uint64_t nr_mfns;
        uint32_t type;
 };
index e8b6519d47e9df818ebbb6d19323f032b8dde988..dd58cf5ea3e4c38469b13d57b58d236225bb05e1 100644 (file)
@@ -60,4 +60,7 @@ struct xen_feature_info {
 /* arg == NULL; returns host memory page size. */
 #define XENVER_pagesize 7
 
+/* arg == xen_domain_handle_t. */
+#define XENVER_guest_handle 8
+
 #endif /* __XEN_PUBLIC_VERSION_H__ */
index 0801468f9abed879eb1b9b1d52363aaeb979a2ae..1e0df6b7d3b305d9a5fbcfd4f4a541ae0d3726eb 100644 (file)
@@ -10,7 +10,6 @@
 #define __XEN_PUBLIC_XEN_H__
 
 #include <asm/xen/interface.h>
-#include <asm/pvclock-abi.h>
 
 /*
  * XEN "SYSTEM CALLS" (a.k.a. HYPERCALLS).
@@ -190,7 +189,7 @@ struct mmuext_op {
        unsigned int cmd;
        union {
                /* [UN]PIN_TABLE, NEW_BASEPTR, NEW_USER_BASEPTR */
-               unsigned long mfn;
+               xen_pfn_t mfn;
                /* INVLPG_LOCAL, INVLPG_ALL, SET_LDT */
                unsigned long linear_addr;
        } arg1;
@@ -430,11 +429,11 @@ struct start_info {
        unsigned long nr_pages;     /* Total pages allocated to this domain.  */
        unsigned long shared_info;  /* MACHINE address of shared info struct. */
        uint32_t flags;             /* SIF_xxx flags.                         */
-       unsigned long store_mfn;    /* MACHINE page number of shared page.    */
+       xen_pfn_t store_mfn;        /* MACHINE page number of shared page.    */
        uint32_t store_evtchn;      /* Event channel for store communication. */
        union {
                struct {
-                       unsigned long mfn;  /* MACHINE page number of console page.   */
+                       xen_pfn_t mfn;      /* MACHINE page number of console page.   */
                        uint32_t  evtchn;   /* Event channel for console page.        */
                } domU;
                struct {
index 17857fb4d5509b24a475609e2806af53c79d5317..a85316811d79ad43493d21c1e35d51ed10aa257c 100644 (file)
@@ -35,8 +35,7 @@
 
 #include <linux/types.h>
 #include <linux/compiler.h>
-
-typedef unsigned long xen_pfn_t;
+#include <xen/interface/xen.h>
 
 struct privcmd_hypercall {
        __u64 op;
@@ -59,13 +58,33 @@ struct privcmd_mmapbatch {
        int num;     /* number of pages to populate */
        domid_t dom; /* target domain */
        __u64 addr;  /* virtual address */
-       xen_pfn_t __user *arr; /* array of mfns - top nibble set on err */
+       xen_pfn_t __user *arr; /* array of mfns - or'd with
+                                 PRIVCMD_MMAPBATCH_*_ERROR on err */
+};
+
+#define PRIVCMD_MMAPBATCH_MFN_ERROR     0xf0000000U
+#define PRIVCMD_MMAPBATCH_PAGED_ERROR   0x80000000U
+
+struct privcmd_mmapbatch_v2 {
+       unsigned int num; /* number of pages to populate */
+       domid_t dom;      /* target domain */
+       __u64 addr;       /* virtual address */
+       const xen_pfn_t __user *arr; /* array of mfns */
+       int __user *err;  /* array of error codes */
 };
 
 /*
  * @cmd: IOCTL_PRIVCMD_HYPERCALL
  * @arg: &privcmd_hypercall_t
  * Return: Value returned from execution of the specified hypercall.
+ *
+ * @cmd: IOCTL_PRIVCMD_MMAPBATCH_V2
+ * @arg: &struct privcmd_mmapbatch_v2
+ * Return: 0 on success (i.e., arg->err contains valid error codes for
+ * each frame).  On an error other than a failed frame remap, -1 is
+ * returned and errno is set to EINVAL, EFAULT etc.  As an exception,
+ * if the operation was otherwise successful but any frame failed with
+ * -ENOENT, then -1 is returned and errno is set to ENOENT.
  */
 #define IOCTL_PRIVCMD_HYPERCALL                                        \
        _IOC(_IOC_NONE, 'P', 0, sizeof(struct privcmd_hypercall))
@@ -73,5 +92,7 @@ struct privcmd_mmapbatch {
        _IOC(_IOC_NONE, 'P', 2, sizeof(struct privcmd_mmap))
 #define IOCTL_PRIVCMD_MMAPBATCH                                        \
        _IOC(_IOC_NONE, 'P', 3, sizeof(struct privcmd_mmapbatch))
+#define IOCTL_PRIVCMD_MMAPBATCH_V2                             \
+       _IOC(_IOC_NONE, 'P', 4, sizeof(struct privcmd_mmapbatch_v2))
 
 #endif /* __LINUX_PUBLIC_PRIVCMD_H__ */
index 4f4d449f00f6b98644be40b85f108667c4cb1642..c050b6b9de38a04dc224475f5f4291a126f12551 100644 (file)
@@ -23,15 +23,6 @@ extern dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
 extern void xen_swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
                                   size_t size, enum dma_data_direction dir,
                                   struct dma_attrs *attrs);
-/*
-extern int
-xen_swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nents,
-                  enum dma_data_direction dir);
-
-extern void
-xen_swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents,
-                    enum dma_data_direction dir);
-*/
 extern int
 xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
                         int nelems, enum dma_data_direction dir,