Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 26 May 2009 19:09:32 +0000 (12:09 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 26 May 2009 19:09:32 +0000 (12:09 -0700)
* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc:
  powerpc/mm: Fix broken MMU PID stealing on !SMP

17 files changed:
Documentation/kernel-parameters.txt
arch/x86/boot/memory.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/reboot.c
arch/x86/kernel/setup_percpu.c
arch/x86/kvm/mmu.c
arch/x86/kvm/x86.c
arch/x86/mm/pageattr.c
drivers/base/power/main.c
drivers/md/bitmap.c
drivers/md/md.c
drivers/md/raid5.c
init/main.c
kernel/async.c
kernel/kexec.c
kernel/power/disk.c
kernel/power/main.c

index e87bdbfbcc75e236124a526d4456ddf3c6afc4e3..fd5cac013037defc68c3ef118ed70b476debee71 100644 (file)
@@ -1535,6 +1535,10 @@ and is between 256 and 4096 characters. It is defined in the file
                        register save and restore. The kernel will only save
                        legacy floating-point registers on task switch.
 
+       noxsave         [BUGS=X86] Disables x86 extended register state save
+                       and restore using xsave. The kernel will fallback to
+                       enabling legacy floating-point and sse state.
+
        nohlt           [BUGS=ARM,SH] Tells the kernel that the sleep(SH) or
                        wfi(ARM) instruction doesn't work correctly and not to
                        use it. This is also useful when using JTAG debugger.
index 5054c2ddd1a03471b4423e7c9eb1719dca667901..74b3d2ba84e90a39bb29f166278ce47bcf56437c 100644 (file)
 
 #define SMAP   0x534d4150      /* ASCII "SMAP" */
 
-struct e820_ext_entry {
-       struct e820entry std;
-       u32 ext_flags;
-} __attribute__((packed));
-
 static int detect_memory_e820(void)
 {
        int count = 0;
@@ -29,13 +24,21 @@ static int detect_memory_e820(void)
        u32 size, id, edi;
        u8 err;
        struct e820entry *desc = boot_params.e820_map;
-       static struct e820_ext_entry buf; /* static so it is zeroed */
+       static struct e820entry buf; /* static so it is zeroed */
 
        /*
-        * Set this here so that if the BIOS doesn't change this field
-        * but still doesn't change %ecx, we're still okay...
+        * Note: at least one BIOS is known which assumes that the
+        * buffer pointed to by one e820 call is the same one as
+        * the previous call, and only changes modified fields.  Therefore,
+        * we use a temporary buffer and copy the results entry by entry.
+        *
+        * This routine deliberately does not try to account for
+        * ACPI 3+ extended attributes.  This is because there are
+        * BIOSes in the field which report zero for the valid bit for
+        * all ranges, and we don't currently make any use of the
+        * other attribute bits.  Revisit this if we see the extended
+        * attribute bits deployed in a meaningful way in the future.
         */
-       buf.ext_flags = 1;
 
        do {
                size = sizeof buf;
@@ -66,13 +69,7 @@ static int detect_memory_e820(void)
                        break;
                }
 
-               /* ACPI 3.0 added the extended flags support.  If bit 0
-                  in the extended flags is zero, we're supposed to simply
-                  ignore the entry -- a backwards incompatible change! */
-               if (size > 20 && !(buf.ext_flags & 1))
-                       continue;
-
-               *desc++ = buf.std;
+               *desc++ = buf;
                count++;
        } while (next && count < ARRAY_SIZE(boot_params.e820_map));
 
index c1caefc82e62512245f52b17251af69d2b2d2c2b..77848d9fca6833fa88488adb6e22cae027a7d6c1 100644 (file)
@@ -114,6 +114,13 @@ DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = {
 } };
 EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
 
+static int __init x86_xsave_setup(char *s)
+{
+       setup_clear_cpu_cap(X86_FEATURE_XSAVE);
+       return 1;
+}
+__setup("noxsave", x86_xsave_setup);
+
 #ifdef CONFIG_X86_32
 static int cachesize_override __cpuinitdata = -1;
 static int disable_x86_serial_nr __cpuinitdata = 1;
