diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-24 20:20:25 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-24 20:20:25 +0100 |
commit | e22057c8599373e5caef0bc42bdb95d2a361ab0d (patch) | |
tree | 04e9f51835f4d5c08aada38597c30de1113c03d9 | |
parent | Fix potential endless loop in kswapd when compaction is not enabled (diff) | |
parent | xen/acpi: Fix Kconfig dependency on CPU_FREQ (diff) | |
download | linux-e22057c8599373e5caef0bc42bdb95d2a361ab0d.tar.xz linux-e22057c8599373e5caef0bc42bdb95d2a361ab0d.zip |
Merge tag 'stable/for-linus-3.4-tag-two' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen
Pull more xen updates from Konrad Rzeszutek Wilk:
"One tiny feature that accidentally got lost in the initial git pull:
* Add fast-EOI acking of interrupts (clear a bit instead of
hypercall)
And bug-fixes:
* Fix CPU bring-up code missing a call to notify other subsystems.
* Fix reading /sys/hypervisor even if PVonHVM drivers are not loaded.
* In Xen ACPI processor driver: remove too verbose WARN messages, fix
up the Kconfig dependency to be a module by default, and add
dependency on CPU_FREQ.
* Disable CPU frequency drivers from loading when booting under Xen
(as we want the Xen ACPI processor to be used instead).
* Cleanups in tmem code."
* tag 'stable/for-linus-3.4-tag-two' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen:
xen/acpi: Fix Kconfig dependency on CPU_FREQ
xen: initialize platform-pci even if xen_emul_unplug=never
xen/smp: Fix bringup bug in AP code.
xen/acpi: Remove the WARN's as they just create noise.
xen/tmem: cleanup
xen: support pirq_eoi_map
xen/acpi-processor: Do not depend on CPU frequency scaling drivers.
xen/cpufreq: Disable the cpu frequency scaling drivers from loading.
provide disable_cpufreq() function to disable the API.
-rw-r--r-- | arch/x86/xen/setup.c | 2 | ||||
-rw-r--r-- | arch/x86/xen/smp.c | 6 | ||||
-rw-r--r-- | drivers/block/xen-blkfront.c | 3 | ||||
-rw-r--r-- | drivers/net/xen-netfront.c | 4 | ||||
-rw-r--r-- | drivers/xen/Kconfig | 5 | ||||
-rw-r--r-- | drivers/xen/events.c | 26 | ||||
-rw-r--r-- | drivers/xen/platform-pci.c | 5 | ||||
-rw-r--r-- | drivers/xen/tmem.c | 21 | ||||
-rw-r--r-- | drivers/xen/xen-acpi-processor.c | 4 | ||||
-rw-r--r-- | include/xen/interface/physdev.h | 21 | ||||
-rw-r--r-- | include/xen/tmem.h | 6 |
11 files changed, 76 insertions, 27 deletions
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index 12366238d07d..1ba8dff26753 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c @@ -10,6 +10,7 @@ #include <linux/pm.h> #include <linux/memblock.h> #include <linux/cpuidle.h> +#include <linux/cpufreq.h> #include <asm/elf.h> #include <asm/vdso.h> @@ -420,6 +421,7 @@ void __init xen_arch_setup(void) boot_cpu_data.hlt_works_ok = 1; #endif disable_cpuidle(); + disable_cpufreq(); WARN_ON(set_pm_idle_to_default()); fiddle_vdso(); } diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 315d8fa0c8fb..02900e8ce26c 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c @@ -75,8 +75,14 @@ static void __cpuinit cpu_bringup(void) xen_setup_cpu_clockevents(); + notify_cpu_starting(cpu); + + ipi_call_lock(); set_cpu_online(cpu, true); + ipi_call_unlock(); + this_cpu_write(cpu_state, CPU_ONLINE); + wmb(); /* We can take interrupts now: we're officially "up". */ diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 2f22874c0a37..d5e1ab956740 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -1475,6 +1475,9 @@ static int __init xlblk_init(void) if (!xen_domain()) return -ENODEV; + if (!xen_platform_pci_unplug) + return -ENODEV; + if (register_blkdev(XENVBD_MAJOR, DEV_NAME)) { printk(KERN_WARNING "xen_blk: can't get major %d with name %s\n", XENVBD_MAJOR, DEV_NAME); diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index b16175032327..663b32c2e931 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -47,6 +47,7 @@ #include <xen/xenbus.h> #include <xen/events.h> #include <xen/page.h> +#include <xen/platform_pci.h> #include <xen/grant_table.h> #include <xen/interface/io/netif.h> @@ -1964,6 +1965,9 @@ static int __init netif_init(void) if (xen_initial_domain()) return 0; + if (!xen_platform_pci_unplug) + return -ENODEV; + printk(KERN_INFO "Initialising Xen virtual ethernet driver.\n"); return xenbus_register_frontend(&netfront_driver); diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig index 648bcd4195c5..94243136f6bf 100644 --- a/drivers/xen/Kconfig +++ b/drivers/xen/Kconfig @@ -180,9 +180,8 @@ config XEN_PRIVCMD config XEN_ACPI_PROCESSOR tristate "Xen ACPI processor" - depends on XEN && X86 && ACPI_PROCESSOR - default y if (X86_ACPI_CPUFREQ = y || X86_POWERNOW_K8 = y) - default m if (X86_ACPI_CPUFREQ = m || X86_POWERNOW_K8 = m) + depends on XEN && X86 && ACPI_PROCESSOR && CPU_FREQ + default m help This ACPI processor uploads Power Management information to the Xen hypervisor. diff --git a/drivers/xen/events.c b/drivers/xen/events.c index e5e5812a1014..4b33acd8ed4e 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -37,6 +37,7 @@ #include <asm/idle.h> #include <asm/io_apic.h> #include <asm/sync_bitops.h> +#include <asm/xen/page.h> #include <asm/xen/pci.h> #include <asm/xen/hypercall.h> #include <asm/xen/hypervisor.h> @@ -109,6 +110,8 @@ struct irq_info { #define PIRQ_SHAREABLE (1 << 1) static int *evtchn_to_irq; +static unsigned long *pirq_eoi_map; +static bool (*pirq_needs_eoi)(unsigned irq); static DEFINE_PER_CPU(unsigned long [NR_EVENT_CHANNELS/BITS_PER_LONG], cpu_evtchn_mask); @@ -269,10 +272,14 @@ static unsigned int cpu_from_evtchn(unsigned int evtchn) return ret; } -static bool pirq_needs_eoi(unsigned irq) +static bool pirq_check_eoi_map(unsigned irq) { - struct irq_info *info = info_for_irq(irq); + return test_bit(irq, pirq_eoi_map); +} +static bool pirq_needs_eoi_flag(unsigned irq) +{ + struct irq_info *info = info_for_irq(irq); BUG_ON(info->type != IRQT_PIRQ); return info->u.pirq.flags & PIRQ_NEEDS_EOI; @@ -1768,7 +1775,7 @@ void xen_callback_vector(void) {} void __init xen_init_IRQ(void) { - int i; + int i, rc; evtchn_to_irq = kcalloc(NR_EVENT_CHANNELS, sizeof(*evtchn_to_irq), GFP_KERNEL); @@ -1782,6 +1789,8 @@ void __init xen_init_IRQ(void) for (i = 0; i < NR_EVENT_CHANNELS; i++) mask_evtchn(i); + pirq_needs_eoi = pirq_needs_eoi_flag; + if (xen_hvm_domain()) { xen_callback_vector(); native_init_IRQ(); @@ -1789,8 +1798,19 @@ void __init xen_init_IRQ(void) * __acpi_register_gsi can point at the right function */ pci_xen_hvm_init(); } else { + struct physdev_pirq_eoi_gmfn eoi_gmfn; + irq_ctx_init(smp_processor_id()); if (xen_initial_domain()) pci_xen_initial_domain(); + + pirq_eoi_map = (void *)__get_free_page(GFP_KERNEL|__GFP_ZERO); + eoi_gmfn.gmfn = virt_to_mfn(pirq_eoi_map); + rc = HYPERVISOR_physdev_op(PHYSDEVOP_pirq_eoi_gmfn_v2, &eoi_gmfn); + if (rc != 0) { + free_page((unsigned long) pirq_eoi_map); + pirq_eoi_map = NULL; + } else + pirq_needs_eoi = pirq_check_eoi_map; } } diff --git a/drivers/xen/platform-pci.c b/drivers/xen/platform-pci.c index 319dd0a94d51..2389e581e23c 100644 --- a/drivers/xen/platform-pci.c +++ b/drivers/xen/platform-pci.c @@ -186,11 +186,6 @@ static struct pci_driver platform_driver = { static int __init platform_pci_module_init(void) { - /* no unplug has been done, IGNORE hasn't been specified: just - * return now */ - if (!xen_platform_pci_unplug) - return -ENODEV; - return pci_register_driver(&platform_driver); } diff --git a/drivers/xen/tmem.c b/drivers/xen/tmem.c index 17d9e37beba4..dcb79521e6c8 100644 --- a/drivers/xen/tmem.c +++ b/drivers/xen/tmem.c @@ -9,7 +9,6 @@ #include <linux/types.h> #include <linux/init.h> #include <linux/pagemap.h> -#include <linux/module.h> #include <linux/cleancache.h> /* temporary ifdef until include/linux/frontswap.h is upstream */ @@ -128,15 +127,13 @@ static int xen_tmem_flush_object(u32 pool_id, struct tmem_oid oid) return xen_tmem_op(TMEM_FLUSH_OBJECT, pool_id, oid, 0, 0, 0, 0, 0); } -int tmem_enabled __read_mostly; -EXPORT_SYMBOL(tmem_enabled); +bool __read_mostly tmem_enabled = false; static int __init enable_tmem(char *s) { - tmem_enabled = 1; + tmem_enabled = true; return 1; } - __setup("tmem", enable_tmem); #ifdef CONFIG_CLEANCACHE @@ -229,17 +226,16 @@ static int tmem_cleancache_init_shared_fs(char *uuid, size_t pagesize) return xen_tmem_new_pool(shared_uuid, TMEM_POOL_SHARED, pagesize); } -static int use_cleancache = 1; +static bool __initdata use_cleancache = true; static int __init no_cleancache(char *s) { - use_cleancache = 0; + use_cleancache = false; return 1; } - __setup("nocleancache", no_cleancache); -static struct cleancache_ops tmem_cleancache_ops = { +static struct cleancache_ops __initdata tmem_cleancache_ops = { .put_page = tmem_cleancache_put_page, .get_page = tmem_cleancache_get_page, .invalidate_page = tmem_cleancache_flush_page, @@ -356,17 +352,16 @@ static void tmem_frontswap_init(unsigned ignored) xen_tmem_new_pool(private, TMEM_POOL_PERSIST, PAGE_SIZE); } -static int __initdata use_frontswap = 1; +static bool __initdata use_frontswap = true; static int __init no_frontswap(char *s) { - use_frontswap = 0; + use_frontswap = false; return 1; } - __setup("nofrontswap", no_frontswap); -static struct frontswap_ops tmem_frontswap_ops = { +static struct frontswap_ops __initdata tmem_frontswap_ops = { .put_page = tmem_frontswap_put_page, .get_page = tmem_frontswap_get_page, .invalidate_page = tmem_frontswap_flush_page, diff --git a/drivers/xen/xen-acpi-processor.c b/drivers/xen/xen-acpi-processor.c index 5c2be963aa18..174b5653cd8a 100644 --- a/drivers/xen/xen-acpi-processor.c +++ b/drivers/xen/xen-acpi-processor.c @@ -501,11 +501,11 @@ static int __init xen_acpi_processor_init(void) perf = per_cpu_ptr(acpi_perf_data, i); rc = acpi_processor_register_performance(perf, i); - if (WARN_ON(rc)) + if (rc) goto err_out; } rc = acpi_processor_notify_smm(THIS_MODULE); - if (WARN_ON(rc)) + if (rc) goto err_unregister; for_each_possible_cpu(i) { diff --git a/include/xen/interface/physdev.h b/include/xen/interface/physdev.h index 0c28989007fb..9ce788d8cf49 100644 --- a/include/xen/interface/physdev.h +++ b/include/xen/interface/physdev.h @@ -39,6 +39,27 @@ struct physdev_eoi { }; /* + * Register a shared page for the hypervisor to indicate whether the guest + * must issue PHYSDEVOP_eoi. The semantics of PHYSDEVOP_eoi change slightly + * once the guest used this function in that the associated event channel + * will automatically get unmasked. The page registered is used as a bit + * array indexed by Xen's PIRQ value. + */ +#define PHYSDEVOP_pirq_eoi_gmfn_v1 17 +/* + * Register a shared page for the hypervisor to indicate whether the + * guest must issue PHYSDEVOP_eoi. This hypercall is very similar to + * PHYSDEVOP_pirq_eoi_gmfn_v1 but it doesn't change the semantics of + * PHYSDEVOP_eoi. The page registered is used as a bit array indexed by + * Xen's PIRQ value. + */ +#define PHYSDEVOP_pirq_eoi_gmfn_v2 28 +struct physdev_pirq_eoi_gmfn { + /* IN */ + unsigned long gmfn; +}; + +/* * Query the status of an IRQ line. * @arg == pointer to physdev_irq_status_query structure. */ diff --git a/include/xen/tmem.h b/include/xen/tmem.h index 82e2c83a32f5..591550a22ac7 100644 --- a/include/xen/tmem.h +++ b/include/xen/tmem.h @@ -1,5 +1,9 @@ #ifndef _XEN_TMEM_H #define _XEN_TMEM_H + +#include <linux/types.h> + /* defined in drivers/xen/tmem.c */ -extern int tmem_enabled; +extern bool tmem_enabled; + #endif /* _XEN_TMEM_H */ |