]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge tag 'stable/for-linus-3.4-tag' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 23 Mar 2012 02:59:19 +0000 (19:59 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 23 Mar 2012 03:16:14 +0000 (20:16 -0700)
Pull xen updates from Konrad Rzeszutek Wilk:
 "which has three neat features:

   - PV multiconsole support, so that there can be hvc1, hvc2, etc; This
     can be used in HVM and in PV mode.

   - P-state and C-state power management driver that uploads said power
     management data to the hypervisor.  It also inhibits cpufreq
     scaling drivers to load so that only the hypervisor can make power
     management decisions - fixing a weird perf bug.

     There is one thing in the Kconfig that you won't like: "default y
     if (X86_ACPI_CPUFREQ = y || X86_POWERNOW_K8 = y)" (note, that it
     all depends on CONFIG_XEN which depends on CONFIG_PARAVIRT which by
     default is off).  I've a fix to convert that boolean expression
     into "default m" which I am going to post after the cpufreq git
     pull - as the two patches to make this work depend on a fix in Dave
     Jones's tree.

   - Function Level Reset (FLR) support in the Xen PCI backend.

  Fixes:

   - Kconfig dependencies for Xen PV keyboard and video
   - Compile warnings and constify fixes
   - Change over to use percpu_xxx instead of this_cpu_xxx"

Fix up trivial conflicts in drivers/tty/hvc/hvc_xen.c due to changes to
a removed commit.

* tag 'stable/for-linus-3.4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen:
  xen kconfig: relax INPUT_XEN_KBDDEV_FRONTEND deps
  xen/acpi-processor: C and P-state driver that uploads said data to hypervisor.
  xen: constify all instances of "struct attribute_group"
  xen/xenbus: ignore console/0
  hvc_xen: introduce HVC_XEN_FRONTEND
  hvc_xen: implement multiconsole support
  hvc_xen: support PV on HVM consoles
  xenbus: don't free other end details too early
  xen/enlighten: Expose MWAIT and MWAIT_LEAF if hypervisor OKs it.
  xen/setup/pm/acpi: Remove the call to boot_option_idle_override.
  xenbus: address compiler warnings
  xen: use this_cpu_xxx replace percpu_xxx funcs
  xen/pciback: Support pci_reset_function, aka FLR or D3 support.
  pci: Introduce __pci_reset_function_locked to be used when holding device_lock.
  xen: Utilize the restore_msi_irqs hook.

1  2 
arch/x86/pci/xen.c
arch/x86/xen/enlighten.c
arch/x86/xen/mmu.c
arch/x86/xen/smp.c
drivers/pci/pci.c
drivers/tty/hvc/Kconfig
drivers/video/Kconfig
drivers/xen/xen-balloon.c
drivers/xen/xen-pciback/pci_stub.c
include/linux/pci.h

diff --combined arch/x86/pci/xen.c
index d99346ea8fdb4317b74fded709c6bd971b3a066c,249a5ae17d0292f4c66c6b06c00775e00bc2961d..7415aa927913eee72a424377636c02cf0f46c518
@@@ -324,6 -324,32 +324,32 @@@ static int xen_initdom_setup_msi_irqs(s
  out:
        return ret;
  }
+ static void xen_initdom_restore_msi_irqs(struct pci_dev *dev, int irq)
+ {
+       int ret = 0;
+       if (pci_seg_supported) {
+               struct physdev_pci_device restore_ext;
+               restore_ext.seg = pci_domain_nr(dev->bus);
+               restore_ext.bus = dev->bus->number;
+               restore_ext.devfn = dev->devfn;
+               ret = HYPERVISOR_physdev_op(PHYSDEVOP_restore_msi_ext,
+                                       &restore_ext);
+               if (ret == -ENOSYS)
+                       pci_seg_supported = false;
+               WARN(ret && ret != -ENOSYS, "restore_msi_ext -> %d\n", ret);
+       }
+       if (!pci_seg_supported) {
+               struct physdev_restore_msi restore;
+               restore.bus = dev->bus->number;
+               restore.devfn = dev->devfn;
+               ret = HYPERVISOR_physdev_op(PHYSDEVOP_restore_msi, &restore);
+               WARN(ret && ret != -ENOSYS, "restore_msi -> %d\n", ret);
+       }
+ }
  #endif
  
  static void xen_teardown_msi_irqs(struct pci_dev *dev)