index 1340dad417f43d8a9fa2666a9e22135daead60c0..667188e0b5a0bfac320d69a0f734dda03b5bee88 100644 (file)
@@ -232,6 +232,14 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "Dell DXP061"),
                },
        },
+       {       /* Handle problems with rebooting on Sony VGN-Z540N */
+               .callback = set_bios_reboot,
+               .ident = "Sony VGN-Z540N",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "VGN-Z540N"),
+               },
+       },
        { }
 };
 
index 3a97a4cf187245462f3890f08313544762642f28..8f0e13be36b31d1a80c94dec2692504d2a9a86db 100644 (file)
@@ -160,8 +160,10 @@ static ssize_t __init setup_pcpu_remap(size_t static_size)
        /*
         * If large page isn't supported, there's no benefit in doing
         * this.  Also, on non-NUMA, embedding is better.
+        *
+        * NOTE: disabled for now.
         */
-       if (!cpu_has_pse || !pcpu_need_numa())
+       if (true || !cpu_has_pse || !pcpu_need_numa())
                return -EINVAL;
 
        /*
index b6caf1329b1b12e003dff8f8d761f67e39810f2f..32cf11e5728a2c1c444c407dfc287b8adf1c3c40 100644 (file)
@@ -2897,8 +2897,7 @@ static int kvm_pv_mmu_write(struct kvm_vcpu *vcpu,
 
 static int kvm_pv_mmu_flush_tlb(struct kvm_vcpu *vcpu)
 {
-       kvm_x86_ops->tlb_flush(vcpu);
-       set_bit(KVM_REQ_MMU_SYNC, &vcpu->requests);
+       kvm_set_cr3(vcpu, vcpu->arch.cr3);
        return 1;
 }
 
index 49079a46687b740f2e91d2bbfbc31c1c5094c22a..3944e917e794fad77dc54d2afaedda47d6dcdca7 100644 (file)
@@ -338,6 +338,9 @@ EXPORT_SYMBOL_GPL(kvm_lmsw);
 
 void kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
 {
+       unsigned long old_cr4 = vcpu->arch.cr4;
+       unsigned long pdptr_bits = X86_CR4_PGE | X86_CR4_PSE | X86_CR4_PAE;
+
        if (cr4 & CR4_RESERVED_BITS) {
                printk(KERN_DEBUG "set_cr4: #GP, reserved bits\n");
                kvm_inject_gp(vcpu, 0);
@@ -351,7 +354,8 @@ void kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
                        kvm_inject_gp(vcpu, 0);
                        return;
                }
-       } else if (is_paging(vcpu) && !is_pae(vcpu) && (cr4 & X86_CR4_PAE)
+       } else if (is_paging(vcpu) && (cr4 & X86_CR4_PAE)
+                  && ((cr4 ^ old_cr4) & pdptr_bits)
                   && !load_pdptrs(vcpu, vcpu->arch.cr3)) {
                printk(KERN_DEBUG "set_cr4: #GP, pdptrs reserved bits\n");
                kvm_inject_gp(vcpu, 0);
index 797f9f107cb6871a3797680c7dbed9430cb0f354..0f9052bcec4b7572cb8519f7972294fa716ac51a 100644 (file)
@@ -153,7 +153,7 @@ static void __cpa_flush_all(void *arg)
         */
        __flush_tlb_all();
 
-       if (cache && boot_cpu_data.x86_model >= 4)
+       if (cache && boot_cpu_data.x86 >= 4)
                wbinvd();
 }
 
@@ -204,6 +204,11 @@ static void cpa_flush_range(unsigned long start, int numpages, int cache)
        }
 }
 
+static void wbinvd_local(void *unused)
+{
+       wbinvd();
+}
+
 static void cpa_flush_array(unsigned long *start, int numpages, int cache,
                            int in_flags, struct page **pages)
 {
@@ -218,8 +223,9 @@ static void cpa_flush_array(unsigned long *start, int numpages, int cache,
 
        /* 4M threshold */
        if (numpages >= 1024) {
-               if (boot_cpu_data.x86_model >= 4)
-                       wbinvd();
+               if (boot_cpu_data.x86 >= 4)
+                       on_each_cpu(wbinvd_local, NULL, 1);
+
                return;
        }
        /*
index 69b4ddb7de3b8c00d59a34fd16af5dc789e7b109..3e4bc699bc0f30349be3ed75b9ecc28cdb77ddf1 100644 (file)
@@ -357,6 +357,7 @@ static void dpm_power_up(pm_message_t state)
 {
        struct device *dev;
 
+       mutex_lock(&dpm_list_mtx);
        list_for_each_entry(dev, &dpm_list, power.entry)
                if (dev->power.status > DPM_OFF) {
                        int error;
@@ -366,6 +367,7 @@ static void dpm_power_up(pm_message_t state)
                        if (error)
                                pm_dev_err(dev, state, " early", error);
                }
+       mutex_unlock(&dpm_list_mtx);
 }
 
 /**
@@ -614,6 +616,7 @@ int device_power_down(pm_message_t state)
        int error = 0;
 
        suspend_device_irqs();
+       mutex_lock(&dpm_list_mtx);
        list_for_each_entry_reverse(dev, &dpm_list, power.entry) {
                error = suspend_device_noirq(dev, state);
                if (error) {
@@ -622,6 +625,7 @@ int device_power_down(pm_message_t state)
                }
                dev->power.status = DPM_OFF_IRQ;
        }
+       mutex_unlock(&dpm_list_mtx);
        if (error)
                device_power_up(resume_event(state));
        return error;
index 47c68bc75a1780be7e1b6679e64d8ee8b6e860e9..56df1cee8fb3435a43e33b07ba1a3dadaf528680 100644 (file)
@@ -1097,14 +1097,12 @@ void bitmap_daemon_work(struct bitmap *bitmap)
        }
        bitmap->allclean = 1;
 
+       spin_lock_irqsave(&bitmap->lock, flags);
        for (j = 0; j < bitmap->chunks; j++) {
                bitmap_counter_t *bmc;
-               spin_lock_irqsave(&bitmap->lock, flags);
-               if (!bitmap->filemap) {
+               if (!bitmap->filemap)
                        /* error or shutdown */
-                       spin_unlock_irqrestore(&bitmap->lock, flags);
                        break;
-               }
 
                page = filemap_get_page(bitmap, j);
 
@@ -1121,6 +1119,8 @@ void bitmap_daemon_work(struct bitmap *bitmap)
                                        write_page(bitmap, page, 0);
                                        bitmap->allclean = 0;
                                }
+                               spin_lock_irqsave(&bitmap->lock, flags);
+                               j |= (PAGE_BITS - 1);
                                continue;
                        }
 
@@ -1181,9 +1181,10 @@ void bitmap_daemon_work(struct bitmap *bitmap)
                                        ext2_clear_bit(file_page_offset(j), paddr);
                                kunmap_atomic(paddr, KM_USER0);
                        }
-               }
-               spin_unlock_irqrestore(&bitmap->lock, flags);
+               } else
+                       j |= PAGE_COUNTER_MASK;
        }