@@@ -374,7 -400,7 +400,7 @@@ int __init pci_xen_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
@@@ -446,6 -472,7 +472,7 @@@ int __init pci_xen_initial_domain(void
  #ifdef CONFIG_PCI_MSI
        x86_msi.setup_msi_irqs = xen_initdom_setup_msi_irqs;
        x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
+       x86_msi.restore_msi_irqs = xen_initdom_restore_msi_irqs;
  #endif
        xen_setup_acpi_sci();
        __acpi_register_gsi = acpi_register_gsi_xen;
diff --combined arch/x86/xen/enlighten.c
index 4172af8ceeb363d06912af15bf89e8508752b794,fe06bf4ef0e313525e67052d136706e640d7b841..b132ade26f778f2cfec7c2d5c7b6db48afe424d5
  #include <asm/reboot.h>
  #include <asm/stackprotector.h>
  #include <asm/hypervisor.h>
+ #include <asm/mwait.h>
+ #ifdef CONFIG_ACPI
+ #include <linux/acpi.h>
+ #include <asm/acpi.h>
+ #include <acpi/pdc_intel.h>
+ #include <acpi/processor.h>
+ #include <xen/interface/platform.h>
+ #endif
  
  #include "xen-ops.h"
  #include "mmu.h"
@@@ -200,13 -209,17 +209,17 @@@ static void __init xen_banner(void
  static __read_mostly unsigned int cpuid_leaf1_edx_mask = ~0;
  static __read_mostly unsigned int cpuid_leaf1_ecx_mask = ~0;
  
+ static __read_mostly unsigned int cpuid_leaf1_ecx_set_mask;
+ static __read_mostly unsigned int cpuid_leaf5_ecx_val;
+ static __read_mostly unsigned int cpuid_leaf5_edx_val;
  static void xen_cpuid(unsigned int *ax, unsigned int *bx,
                      unsigned int *cx, unsigned int *dx)
  {
        unsigned maskebx = ~0;
        unsigned maskecx = ~0;
        unsigned maskedx = ~0;
+       unsigned setecx = 0;
        /*
         * Mask out inconvenient features, to try and disable as many
         * unsupported kernel subsystems as possible.
        switch (*ax) {
        case 1:
                maskecx = cpuid_leaf1_ecx_mask;
+               setecx = cpuid_leaf1_ecx_set_mask;
                maskedx = cpuid_leaf1_edx_mask;
                break;
  
+       case CPUID_MWAIT_LEAF:
+               /* Synthesize the values.. */
+               *ax = 0;
+               *bx = 0;
+               *cx = cpuid_leaf5_ecx_val;
+               *dx = cpuid_leaf5_edx_val;
+               return;
        case 0xb:
                /* Suppress extended topology stuff */
                maskebx = 0;
  
        *bx &= maskebx;
        *cx &= maskecx;
+       *cx |= setecx;
        *dx &= maskedx;
  }
  
+ static bool __init xen_check_mwait(void)
+ {
+ #ifdef CONFIG_ACPI
+       struct xen_platform_op op = {
+               .cmd                    = XENPF_set_processor_pminfo,
+               .u.set_pminfo.id        = -1,
+               .u.set_pminfo.type      = XEN_PM_PDC,
+       };
+       uint32_t buf[3];
+       unsigned int ax, bx, cx, dx;
+       unsigned int mwait_mask;
+       /* We need to determine whether it is OK to expose the MWAIT
+        * capability to the kernel to harvest deeper than C3 states from ACPI
+        * _CST using the processor_harvest_xen.c module. For this to work, we
+        * need to gather the MWAIT_LEAF values (which the cstate.c code
+        * checks against). The hypervisor won't expose the MWAIT flag because
+        * it would break backwards compatibility; so we will find out directly
+        * from the hardware and hypercall.
+        */
+       if (!xen_initial_domain())
+               return false;
+       ax = 1;
+       cx = 0;
+       native_cpuid(&ax, &bx, &cx, &dx);
+       mwait_mask = (1 << (X86_FEATURE_EST % 32)) |
+                    (1 << (X86_FEATURE_MWAIT % 32));
+       if ((cx & mwait_mask) != mwait_mask)
+               return false;
+       /* We need to emulate the MWAIT_LEAF and for that we need both
+        * ecx and edx. The hypercall provides only partial information.
+        */
+       ax = CPUID_MWAIT_LEAF;
+       bx = 0;
+       cx = 0;
+       dx = 0;
+       native_cpuid(&ax, &bx, &cx, &dx);
+       /* Ask the Hypervisor whether to clear ACPI_PDC_C_C2C3_FFH. If so,
+        * don't expose MWAIT_LEAF and let ACPI pick the IOPORT version of C3.
+        */
+       buf[0] = ACPI_PDC_REVISION_ID;
+       buf[1] = 1;
+       buf[2] = (ACPI_PDC_C_CAPABILITY_SMP | ACPI_PDC_EST_CAPABILITY_SWSMP);
+       set_xen_guest_handle(op.u.set_pminfo.pdc, buf);
+       if ((HYPERVISOR_dom0_op(&op) == 0) &&
+           (buf[2] & (ACPI_PDC_C_C1_FFH | ACPI_PDC_C_C2C3_FFH))) {
+               cpuid_leaf5_ecx_val = cx;
+               cpuid_leaf5_edx_val = dx;
+       }
+       return true;
+ #else
+       return false;
+ #endif
+ }
  static void __init xen_init_cpuid_mask(void)
  {
        unsigned int ax, bx, cx, dx;
        /* Xen will set CR4.OSXSAVE if supported and not disabled by force */
        if ((cx & xsave_mask) != xsave_mask)
                cpuid_leaf1_ecx_mask &= ~xsave_mask; /* disable XSAVE & OSXSAVE */
+       if (xen_check_mwait())
+               cpuid_leaf1_ecx_set_mask = (1 << (X86_FEATURE_MWAIT % 32));
  }
  
  static void xen_set_debugreg(int reg, unsigned long val)
@@@ -777,11 -868,11 +868,11 @@@ static DEFINE_PER_CPU(unsigned long, xe
  
  static unsigned long xen_read_cr0(void)
  {
-       unsigned long cr0 = percpu_read(xen_cr0_value);
+       unsigned long cr0 = this_cpu_read(xen_cr0_value);
  
        if (unlikely(cr0 == 0)) {
                cr0 = native_read_cr0();
-               percpu_write(xen_cr0_value, cr0);
+               this_cpu_write(xen_cr0_value, cr0);
        }
  
        return cr0;
@@@ -791,7 -882,7 +882,7 @@@ static void xen_write_cr0(unsigned lon
  {
        struct multicall_space mcs;
  
-       percpu_write(xen_cr0_value, cr0);
+       this_cpu_write(xen_cr0_value, cr0);
  
        /* Only pay attention to cr0.TS; everything else is
           ignored. */
@@@ -1141,9 -1232,7 +1232,9 @@@ asmlinkage void __init xen_start_kernel
  
        /* Prevent unwanted bits from being set in PTEs. */
        __supported_pte_mask &= ~_PAGE_GLOBAL;
 +#if 0
        if (!xen_initial_domain())
 +#endif
                __supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD);
  
        __supported_pte_mask |= _PAGE_IOMAP;
  
        pgd = (pgd_t *)xen_start_info->pt_base;
  
 -      if (!xen_initial_domain())
 -              __supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD);
 -
 -      __supported_pte_mask |= _PAGE_IOMAP;
        /* Don't do the full vcpu_info placement stuff until we have a
           possible map and a non-dummy shared_info. */
        per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0];
diff --combined arch/x86/xen/mmu.c
index 95c1cf60c6694a0ff569e47012b9b30f2a73c97a,1a309ee2331eff879017e3a014dda53dba5f9556..988828b479ed29660363f87adda4c6c62707441b
@@@ -415,13 -415,13 +415,13 @@@ static pteval_t iomap_pte(pteval_t val
  static pteval_t xen_pte_val(pte_t pte)
  {
        pteval_t pteval = pte.pte;
 -
 +#if 0
        /* If this is a WC pte, convert back from Xen WC to Linux WC */
        if ((pteval & (_PAGE_PAT | _PAGE_PCD | _PAGE_PWT)) == _PAGE_PAT) {
                WARN_ON(!pat_enabled);
                pteval = (pteval & ~_PAGE_PAT) | _PAGE_PWT;
        }
 -
 +#endif
        if (xen_initial_domain() && (pteval & _PAGE_IOMAP))
                return pteval;
  
@@@ -463,7 -463,7 +463,7 @@@ void xen_set_pat(u64 pat
  static pte_t xen_make_pte(pteval_t pte)
  {
        phys_addr_t addr = (pte & PTE_PFN_MASK);
 -
 +#if 0
        /* If Linux is trying to set a WC pte, then map to the Xen WC.
         * If _PAGE_PAT is set, then it probably means it is really
         * _PAGE_PSE, so avoid fiddling with the PAT mapping and hope
                if ((pte & (_PAGE_PCD | _PAGE_PWT)) == _PAGE_PWT)
                        pte = (pte & ~(_PAGE_PCD | _PAGE_PWT)) | _PAGE_PAT;
        }
 -
 +#endif
        /*
         * Unprivileged domains are allowed to do IOMAPpings for
         * PCI passthrough, but not map ISA space.  The ISA
@@@ -1071,14 -1071,14 +1071,14 @@@ static void drop_other_mm_ref(void *inf
        struct mm_struct *mm = info;
        struct mm_struct *active_mm;
  
-       active_mm = percpu_read(cpu_tlbstate.active_mm);
+       active_mm = this_cpu_read(cpu_tlbstate.active_mm);
  
-       if (active_mm == mm && percpu_read(cpu_tlbstate.state) != TLBSTATE_OK)
+       if (active_mm == mm && this_cpu_read(cpu_tlbstate.state) != TLBSTATE_OK)
                leave_mm(smp_processor_id());
  
        /* If this cpu still has a stale cr3 reference, then make sure
           it has been flushed. */
-       if (percpu_read(xen_current_cr3) == __pa(mm->pgd))
+       if (this_cpu_read(xen_current_cr3) == __pa(mm->pgd))
                load_cr3(swapper_pg_dir);
  }
  
@@@ -1185,17 -1185,17 +1185,17 @@@ static void __init xen_pagetable_setup_
  
  static void xen_write_cr2(unsigned long cr2)
  {
-       percpu_read(xen_vcpu)->arch.cr2 = cr2;
+       this_cpu_read(xen_vcpu)->arch.cr2 = cr2;
  }
  
  static unsigned long xen_read_cr2(void)
  {
-       return percpu_read(xen_vcpu)->arch.cr2;
+       return this_cpu_read(xen_vcpu)->arch.cr2;
  }
  
  unsigned long xen_read_cr2_direct(void)
  {
-       return percpu_read(xen_vcpu_info.arch.cr2);
+       return this_cpu_read(xen_vcpu_info.arch.cr2);
  }
  
  static void xen_flush_tlb(void)
@@@ -1278,12 -1278,12 +1278,12 @@@ static void xen_flush_tlb_others(const 
  
  static unsigned long xen_read_cr3(void)
  {
-       return percpu_read(xen_cr3);
+       return this_cpu_read(xen_cr3);
  }
  
  static void set_current_cr3(void *v)
  {
-       percpu_write(xen_current_cr3, (unsigned long)v);
+       this_cpu_write(xen_current_cr3, (unsigned long)v);
  }
  
  static void __xen_write_cr3(bool kernel, unsigned long cr3)
        xen_extend_mmuext_op(&op);
  
        if (kernel) {
-               percpu_write(xen_cr3, cr3);
+               this_cpu_write(xen_cr3, cr3);
  
                /* Update xen_current_cr3 once the batch has actually
                   been submitted. */
@@@ -1322,7 -1322,7 +1322,7 @@@ static void xen_write_cr3(unsigned lon
  
        /* Update while interrupts are disabled, so its atomic with
           respect to ipis */
-       percpu_write(xen_cr3, cr3);
+       this_cpu_write(xen_cr3, cr3);
  
        __xen_write_cr3(true, cr3);
  
diff --combined arch/x86/xen/smp.c
index 501d4e0244ba229d90eabbe768ae1d25e057574f,449f86897db3abeff4cd1f44222a2b73f740b01a..315d8fa0c8fb8070b95422ef03b96a8f27c49d1f
@@@ -76,7 -76,7 +76,7 @@@ static void __cpuinit cpu_bringup(void
        xen_setup_cpu_clockevents();
  
        set_cpu_online(cpu, true);
-       percpu_write(cpu_state, CPU_ONLINE);
+       this_cpu_write(cpu_state, CPU_ONLINE);
        wmb();
  
        /* We can take interrupts now: we're officially "up". */
@@@ -409,13 -409,6 +409,13 @@@ static void __cpuinit xen_play_dead(voi
        play_dead_common();
        HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL);
        cpu_bringup();
 +      /*
 +       * Balance out the preempt calls - as we are running in cpu_idle
 +       * loop which has been called at bootup from cpu_bringup_and_idle.
 +       * The cpucpu_bringup_and_idle called cpu_bringup which made a
 +       * preempt_disable() So this preempt_enable will balance it out.
 +       */
 +      preempt_enable();
  }
  
  #else /* !CONFIG_HOTPLUG_CPU */
diff --combined drivers/pci/pci.c
index af295bb21d62890020cc2c0084f3570bd42babdc,192be5dbde56284d03df57b5c32d929ef2b91800..053670e09e2b93bafa15e3662c8672fdebd8ef34
@@@ -2802,7 -2802,7 +2802,7 @@@ pci_intx(struct pci_dev *pdev, int enab
  
  /**
   * pci_intx_mask_supported - probe for INTx masking support
 - * @pdev: the PCI device to operate on
 + * @dev: the PCI device to operate on
   *
   * Check if the device dev support INTx masking via the config space
   * command word.
@@@ -2884,7 -2884,7 +2884,7 @@@ done
  
  /**
   * pci_check_and_mask_intx - mask INTx on pending interrupt
 - * @pdev: the PCI device to operate on
 + * @dev: the PCI device to operate on
   *
   * Check if the device dev has its INTx line asserted, mask it and
   * return true in that case. False is returned if not interrupt was
@@@ -2898,7 -2898,7 +2898,7 @@@ EXPORT_SYMBOL_GPL(pci_check_and_mask_in
  
  /**
   * pci_check_and_mask_intx - unmask INTx of no interrupt is pending
 - * @pdev: the PCI device to operate on
 + * @dev: the PCI device to operate on
   *
   * Check if the device dev has its INTx line asserted, unmask it if not
   * and return true. False is returned and the mask remains active if
@@@ -3162,6 -3162,31 +3162,31 @@@ int __pci_reset_function(struct pci_de
  }
  EXPORT_SYMBOL_GPL(__pci_reset_function);
  
+ /**
+  * __pci_reset_function_locked - reset a PCI device function while holding
+  * the @dev mutex lock.
+  * @dev: PCI device to reset
+  *
+  * Some devices allow an individual function to be reset without affecting
+  * other functions in the same device.  The PCI device must be responsive
+  * to PCI config space in order to use this function.
+  *
+  * The device function is presumed to be unused and the caller is holding
+  * the device mutex lock when this function is called.
+  * Resetting the device will make the contents of PCI configuration space
+  * random, so any caller of this must be prepared to reinitialise the
+  * device including MSI, bus mastering, BARs, decoding IO and memory spaces,
+  * etc.
+  *
+  * Returns 0 if the device function was successfully reset or negative if the
+  * device doesn't support resetting a single function.
+  */
+ int __pci_reset_function_locked(struct pci_dev *dev)
+ {
+       return pci_dev_reset(dev, 1);
+ }
+ EXPORT_SYMBOL_GPL(__pci_reset_function_locked);
  /**
   * pci_probe_reset_function - check whether the device can be safely reset
   * @dev: PCI device to reset
diff --combined drivers/tty/hvc/Kconfig
index 48cb8d3d175878773b32c6d7cd3f0ef27fa077f0,192e21e2239c6547708c0f9c97061adcb24d5390..0282a83f51fbfa58d4771d071fb9414f1e934f44
@@@ -24,6 -24,16 +24,6 @@@ config HVC_OLD_HVS
        depends on HVC_CONSOLE
        default n
  
 -config HVC_ISERIES
 -      bool "iSeries Hypervisor Virtual Console support"
 -      depends on PPC_ISERIES
 -      default y
 -      select HVC_DRIVER
 -      select HVC_IRQ
 -      select VIOPATH
 -      help
 -        iSeries machines support a hypervisor virtual console.
 -
  config HVC_OPAL
        bool "OPAL Console support"
        depends on PPC_POWERNV
@@@ -66,15 -76,19 +66,23 @@@ config HVC_XE
        help
          Xen virtual console device driver
  
+ config HVC_XEN_FRONTEND
+       bool "Xen Hypervisor Multiple Consoles support"
+       depends on HVC_XEN
+       select XEN_XENBUS_FRONTEND
+       default y
+       help
+         Xen driver for secondary virtual consoles
  config HVC_UDBG
         bool "udbg based fake hypervisor console"
         depends on PPC && EXPERIMENTAL
         select HVC_DRIVER
         default n
 +       help
 +         This is meant to be used during HW bring up or debugging when
 +       no other console mechanism exist but udbg, to get you a quick
 +       console for userspace. Do NOT enable in production kernels. 
  
  config HVC_DCC
         bool "ARM JTAG DCC console"
diff --combined drivers/video/Kconfig
index 6ca0c407c1447151f1d9b64bfb6c9445acd61b72,269b29919567f3a0685f841c8a96c658509f725f..eca60c73ef1f7d4f476bf768a965275f2a1447f2
@@@ -1763,16 -1763,16 +1763,16 @@@ config FB_AU110
          au1100fb:panel=<name>.
  
  config FB_AU1200
 -      bool "Au1200 LCD Driver"
 +      bool "Au1200/Au1300 LCD Driver"
        depends on (FB = y) && MIPS_ALCHEMY
        select FB_SYS_FILLRECT
        select FB_SYS_COPYAREA
        select FB_SYS_IMAGEBLIT
        select FB_SYS_FOPS
        help
 -        This is the framebuffer driver for the AMD Au1200 SOC.  It can drive
 -        various panels and CRTs by passing in kernel cmd line option
 -        au1200fb:panel=<name>.
 +        This is the framebuffer driver for the Au1200/Au1300 SOCs.
 +        It can drive various panels and CRTs by passing in kernel cmd line
 +        option au1200fb:panel=<name>.
  
  config FB_VT8500
        bool "VT8500 LCD Driver"
@@@ -2269,6 -2269,7 +2269,7 @@@ config XEN_FBDEV_FRONTEN
        select FB_SYS_IMAGEBLIT
        select FB_SYS_FOPS
        select FB_DEFERRED_IO
+       select INPUT_XEN_KBDDEV_FRONTEND
        select XEN_XENBUS_FRONTEND
        default y
        help
@@@ -2413,6 -2414,7 +2414,6 @@@ source "drivers/video/omap/Kconfig
  source "drivers/video/omap2/Kconfig"
  
  source "drivers/video/backlight/Kconfig"
 -source "drivers/video/display/Kconfig"
  
  if VT
        source "drivers/video/console/Kconfig"
index 596e6a7b17d68bc3ebf424cc11344da1cc32f1e5,3f7922ec13e3d5ecabf46bf01dd48979e1a960a3..8f37e23f6d139ec1e46577eeaa6a599bba3b26eb
@@@ -207,7 -207,7 +207,7 @@@ static struct attribute *balloon_info_a
        NULL
  };
  
- static struct attribute_group balloon_info_group = {
+ static const struct attribute_group balloon_info_group = {
        .name = "info",
        .attrs = balloon_info_attrs
  };
@@@ -221,7 -221,7 +221,7 @@@ static int register_balloon(struct devi
  {
        int i, error;
  
 -      error = bus_register(&balloon_subsys);
 +      error = subsys_system_register(&balloon_subsys, NULL);
        if (error)
                return error;
  
index 19834d1c7c3679668fd50b3b3514ed0390014dfe,6f63b9d954fba3bf6207ec5b433f7940081e391f..097e536e8672d68ff32da41406156a75ed05a996
@@@ -85,19 -85,34 +85,34 @@@ static struct pcistub_device *pcistub_d
  static void pcistub_device_release(struct kref *kref)
  {
        struct pcistub_device *psdev;
+       struct xen_pcibk_dev_data *dev_data;
  
        psdev = container_of(kref, struct pcistub_device, kref);
+       dev_data = pci_get_drvdata(psdev->dev);
  
        dev_dbg(&psdev->dev->dev, "pcistub_device_release\n");
  
        xen_unregister_device_domain_owner(psdev->dev);
  
-       /* Clean-up the device */
+       /* Call the reset function which does not take lock as this
+        * is called from "unbind" which takes a device_lock mutex.
+        */
+       __pci_reset_function_locked(psdev->dev);
+       if (pci_load_and_free_saved_state(psdev->dev,
+                                         &dev_data->pci_saved_state)) {
+               dev_dbg(&psdev->dev->dev, "Could not reload PCI state\n");
+       } else
+               pci_restore_state(psdev->dev);
+       /* Disable the device */
        xen_pcibk_reset_device(psdev->dev);
+       kfree(dev_data);
+       pci_set_drvdata(psdev->dev, NULL);
+       /* Clean-up the device */
        xen_pcibk_config_free_dyn_fields(psdev->dev);
        xen_pcibk_config_free_dev(psdev->dev);
-       kfree(pci_get_drvdata(psdev->dev));
-       pci_set_drvdata(psdev->dev, NULL);
  
        psdev->dev->dev_flags &= ~PCI_DEV_FLAGS_ASSIGNED;
        pci_dev_put(psdev->dev);
@@@ -231,7 -246,17 +246,17 @@@ void pcistub_put_pci_dev(struct pci_de
        /* Cleanup our device
         * (so it's ready for the next domain)
         */
+       /* This is OK - we are running from workqueue context
+        * and want to inhibit the user from fiddling with 'reset'
+        */
+       pci_reset_function(dev);
+       pci_restore_state(psdev->dev);
+       /* This disables the device. */
        xen_pcibk_reset_device(found_psdev->dev);
+       /* And cleanup up our emulated fields. */
        xen_pcibk_config_free_dyn_fields(found_psdev->dev);
        xen_pcibk_config_reset_dev(found_psdev->dev);
  
@@@ -328,6 -353,16 +353,16 @@@ static int __devinit pcistub_init_devic
        if (err)
                goto config_release;
  
+       dev_dbg(&dev->dev, "reseting (FLR, D3, etc) the device\n");
+       __pci_reset_function_locked(dev);
+       /* We need the device active to save the state. */
+       dev_dbg(&dev->dev, "save state of device\n");
+       pci_save_state(dev);
+       dev_data->pci_saved_state = pci_store_saved_state(dev);
+       if (!dev_data->pci_saved_state)
+               dev_err(&dev->dev, "Could not store PCI conf saved state!\n");
        /* Now disable the device (this also ensures some private device
         * data is setup before we export)
         */
@@@ -884,7 -919,7 +919,7 @@@ static inline int str_to_quirk(const ch
        int err;
  
        err =
 -          sscanf(buf, " %04x:%02x:%02x.%1x-%08x:%1x:%08x", domain, bus, slot,
 +          sscanf(buf, " %04x:%02x:%02x.%d-%08x:%1x:%08x", domain, bus, slot,
                   func, reg, size, mask);
        if (err == 7)
                return 0;
@@@ -904,7 -939,7 +939,7 @@@ static int pcistub_device_id_add(int do
        pci_dev_id->bus = bus;
        pci_dev_id->devfn = PCI_DEVFN(slot, func);
  
 -      pr_debug(DRV_NAME ": wants to seize %04x:%02x:%02x.%01x\n",
 +      pr_debug(DRV_NAME ": wants to seize %04x:%02x:%02x.%d\n",
                 domain, bus, slot, func);
  
        spin_lock_irqsave(&device_ids_lock, flags);
@@@ -934,7 -969,7 +969,7 @@@ static int pcistub_device_id_remove(in
  
                        err = 0;
  
 -                      pr_debug(DRV_NAME ": removed %04x:%02x:%02x.%01x from "
 +                      pr_debug(DRV_NAME ": removed %04x:%02x:%02x.%d from "
                                 "seize list\n", domain, bus, slot, func);
                }
        }
@@@ -1029,7 -1064,7 +1064,7 @@@ static ssize_t pcistub_slot_show(struc
                        break;
  
                count += scnprintf(buf + count, PAGE_SIZE - count,
 -                                 "%04x:%02x:%02x.%01x\n",
 +                                 "%04x:%02x:%02x.%d\n",
                                   pci_dev_id->domain, pci_dev_id->bus,
                                   PCI_SLOT(pci_dev_id->devfn),
                                   PCI_FUNC(pci_dev_id->devfn));
diff --combined include/linux/pci.h
index 27bf521bcebdf2c4cc0376b025af8e65083c45ae,65c2d8a32b233414d273f6c8e6371c313c736d5d..900da5db60ee313a161ca9dc68ab504ce465f90d
@@@ -746,28 -746,28 +746,28 @@@ int pci_bus_write_config_dword(struct p
                               int where, u32 val);
  struct pci_ops *pci_bus_set_ops(struct pci_bus *bus, struct pci_ops *ops);
  
 -static inline int pci_read_config_byte(struct pci_dev *dev, int where, u8 *val)
 +static inline int pci_read_config_byte(const struct pci_dev *dev, int where, u8 *val)
  {
        return pci_bus_read_config_byte(dev->bus, dev->devfn, where, val);
  }
 -static inline int pci_read_config_word(struct pci_dev *dev, int where, u16 *val)
 +static inline int pci_read_config_word(const struct pci_dev *dev, int where, u16 *val)
  {
        return pci_bus_read_config_word(dev->bus, dev->devfn, where, val);
  }
 -static inline int pci_read_config_dword(struct pci_dev *dev, int where,
 +static inline int pci_read_config_dword(const struct pci_dev *dev, int where,
                                        u32 *val)
  {
        return pci_bus_read_config_dword(dev->bus, dev->devfn, where, val);
  }
 -static inline int pci_write_config_byte(struct pci_dev *dev, int where, u8 val)
 +static inline int pci_write_config_byte(const struct pci_dev *dev, int where, u8 val)
  {
        return pci_bus_write_config_byte(dev->bus, dev->devfn, where, val);
  }
 -static inline int pci_write_config_word(struct pci_dev *dev, int where, u16 val)
 +static inline int pci_write_config_word(const struct pci_dev *dev, int where, u16 val)
  {
        return pci_bus_write_config_word(dev->bus, dev->devfn, where, val);
  }
 -static inline int pci_write_config_dword(struct pci_dev *dev, int where,
 +static inline int pci_write_config_dword(const struct pci_dev *dev, int where,
                                         u32 val)
  {
        return pci_bus_write_config_dword(dev->bus, dev->devfn, where, val);
@@@ -817,6 -817,7 +817,7 @@@ int pcie_set_readrq(struct pci_dev *dev
  int pcie_get_mps(struct pci_dev *dev);
  int pcie_set_mps(struct pci_dev *dev, int mps);
  int __pci_reset_function(struct pci_dev *dev);
+ int __pci_reset_function_locked(struct pci_dev *dev);
  int pci_reset_function(struct pci_dev *dev);
  void pci_update_resource(struct pci_dev *dev, int resno);
  int __must_check pci_assign_resource(struct pci_dev *dev, int i);
@@@ -946,19 -947,6 +947,19 @@@ int __must_check __pci_register_driver(
        __pci_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)
  
  void pci_unregister_driver(struct pci_driver *dev);
 +
 +/**
 + * module_pci_driver() - Helper macro for registering a PCI driver
 + * @__pci_driver: pci_driver struct
 + *
 + * Helper macro for PCI drivers which do not do anything special in module
 + * init/exit. This eliminates a lot of boilerplate. Each module may only
 + * use this macro once, and calling it replaces module_init() and module_exit()
 + */
 +#define module_pci_driver(__pci_driver) \
 +      module_driver(__pci_driver, pci_register_driver, \
 +                     pci_unregister_driver)
 +
  void pci_remove_behind_bridge(struct pci_dev *dev);
  struct pci_driver *pci_dev_driver(const struct pci_dev *dev);
  int pci_add_dynid(struct pci_driver *drv,
@@@ -1660,13 -1648,6 +1661,13 @@@ static inline void pci_set_bus_of_node(
  static inline void pci_release_bus_of_node(struct pci_bus *bus) { }
  #endif  /* CONFIG_OF */
  
 +#ifdef CONFIG_EEH
 +static inline struct eeh_dev *pci_dev_to_eeh_dev(struct pci_dev *pdev)
 +{
 +      return pdev->dev.archdata.edev;
 +}
 +#endif
 +
  /**
   * pci_find_upstream_pcie_bridge - find upstream PCIe-to-PCI bridge of a device
   * @pdev: the PCI device