+       spin_unlock_irqrestore(&bitmap->lock, flags);
 
        /* now sync the final page */
        if (lastpage != NULL) {
index fccc8343a2501dbb8db452ea9e5469df11ef53e1..641b211fe3feb33e15cb1159e3a76ca26b90c124 100644 (file)
@@ -1375,6 +1375,9 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
 
        sb->raid_disks = cpu_to_le32(mddev->raid_disks);
        sb->size = cpu_to_le64(mddev->dev_sectors);
+       sb->chunksize = cpu_to_le32(mddev->chunk_size >> 9);
+       sb->level = cpu_to_le32(mddev->level);
+       sb->layout = cpu_to_le32(mddev->layout);
 
        if (mddev->bitmap && mddev->bitmap_file == NULL) {
                sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_offset);
@@ -3303,7 +3306,9 @@ static ssize_t
 action_show(mddev_t *mddev, char *page)
 {
        char *type = "idle";
-       if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
+       if (test_bit(MD_RECOVERY_FROZEN, &mddev->recovery))
+               type = "frozen";
+       else if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
            (!mddev->ro && test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))) {
                if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
                        type = "reshape";
@@ -3326,7 +3331,12 @@ action_store(mddev_t *mddev, const char *page, size_t len)
        if (!mddev->pers || !mddev->pers->sync_request)
                return -EINVAL;
 
-       if (cmd_match(page, "idle")) {
+       if (cmd_match(page, "frozen"))
+               set_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+       else
+               clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+
+       if (cmd_match(page, "idle") || cmd_match(page, "frozen")) {
                if (mddev->sync_thread) {
                        set_bit(MD_RECOVERY_INTR, &mddev->recovery);
                        md_unregister_thread(mddev->sync_thread);
@@ -3680,7 +3690,7 @@ array_size_store(mddev_t *mddev, const char *buf, size_t len)
                if (strict_blocks_to_sectors(buf, &sectors) < 0)
                        return -EINVAL;
                if (mddev->pers && mddev->pers->size(mddev, 0, 0) < sectors)
-                       return -EINVAL;
+                       return -E2BIG;
 
                mddev->external_size = 1;
        }
@@ -5557,7 +5567,7 @@ static struct block_device_operations md_fops =
        .owner          = THIS_MODULE,
        .open           = md_open,
        .release        = md_release,
-       .locked_ioctl   = md_ioctl,
+       .ioctl          = md_ioctl,
        .getgeo         = md_getgeo,
        .media_changed  = md_media_changed,
        .revalidate_disk= md_revalidate,
@@ -6352,12 +6362,13 @@ void md_do_sync(mddev_t *mddev)
 
                skipped = 0;
 
-               if ((mddev->curr_resync > mddev->curr_resync_completed &&
-                    (mddev->curr_resync - mddev->curr_resync_completed)
-                   > (max_sectors >> 4)) ||
-                   (j - mddev->curr_resync_completed)*2
-                   >= mddev->resync_max - mddev->curr_resync_completed
-                       ) {
+               if (!test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) &&
+                   ((mddev->curr_resync > mddev->curr_resync_completed &&
+                     (mddev->curr_resync - mddev->curr_resync_completed)
+                     > (max_sectors >> 4)) ||
+                    (j - mddev->curr_resync_completed)*2
+                    >= mddev->resync_max - mddev->curr_resync_completed
+                           )) {
                        /* time to update curr_resync_completed */
                        blk_unplug(mddev->queue);
                        wait_event(mddev->recovery_wait,
index 4616bc3a6e713065e689943db4cdde421076d318..3c3626d2a1f9fe7a616bf84626a39593a56c2f84 100644 (file)
@@ -3811,13 +3811,13 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
        safepos = conf->reshape_safe;
        sector_div(safepos, data_disks);
        if (mddev->delta_disks < 0) {
-               writepos -= reshape_sectors;
+               writepos -= min(reshape_sectors, writepos);
                readpos += reshape_sectors;
                safepos += reshape_sectors;
        } else {
                writepos += reshape_sectors;
-               readpos -= reshape_sectors;
-               safepos -= reshape_sectors;
+               readpos -= min(reshape_sectors, readpos);
+               safepos -= min(reshape_sectors, safepos);
        }
 
        /* 'writepos' is the most advanced device address we might write.
index 3bbf93be744cf8be8614ca92c32b01181bf58a4f..d721dad05dd722fa065170e9f573a4f74c49d38d 100644 (file)
@@ -566,8 +566,7 @@ asmlinkage void __init start_kernel(void)
        tick_init();
        boot_cpu_init();
        page_address_init();
-       printk(KERN_NOTICE);
-       printk(linux_banner);
+       printk(KERN_NOTICE "%s", linux_banner);
        setup_arch(&command_line);
        mm_init_owner(&init_mm, &init_task);
        setup_command_line(command_line);
index 968ef9457d4ec90aeb5148695c31ae02b68d33bb..50540301ed0f2d5308ab15a012715bd0b53f0a04 100644 (file)
@@ -92,19 +92,23 @@ extern int initcall_debug;
 static async_cookie_t  __lowest_in_progress(struct list_head *running)
 {
        struct async_entry *entry;
+       async_cookie_t ret = next_cookie; /* begin with "infinity" value */
+
        if (!list_empty(running)) {
                entry = list_first_entry(running,
                        struct async_entry, list);
-               return entry->cookie;
-       } else if (!list_empty(&async_pending)) {
-               entry = list_first_entry(&async_pending,
-                       struct async_entry, list);
-               return entry->cookie;
-       } else {
-               /* nothing in progress... next_cookie is "infinity" */
-               return next_cookie;
+               ret = entry->cookie;
        }
 
+       if (!list_empty(&async_pending)) {
+               list_for_each_entry(entry, &async_pending, list)
+                       if (entry->running == running) {
+                               ret = entry->cookie;
+                               break;
+                       }
+       }
+
+       return ret;
 }
 
 static async_cookie_t  lowest_in_progress(struct list_head *running)
index 5a758c6e4950492fcb15248c91ed4f5f6b824dbc..e4983770913b915e85fb2906e4f9ffd766d0694f 100644 (file)
@@ -1451,7 +1451,6 @@ int kernel_kexec(void)
                error = device_suspend(PMSG_FREEZE);
                if (error)
                        goto Resume_console;
-               device_pm_lock();
                /* At this point, device_suspend() has been called,
                 * but *not* device_power_down(). We *must*
                 * device_power_down() now.  Otherwise, drivers for
@@ -1489,7 +1488,6 @@ int kernel_kexec(void)
                enable_nonboot_cpus();
                device_power_up(PMSG_RESTORE);
  Resume_devices:
-               device_pm_unlock();
                device_resume(PMSG_RESTORE);
  Resume_console:
                resume_console();
index b0dc9e7a0d17555d19baecbf1780948ec647698a..5cb080e7eebd9a388d31a12425283c6b768a6e59 100644 (file)
@@ -215,8 +215,6 @@ static int create_image(int platform_mode)
        if (error)
                return error;
 
-       device_pm_lock();
-
        /* At this point, device_suspend() has been called, but *not*
         * device_power_down(). We *must* call device_power_down() now.
         * Otherwise, drivers for some devices (e.g. interrupt controllers)
@@ -227,7 +225,7 @@ static int create_image(int platform_mode)
        if (error) {
                printk(KERN_ERR "PM: Some devices failed to power down, "
                        "aborting hibernation\n");
-               goto Unlock;
+               return error;
        }
 
        error = platform_pre_snapshot(platform_mode);
@@ -280,9 +278,6 @@ static int create_image(int platform_mode)
        device_power_up(in_suspend ?
                (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE);
 
- Unlock:
-       device_pm_unlock();
-
        return error;
 }
 
@@ -344,13 +339,11 @@ static int resume_target_kernel(bool platform_mode)
 {
        int error;
 
-       device_pm_lock();
-
        error = device_power_down(PMSG_QUIESCE);
        if (error) {
                printk(KERN_ERR "PM: Some devices failed to power down, "
                        "aborting resume\n");
-               goto Unlock;
+               return error;
        }
 
        error = platform_pre_restore(platform_mode);
@@ -403,9 +396,6 @@ static int resume_target_kernel(bool platform_mode)
 
        device_power_up(PMSG_RECOVER);
 
- Unlock:
-       device_pm_unlock();
-
        return error;
 }
 
@@ -464,11 +454,9 @@ int hibernation_platform_enter(void)
                goto Resume_devices;
        }
 
-       device_pm_lock();
-
        error = device_power_down(PMSG_HIBERNATE);
        if (error)
-               goto Unlock;
+               goto Resume_devices;
 
        error = hibernation_ops->prepare();
        if (error)
@@ -493,9 +481,6 @@ int hibernation_platform_enter(void)
 
        device_power_up(PMSG_RESTORE);
 
- Unlock:
-       device_pm_unlock();
-
  Resume_devices:
        entering_platform_hibernation = false;
        device_resume(PMSG_RESTORE);
index f99ed6a75eac434c7720607fefb480771eae3df5..868028280d13474811810098cfa0f1923d212b32 100644 (file)
@@ -289,12 +289,10 @@ static int suspend_enter(suspend_state_t state)
 {
        int error;
 
-       device_pm_lock();
-
        if (suspend_ops->prepare) {
                error = suspend_ops->prepare();
                if (error)
-                       goto Done;
+                       return error;
        }
 
        error = device_power_down(PMSG_SUSPEND);
@@ -343,9 +341,6 @@ static int suspend_enter(suspend_state_t state)
        if (suspend_ops->finish)
                suspend_ops->finish();
 
- Done:
-       device_pm_unlock();
-
        return error;
 }