diff options
36 files changed, 367 insertions, 80 deletions
@@ -533,7 +533,7 @@ endif | |||
533 | 533 | ||
534 | include $(srctree)/arch/$(SRCARCH)/Makefile | 534 | include $(srctree)/arch/$(SRCARCH)/Makefile |
535 | 535 | ||
536 | ifneq (CONFIG_FRAME_WARN,0) | 536 | ifneq ($(CONFIG_FRAME_WARN),0) |
537 | KBUILD_CFLAGS += $(call cc-option,-Wframe-larger-than=${CONFIG_FRAME_WARN}) | 537 | KBUILD_CFLAGS += $(call cc-option,-Wframe-larger-than=${CONFIG_FRAME_WARN}) |
538 | endif | 538 | endif |
539 | 539 | ||
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index f6b32d112357..35dc8fbe92bd 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c | |||
@@ -835,7 +835,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) | |||
835 | { | 835 | { |
836 | struct cpufreq_frequency_table *powernow_table; | 836 | struct cpufreq_frequency_table *powernow_table; |
837 | int ret_val = -ENODEV; | 837 | int ret_val = -ENODEV; |
838 | acpi_integer space_id; | 838 | acpi_integer control, status; |
839 | 839 | ||
840 | if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) { | 840 | if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) { |
841 | dprintk("register performance failed: bad ACPI data\n"); | 841 | dprintk("register performance failed: bad ACPI data\n"); |
@@ -848,12 +848,13 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) | |||
848 | goto err_out; | 848 | goto err_out; |
849 | } | 849 | } |
850 | 850 | ||
851 | space_id = data->acpi_data.control_register.space_id; | 851 | control = data->acpi_data.control_register.space_id; |
852 | if ((space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) || | 852 | status = data->acpi_data.status_register.space_id; |
853 | (space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) { | 853 | |
854 | if ((control != ACPI_ADR_SPACE_FIXED_HARDWARE) || | ||
855 | (status != ACPI_ADR_SPACE_FIXED_HARDWARE)) { | ||
854 | dprintk("Invalid control/status registers (%x - %x)\n", | 856 | dprintk("Invalid control/status registers (%x - %x)\n", |
855 | data->acpi_data.control_register.space_id, | 857 | control, status); |
856 | space_id); | ||
857 | goto err_out; | 858 | goto err_out; |
858 | } | 859 | } |
859 | 860 | ||
diff --git a/arch/x86/lguest/Makefile b/arch/x86/lguest/Makefile index 27f0c9ed7f60..94e0e54056a9 100644 --- a/arch/x86/lguest/Makefile +++ b/arch/x86/lguest/Makefile | |||
@@ -1 +1,2 @@ | |||
1 | obj-y := i386_head.o boot.o | 1 | obj-y := i386_head.o boot.o |
2 | CFLAGS_boot.o := $(call cc-option, -fno-stack-protector) | ||
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index ca7ec44bafc3..33a93b417396 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c | |||
@@ -67,6 +67,7 @@ | |||
67 | #include <asm/mce.h> | 67 | #include <asm/mce.h> |
68 | #include <asm/io.h> | 68 | #include <asm/io.h> |
69 | #include <asm/i387.h> | 69 | #include <asm/i387.h> |
70 | #include <asm/stackprotector.h> | ||
70 | #include <asm/reboot.h> /* for struct machine_ops */ | 71 | #include <asm/reboot.h> /* for struct machine_ops */ |
71 | 72 | ||
72 | /*G:010 Welcome to the Guest! | 73 | /*G:010 Welcome to the Guest! |
@@ -1088,13 +1089,21 @@ __init void lguest_init(void) | |||
1088 | * lguest_init() where the rest of the fairly chaotic boot setup | 1089 | * lguest_init() where the rest of the fairly chaotic boot setup |
1089 | * occurs. */ | 1090 | * occurs. */ |
1090 | 1091 | ||
1092 | /* The stack protector is a weird thing where gcc places a canary | ||
1093 | * value on the stack and then checks it on return. This file is | ||
1094 | * compiled with -fno-stack-protector it, so we got this far without | ||
1095 | * problems. The value of the canary is kept at offset 20 from the | ||
1096 | * %gs register, so we need to set that up before calling C functions | ||
1097 | * in other files. */ | ||
1098 | setup_stack_canary_segment(0); | ||
1099 | /* We could just call load_stack_canary_segment(), but we might as | ||
1100 | * call switch_to_new_gdt() which loads the whole table and sets up | ||
1101 | * the per-cpu segment descriptor register %fs as well. */ | ||
1102 | switch_to_new_gdt(0); | ||
1103 | |||
1091 | /* As described in head_32.S, we map the first 128M of memory. */ | 1104 | /* As described in head_32.S, we map the first 128M of memory. */ |
1092 | max_pfn_mapped = (128*1024*1024) >> PAGE_SHIFT; | 1105 | max_pfn_mapped = (128*1024*1024) >> PAGE_SHIFT; |
1093 | 1106 | ||
1094 | /* Load the %fs segment register (the per-cpu segment register) with | ||
1095 | * the normal data segment to get through booting. */ | ||
1096 | asm volatile ("mov %0, %%fs" : : "r" (__KERNEL_DS) : "memory"); | ||
1097 | |||
1098 | /* The Host<->Guest Switcher lives at the top of our address space, and | 1107 | /* The Host<->Guest Switcher lives at the top of our address space, and |
1099 | * the Host told us how big it is when we made LGUEST_INIT hypercall: | 1108 | * the Host told us how big it is when we made LGUEST_INIT hypercall: |
1100 | * it put the answer in lguest_data.reserve_mem */ | 1109 | * it put the answer in lguest_data.reserve_mem */ |
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 08186ecbaf8d..6b91c26a4635 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -220,6 +220,7 @@ enum { | |||
220 | AHCI_HFLAG_NO_HOTPLUG = (1 << 7), /* ignore PxSERR.DIAG.N */ | 220 | AHCI_HFLAG_NO_HOTPLUG = (1 << 7), /* ignore PxSERR.DIAG.N */ |
221 | AHCI_HFLAG_SECT255 = (1 << 8), /* max 255 sectors */ | 221 | AHCI_HFLAG_SECT255 = (1 << 8), /* max 255 sectors */ |
222 | AHCI_HFLAG_YES_NCQ = (1 << 9), /* force NCQ cap on */ | 222 | AHCI_HFLAG_YES_NCQ = (1 << 9), /* force NCQ cap on */ |
223 | AHCI_HFLAG_NO_SUSPEND = (1 << 10), /* don't suspend */ | ||
223 | 224 | ||
224 | /* ap->flags bits */ | 225 | /* ap->flags bits */ |
225 | 226 | ||
@@ -2316,9 +2317,17 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg) | |||
2316 | static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) | 2317 | static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) |
2317 | { | 2318 | { |
2318 | struct ata_host *host = dev_get_drvdata(&pdev->dev); | 2319 | struct ata_host *host = dev_get_drvdata(&pdev->dev); |
2320 | struct ahci_host_priv *hpriv = host->private_data; | ||
2319 | void __iomem *mmio = host->iomap[AHCI_PCI_BAR]; | 2321 | void __iomem *mmio = host->iomap[AHCI_PCI_BAR]; |
2320 | u32 ctl; | 2322 | u32 ctl; |
2321 | 2323 | ||
2324 | if (mesg.event & PM_EVENT_SUSPEND && | ||
2325 | hpriv->flags & AHCI_HFLAG_NO_SUSPEND) { | ||
2326 | dev_printk(KERN_ERR, &pdev->dev, | ||
2327 | "BIOS update required for suspend/resume\n"); | ||
2328 | return -EIO; | ||
2329 | } | ||
2330 | |||
2322 | if (mesg.event & PM_EVENT_SLEEP) { | 2331 | if (mesg.event & PM_EVENT_SLEEP) { |
2323 | /* AHCI spec rev1.1 section 8.3.3: | 2332 | /* AHCI spec rev1.1 section 8.3.3: |
2324 | * Software must disable interrupts prior to requesting a | 2333 | * Software must disable interrupts prior to requesting a |
@@ -2610,6 +2619,63 @@ static bool ahci_broken_system_poweroff(struct pci_dev *pdev) | |||
2610 | return false; | 2619 | return false; |
2611 | } | 2620 | } |
2612 | 2621 | ||
2622 | static bool ahci_broken_suspend(struct pci_dev *pdev) | ||
2623 | { | ||
2624 | static const struct dmi_system_id sysids[] = { | ||
2625 | /* | ||
2626 | * On HP dv[4-6] and HDX18 with earlier BIOSen, link | ||
2627 | * to the harddisk doesn't become online after | ||
2628 | * resuming from STR. Warn and fail suspend. | ||
2629 | */ | ||
2630 | { | ||
2631 | .ident = "dv4", | ||
2632 | .matches = { | ||
2633 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
2634 | DMI_MATCH(DMI_PRODUCT_NAME, | ||
2635 | "HP Pavilion dv4 Notebook PC"), | ||
2636 | }, | ||
2637 | .driver_data = "F.30", /* cutoff BIOS version */ | ||
2638 | }, | ||
2639 | { | ||
2640 | .ident = "dv5", | ||
2641 | .matches = { | ||
2642 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
2643 | DMI_MATCH(DMI_PRODUCT_NAME, | ||
2644 | "HP Pavilion dv5 Notebook PC"), | ||
2645 | }, | ||
2646 | .driver_data = "F.16", /* cutoff BIOS version */ | ||
2647 | }, | ||
2648 | { | ||
2649 | .ident = "dv6", | ||
2650 | .matches = { | ||
2651 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
2652 | DMI_MATCH(DMI_PRODUCT_NAME, | ||
2653 | "HP Pavilion dv6 Notebook PC"), | ||
2654 | }, | ||
2655 | .driver_data = "F.21", /* cutoff BIOS version */ | ||
2656 | }, | ||
2657 | { | ||
2658 | .ident = "HDX18", | ||
2659 | .matches = { | ||
2660 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
2661 | DMI_MATCH(DMI_PRODUCT_NAME, | ||
2662 | "HP HDX18 Notebook PC"), | ||
2663 | }, | ||
2664 | .driver_data = "F.23", /* cutoff BIOS version */ | ||
2665 | }, | ||
2666 | { } /* terminate list */ | ||
2667 | }; | ||
2668 | const struct dmi_system_id *dmi = dmi_first_match(sysids); | ||
2669 | const char *ver; | ||
2670 | |||
2671 | if (!dmi || pdev->bus->number || pdev->devfn != PCI_DEVFN(0x1f, 2)) | ||
2672 | return false; | ||
2673 | |||
2674 | ver = dmi_get_system_info(DMI_BIOS_VERSION); | ||
2675 | |||
2676 | return !ver || strcmp(ver, dmi->driver_data) < 0; | ||
2677 | } | ||
2678 | |||
2613 | static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 2679 | static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
2614 | { | 2680 | { |
2615 | static int printed_version; | 2681 | static int printed_version; |
@@ -2715,6 +2781,12 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2715 | "quirky BIOS, skipping spindown on poweroff\n"); | 2781 | "quirky BIOS, skipping spindown on poweroff\n"); |
2716 | } | 2782 | } |
2717 | 2783 | ||
2784 | if (ahci_broken_suspend(pdev)) { | ||
2785 | hpriv->flags |= AHCI_HFLAG_NO_SUSPEND; | ||
2786 | dev_printk(KERN_WARNING, &pdev->dev, | ||
2787 | "BIOS update required for suspend/resume\n"); | ||
2788 | } | ||
2789 | |||
2718 | /* CAP.NP sometimes indicate the index of the last enabled | 2790 | /* CAP.NP sometimes indicate the index of the last enabled |
2719 | * port, at other times, that of the last possible port, so | 2791 | * port, at other times, that of the last possible port, so |
2720 | * determining the maximum port number requires looking at | 2792 | * determining the maximum port number requires looking at |
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index d51a17c0f59b..1aeb7082b0c4 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c | |||
@@ -1455,6 +1455,15 @@ static bool piix_broken_system_poweroff(struct pci_dev *pdev) | |||
1455 | /* PCI slot number of the controller */ | 1455 | /* PCI slot number of the controller */ |
1456 | .driver_data = (void *)0x1FUL, | 1456 | .driver_data = (void *)0x1FUL, |
1457 | }, | 1457 | }, |
1458 | { | ||
1459 | .ident = "HP Compaq nc6000", | ||
1460 | .matches = { | ||
1461 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
1462 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nc6000"), | ||
1463 | }, | ||
1464 | /* PCI slot number of the controller */ | ||
1465 | .driver_data = (void *)0x1FUL, | ||
1466 | }, | ||
1458 | 1467 | ||
1459 | { } /* terminate list */ | 1468 | { } /* terminate list */ |
1460 | }; | 1469 | }; |
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c index 751b7ea4816c..fc9c5d6d7d80 100644 --- a/drivers/ata/pata_ali.c +++ b/drivers/ata/pata_ali.c | |||
@@ -497,14 +497,16 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
497 | }; | 497 | }; |
498 | /* Revision 0x20 added DMA */ | 498 | /* Revision 0x20 added DMA */ |
499 | static const struct ata_port_info info_20 = { | 499 | static const struct ata_port_info info_20 = { |
500 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, | 500 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48 | |
501 | ATA_FLAG_IGN_SIMPLEX, | ||
501 | .pio_mask = ATA_PIO4, | 502 | .pio_mask = ATA_PIO4, |
502 | .mwdma_mask = ATA_MWDMA2, | 503 | .mwdma_mask = ATA_MWDMA2, |
503 | .port_ops = &ali_20_port_ops | 504 | .port_ops = &ali_20_port_ops |
504 | }; | 505 | }; |
505 | /* Revision 0x20 with support logic added UDMA */ | 506 | /* Revision 0x20 with support logic added UDMA */ |
506 | static const struct ata_port_info info_20_udma = { | 507 | static const struct ata_port_info info_20_udma = { |
507 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, | 508 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48 | |
509 | ATA_FLAG_IGN_SIMPLEX, | ||
508 | .pio_mask = ATA_PIO4, | 510 | .pio_mask = ATA_PIO4, |
509 | .mwdma_mask = ATA_MWDMA2, | 511 | .mwdma_mask = ATA_MWDMA2, |
510 | .udma_mask = ATA_UDMA2, | 512 | .udma_mask = ATA_UDMA2, |
@@ -512,7 +514,8 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
512 | }; | 514 | }; |
513 | /* Revision 0xC2 adds UDMA66 */ | 515 | /* Revision 0xC2 adds UDMA66 */ |
514 | static const struct ata_port_info info_c2 = { | 516 | static const struct ata_port_info info_c2 = { |
515 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, | 517 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48 | |
518 | ATA_FLAG_IGN_SIMPLEX, | ||
516 | .pio_mask = ATA_PIO4, | 519 | .pio_mask = ATA_PIO4, |
517 | .mwdma_mask = ATA_MWDMA2, | 520 | .mwdma_mask = ATA_MWDMA2, |
518 | .udma_mask = ATA_UDMA4, | 521 | .udma_mask = ATA_UDMA4, |
@@ -520,7 +523,8 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
520 | }; | 523 | }; |
521 | /* Revision 0xC3 is UDMA66 for now */ | 524 | /* Revision 0xC3 is UDMA66 for now */ |
522 | static const struct ata_port_info info_c3 = { | 525 | static const struct ata_port_info info_c3 = { |
523 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, | 526 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48 | |
527 | ATA_FLAG_IGN_SIMPLEX, | ||
524 | .pio_mask = ATA_PIO4, | 528 | .pio_mask = ATA_PIO4, |
525 | .mwdma_mask = ATA_MWDMA2, | 529 | .mwdma_mask = ATA_MWDMA2, |
526 | .udma_mask = ATA_UDMA4, | 530 | .udma_mask = ATA_UDMA4, |
@@ -528,7 +532,8 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
528 | }; | 532 | }; |
529 | /* Revision 0xC4 is UDMA100 */ | 533 | /* Revision 0xC4 is UDMA100 */ |
530 | static const struct ata_port_info info_c4 = { | 534 | static const struct ata_port_info info_c4 = { |
531 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, | 535 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48 | |
536 | ATA_FLAG_IGN_SIMPLEX, | ||
532 | .pio_mask = ATA_PIO4, | 537 | .pio_mask = ATA_PIO4, |
533 | .mwdma_mask = ATA_MWDMA2, | 538 | .mwdma_mask = ATA_MWDMA2, |
534 | .udma_mask = ATA_UDMA5, | 539 | .udma_mask = ATA_UDMA5, |
@@ -536,7 +541,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
536 | }; | 541 | }; |
537 | /* Revision 0xC5 is UDMA133 with LBA48 DMA */ | 542 | /* Revision 0xC5 is UDMA133 with LBA48 DMA */ |
538 | static const struct ata_port_info info_c5 = { | 543 | static const struct ata_port_info info_c5 = { |
539 | .flags = ATA_FLAG_SLAVE_POSS, | 544 | .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_IGN_SIMPLEX, |
540 | .pio_mask = ATA_PIO4, | 545 | .pio_mask = ATA_PIO4, |
541 | .mwdma_mask = ATA_MWDMA2, | 546 | .mwdma_mask = ATA_MWDMA2, |
542 | .udma_mask = ATA_UDMA6, | 547 | .udma_mask = ATA_UDMA6, |
diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c index 2085e0a3a05a..2a6412f5d117 100644 --- a/drivers/ata/pata_efar.c +++ b/drivers/ata/pata_efar.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <linux/ata.h> | 22 | #include <linux/ata.h> |
23 | 23 | ||
24 | #define DRV_NAME "pata_efar" | 24 | #define DRV_NAME "pata_efar" |
25 | #define DRV_VERSION "0.4.4" | 25 | #define DRV_VERSION "0.4.5" |
26 | 26 | ||
27 | /** | 27 | /** |
28 | * efar_pre_reset - Enable bits | 28 | * efar_pre_reset - Enable bits |
@@ -98,18 +98,17 @@ static void efar_set_piomode (struct ata_port *ap, struct ata_device *adev) | |||
98 | { 2, 1 }, | 98 | { 2, 1 }, |
99 | { 2, 3 }, }; | 99 | { 2, 3 }, }; |
100 | 100 | ||
101 | if (pio > 2) | 101 | if (pio > 1) |
102 | control |= 1; /* TIME1 enable */ | 102 | control |= 1; /* TIME */ |
103 | if (ata_pio_need_iordy(adev)) /* PIO 3/4 require IORDY */ | 103 | if (ata_pio_need_iordy(adev)) /* PIO 3/4 require IORDY */ |
104 | control |= 2; /* IE enable */ | 104 | control |= 2; /* IE */ |
105 | /* Intel specifies that the PPE functionality is for disk only */ | 105 | /* Intel specifies that the prefetch/posting is for disk only */ |
106 | if (adev->class == ATA_DEV_ATA) | 106 | if (adev->class == ATA_DEV_ATA) |
107 | control |= 4; /* PPE enable */ | 107 | control |= 4; /* PPE */ |
108 | 108 | ||
109 | pci_read_config_word(dev, idetm_port, &idetm_data); | 109 | pci_read_config_word(dev, idetm_port, &idetm_data); |
110 | 110 | ||
111 | /* Enable PPE, IE and TIME as appropriate */ | 111 | /* Set PPE, IE, and TIME as appropriate */ |
112 | |||
113 | if (adev->devno == 0) { | 112 | if (adev->devno == 0) { |
114 | idetm_data &= 0xCCF0; | 113 | idetm_data &= 0xCCF0; |
115 | idetm_data |= control; | 114 | idetm_data |= control; |
@@ -129,7 +128,7 @@ static void efar_set_piomode (struct ata_port *ap, struct ata_device *adev) | |||
129 | pci_write_config_byte(dev, 0x44, slave_data); | 128 | pci_write_config_byte(dev, 0x44, slave_data); |
130 | } | 129 | } |
131 | 130 | ||
132 | idetm_data |= 0x4000; /* Ensure SITRE is enabled */ | 131 | idetm_data |= 0x4000; /* Ensure SITRE is set */ |
133 | pci_write_config_word(dev, idetm_port, idetm_data); | 132 | pci_write_config_word(dev, idetm_port, idetm_data); |
134 | } | 133 | } |
135 | 134 | ||
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index f72c6c5b820f..6932e56d179c 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c | |||
@@ -48,6 +48,7 @@ | |||
48 | * | 48 | * |
49 | */ | 49 | */ |
50 | 50 | ||
51 | #include <linux/async.h> | ||
51 | #include <linux/kernel.h> | 52 | #include <linux/kernel.h> |
52 | #include <linux/module.h> | 53 | #include <linux/module.h> |
53 | #include <linux/pci.h> | 54 | #include <linux/pci.h> |
@@ -1028,6 +1029,7 @@ static __init int legacy_init_one(struct legacy_probe *probe) | |||
1028 | &legacy_sht); | 1029 | &legacy_sht); |
1029 | if (ret) | 1030 | if (ret) |
1030 | goto fail; | 1031 | goto fail; |
1032 | async_synchronize_full(); | ||
1031 | ld->platform_dev = pdev; | 1033 | ld->platform_dev = pdev; |
1032 | 1034 | ||
1033 | /* Nothing found means we drop the port as its probably not there */ | 1035 | /* Nothing found means we drop the port as its probably not there */ |
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 8f05c38c2f06..65e12bca657c 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c | |||
@@ -694,6 +694,9 @@ static ssize_t read_zero(struct file * file, char __user * buf, | |||
694 | written += chunk - unwritten; | 694 | written += chunk - unwritten; |
695 | if (unwritten) | 695 | if (unwritten) |
696 | break; | 696 | break; |
697 | /* Consider changing this to just 'signal_pending()' with lots of testing */ | ||
698 | if (fatal_signal_pending(current)) | ||
699 | return written ? written : -EINTR; | ||
697 | buf += chunk; | 700 | buf += chunk; |
698 | count -= chunk; | 701 | count -= chunk; |
699 | cond_resched(); | 702 | cond_resched(); |
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 94a768871734..8fab7890a363 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -2294,7 +2294,12 @@ int drm_mode_connector_property_set_ioctl(struct drm_device *dev, | |||
2294 | } | 2294 | } |
2295 | } | 2295 | } |
2296 | 2296 | ||
2297 | if (connector->funcs->set_property) | 2297 | /* Do DPMS ourselves */ |
2298 | if (property == connector->dev->mode_config.dpms_property) { | ||
2299 | if (connector->funcs->dpms) | ||
2300 | (*connector->funcs->dpms)(connector, (int) out_resp->value); | ||
2301 | ret = 0; | ||
2302 | } else if (connector->funcs->set_property) | ||
2298 | ret = connector->funcs->set_property(connector, property, out_resp->value); | 2303 | ret = connector->funcs->set_property(connector, property, out_resp->value); |
2299 | 2304 | ||
2300 | /* store the property value if succesful */ | 2305 | /* store the property value if succesful */ |
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 45890447feec..a6f73f1e99d9 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
@@ -199,6 +199,29 @@ static void drm_helper_add_std_modes(struct drm_device *dev, | |||
199 | } | 199 | } |
200 | 200 | ||
201 | /** | 201 | /** |
202 | * drm_helper_encoder_in_use - check if a given encoder is in use | ||
203 | * @encoder: encoder to check | ||
204 | * | ||
205 | * LOCKING: | ||
206 | * Caller must hold mode config lock. | ||
207 | * | ||
208 | * Walk @encoders's DRM device's mode_config and see if it's in use. | ||
209 | * | ||
210 | * RETURNS: | ||
211 | * True if @encoder is part of the mode_config, false otherwise. | ||
212 | */ | ||
213 | bool drm_helper_encoder_in_use(struct drm_encoder *encoder) | ||
214 | { | ||
215 | struct drm_connector *connector; | ||
216 | struct drm_device *dev = encoder->dev; | ||
217 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) | ||
218 | if (connector->encoder == encoder) | ||
219 | return true; | ||
220 | return false; | ||
221 | } | ||
222 | EXPORT_SYMBOL(drm_helper_encoder_in_use); | ||
223 | |||
224 | /** | ||
202 | * drm_helper_crtc_in_use - check if a given CRTC is in a mode_config | 225 | * drm_helper_crtc_in_use - check if a given CRTC is in a mode_config |
203 | * @crtc: CRTC to check | 226 | * @crtc: CRTC to check |
204 | * | 227 | * |
@@ -216,7 +239,7 @@ bool drm_helper_crtc_in_use(struct drm_crtc *crtc) | |||
216 | struct drm_device *dev = crtc->dev; | 239 | struct drm_device *dev = crtc->dev; |
217 | /* FIXME: Locking around list access? */ | 240 | /* FIXME: Locking around list access? */ |
218 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) | 241 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) |
219 | if (encoder->crtc == crtc) | 242 | if (encoder->crtc == crtc && drm_helper_encoder_in_use(encoder)) |
220 | return true; | 243 | return true; |
221 | return false; | 244 | return false; |
222 | } | 245 | } |
@@ -240,7 +263,7 @@ void drm_helper_disable_unused_functions(struct drm_device *dev) | |||
240 | 263 | ||
241 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 264 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
242 | encoder_funcs = encoder->helper_private; | 265 | encoder_funcs = encoder->helper_private; |
243 | if (!encoder->crtc) | 266 | if (!drm_helper_encoder_in_use(encoder)) |
244 | (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); | 267 | (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); |
245 | } | 268 | } |
246 | 269 | ||
@@ -935,6 +958,88 @@ bool drm_helper_initial_config(struct drm_device *dev) | |||
935 | } | 958 | } |
936 | EXPORT_SYMBOL(drm_helper_initial_config); | 959 | EXPORT_SYMBOL(drm_helper_initial_config); |
937 | 960 | ||
961 | static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder) | ||
962 | { | ||
963 | int dpms = DRM_MODE_DPMS_OFF; | ||
964 | struct drm_connector *connector; | ||
965 | struct drm_device *dev = encoder->dev; | ||
966 | |||
967 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) | ||
968 | if (connector->encoder == encoder) | ||
969 | if (connector->dpms < dpms) | ||
970 | dpms = connector->dpms; | ||
971 | return dpms; | ||
972 | } | ||
973 | |||
974 | static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc) | ||
975 | { | ||
976 | int dpms = DRM_MODE_DPMS_OFF; | ||
977 | struct drm_connector *connector; | ||
978 | struct drm_device *dev = crtc->dev; | ||
979 | |||
980 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) | ||
981 | if (connector->encoder && connector->encoder->crtc == crtc) | ||
982 | if (connector->dpms < dpms) | ||
983 | dpms = connector->dpms; | ||
984 | return dpms; | ||
985 | } | ||
986 | |||
987 | /** | ||
988 | * drm_helper_connector_dpms | ||
989 | * @connector affected connector | ||
990 | * @mode DPMS mode | ||
991 | * | ||
992 | * Calls the low-level connector DPMS function, then | ||
993 | * calls appropriate encoder and crtc DPMS functions as well | ||
994 | */ | ||
995 | void drm_helper_connector_dpms(struct drm_connector *connector, int mode) | ||
996 | { | ||
997 | struct drm_encoder *encoder = connector->encoder; | ||
998 | struct drm_crtc *crtc = encoder ? encoder->crtc : NULL; | ||
999 | int old_dpms; | ||
1000 | |||
1001 | if (mode == connector->dpms) | ||
1002 | return; | ||
1003 | |||
1004 | old_dpms = connector->dpms; | ||
1005 | connector->dpms = mode; | ||
1006 | |||
1007 | /* from off to on, do crtc then encoder */ | ||
1008 | if (mode < old_dpms) { | ||
1009 | if (crtc) { | ||
1010 | struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; | ||
1011 | if (crtc_funcs->dpms) | ||
1012 | (*crtc_funcs->dpms) (crtc, | ||
1013 | drm_helper_choose_crtc_dpms(crtc)); | ||
1014 | } | ||
1015 | if (encoder) { | ||
1016 | struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; | ||
1017 | if (encoder_funcs->dpms) | ||
1018 | (*encoder_funcs->dpms) (encoder, | ||
1019 | drm_helper_choose_encoder_dpms(encoder)); | ||
1020 | } | ||
1021 | } | ||
1022 | |||
1023 | /* from on to off, do encoder then crtc */ | ||
1024 | if (mode > old_dpms) { | ||
1025 | if (encoder) { | ||
1026 | struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; | ||
1027 | if (encoder_funcs->dpms) | ||
1028 | (*encoder_funcs->dpms) (encoder, | ||
1029 | drm_helper_choose_encoder_dpms(encoder)); | ||
1030 | } | ||
1031 | if (crtc) { | ||
1032 | struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; | ||
1033 | if (crtc_funcs->dpms) | ||
1034 | (*crtc_funcs->dpms) (crtc, | ||
1035 | drm_helper_choose_crtc_dpms(crtc)); | ||
1036 | } | ||
1037 | } | ||
1038 | |||
1039 | return; | ||
1040 | } | ||
1041 | EXPORT_SYMBOL(drm_helper_connector_dpms); | ||
1042 | |||
938 | /** | 1043 | /** |
939 | * drm_hotplug_stage_two | 1044 | * drm_hotplug_stage_two |
940 | * @dev DRM device | 1045 | * @dev DRM device |
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index ca9c61656714..6f6b26479d82 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -289,6 +289,11 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, | |||
289 | struct drm_display_mode *mode; | 289 | struct drm_display_mode *mode; |
290 | struct detailed_pixel_timing *pt = &timing->data.pixel_data; | 290 | struct detailed_pixel_timing *pt = &timing->data.pixel_data; |
291 | 291 | ||
292 | /* ignore tiny modes */ | ||
293 | if (((pt->hactive_hi << 8) | pt->hactive_lo) < 64 || | ||
294 | ((pt->vactive_hi << 8) | pt->hactive_lo) < 64) | ||
295 | return NULL; | ||
296 | |||
292 | if (pt->stereo) { | 297 | if (pt->stereo) { |
293 | printk(KERN_WARNING "stereo mode not supported\n"); | 298 | printk(KERN_WARNING "stereo mode not supported\n"); |
294 | return NULL; | 299 | return NULL; |
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 93e677a481f5..fc8e5acd9d9a 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
@@ -196,6 +196,7 @@ int drm_irq_install(struct drm_device *dev) | |||
196 | { | 196 | { |
197 | int ret = 0; | 197 | int ret = 0; |
198 | unsigned long sh_flags = 0; | 198 | unsigned long sh_flags = 0; |
199 | char *irqname; | ||
199 | 200 | ||
200 | if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) | 201 | if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) |
201 | return -EINVAL; | 202 | return -EINVAL; |
@@ -227,8 +228,13 @@ int drm_irq_install(struct drm_device *dev) | |||
227 | if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED)) | 228 | if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED)) |
228 | sh_flags = IRQF_SHARED; | 229 | sh_flags = IRQF_SHARED; |
229 | 230 | ||
231 | if (dev->devname) | ||
232 | irqname = dev->devname; | ||
233 | else | ||
234 | irqname = dev->driver->name; | ||
235 | |||
230 | ret = request_irq(drm_dev_to_irq(dev), dev->driver->irq_handler, | 236 | ret = request_irq(drm_dev_to_irq(dev), dev->driver->irq_handler, |
231 | sh_flags, dev->devname, dev); | 237 | sh_flags, irqname, dev); |
232 | 238 | ||
233 | if (ret < 0) { | 239 | if (ret < 0) { |
234 | mutex_lock(&dev->struct_mutex); | 240 | mutex_lock(&dev->struct_mutex); |
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 8f9372921f82..9987ab880835 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c | |||
@@ -147,7 +147,7 @@ static ssize_t status_show(struct device *device, | |||
147 | enum drm_connector_status status; | 147 | enum drm_connector_status status; |
148 | 148 | ||
149 | status = connector->funcs->detect(connector); | 149 | status = connector->funcs->detect(connector); |
150 | return snprintf(buf, PAGE_SIZE, "%s", | 150 | return snprintf(buf, PAGE_SIZE, "%s\n", |
151 | drm_get_connector_status_name(status)); | 151 | drm_get_connector_status_name(status)); |
152 | } | 152 | } |
153 | 153 | ||
@@ -166,7 +166,7 @@ static ssize_t dpms_show(struct device *device, | |||
166 | if (ret) | 166 | if (ret) |
167 | return 0; | 167 | return 0; |
168 | 168 | ||
169 | return snprintf(buf, PAGE_SIZE, "%s", | 169 | return snprintf(buf, PAGE_SIZE, "%s\n", |
170 | drm_get_dpms_name((int)dpms_status)); | 170 | drm_get_dpms_name((int)dpms_status)); |
171 | } | 171 | } |
172 | 172 | ||
@@ -176,7 +176,7 @@ static ssize_t enabled_show(struct device *device, | |||
176 | { | 176 | { |
177 | struct drm_connector *connector = to_drm_connector(device); | 177 | struct drm_connector *connector = to_drm_connector(device); |
178 | 178 | ||
179 | return snprintf(buf, PAGE_SIZE, connector->encoder ? "enabled" : | 179 | return snprintf(buf, PAGE_SIZE, "%s\n", connector->encoder ? "enabled" : |
180 | "disabled"); | 180 | "disabled"); |
181 | } | 181 | } |
182 | 182 | ||
@@ -317,6 +317,7 @@ static struct device_attribute connector_attrs_opt1[] = { | |||
317 | 317 | ||
318 | static struct bin_attribute edid_attr = { | 318 | static struct bin_attribute edid_attr = { |
319 | .attr.name = "edid", | 319 | .attr.name = "edid", |
320 | .attr.mode = 0444, | ||
320 | .size = 128, | 321 | .size = 128, |
321 | .read = edid_show, | 322 | .read = edid_show, |
322 | }; | 323 | }; |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 53d544552625..0ccb63ee50ee 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -987,12 +987,6 @@ static int i915_load_modeset_init(struct drm_device *dev) | |||
987 | int fb_bar = IS_I9XX(dev) ? 2 : 0; | 987 | int fb_bar = IS_I9XX(dev) ? 2 : 0; |
988 | int ret = 0; | 988 | int ret = 0; |
989 | 989 | ||
990 | dev->devname = kstrdup(DRIVER_NAME, GFP_KERNEL); | ||
991 | if (!dev->devname) { | ||
992 | ret = -ENOMEM; | ||
993 | goto out; | ||
994 | } | ||
995 | |||
996 | dev->mode_config.fb_base = drm_get_resource_start(dev, fb_bar) & | 990 | dev->mode_config.fb_base = drm_get_resource_start(dev, fb_bar) & |
997 | 0xff000000; | 991 | 0xff000000; |
998 | 992 | ||
@@ -1006,7 +1000,7 @@ static int i915_load_modeset_init(struct drm_device *dev) | |||
1006 | 1000 | ||
1007 | ret = i915_probe_agp(dev, &agp_size, &prealloc_size); | 1001 | ret = i915_probe_agp(dev, &agp_size, &prealloc_size); |
1008 | if (ret) | 1002 | if (ret) |
1009 | goto kfree_devname; | 1003 | goto out; |
1010 | 1004 | ||
1011 | /* Basic memrange allocator for stolen space (aka vram) */ | 1005 | /* Basic memrange allocator for stolen space (aka vram) */ |
1012 | drm_mm_init(&dev_priv->vram, 0, prealloc_size); | 1006 | drm_mm_init(&dev_priv->vram, 0, prealloc_size); |
@@ -1024,7 +1018,7 @@ static int i915_load_modeset_init(struct drm_device *dev) | |||
1024 | 1018 | ||
1025 | ret = i915_gem_init_ringbuffer(dev); | 1019 | ret = i915_gem_init_ringbuffer(dev); |
1026 | if (ret) | 1020 | if (ret) |
1027 | goto kfree_devname; | 1021 | goto out; |
1028 | 1022 | ||
1029 | /* Allow hardware batchbuffers unless told otherwise. | 1023 | /* Allow hardware batchbuffers unless told otherwise. |
1030 | */ | 1024 | */ |
@@ -1056,8 +1050,6 @@ static int i915_load_modeset_init(struct drm_device *dev) | |||
1056 | 1050 | ||
1057 | destroy_ringbuffer: | 1051 | destroy_ringbuffer: |
1058 | i915_gem_cleanup_ringbuffer(dev); | 1052 | i915_gem_cleanup_ringbuffer(dev); |
1059 | kfree_devname: | ||
1060 | kfree(dev->devname); | ||
1061 | out: | 1053 | out: |
1062 | return ret; | 1054 | return ret; |
1063 | } | 1055 | } |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 670d12881468..39f5c658ef5e 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -2260,9 +2260,6 @@ try_again: | |||
2260 | goto try_again; | 2260 | goto try_again; |
2261 | } | 2261 | } |
2262 | 2262 | ||
2263 | BUG_ON(old_obj_priv->active || | ||
2264 | (reg->obj->write_domain & I915_GEM_GPU_DOMAINS)); | ||
2265 | |||
2266 | /* | 2263 | /* |
2267 | * Zap this virtual mapping so we can set up a fence again | 2264 | * Zap this virtual mapping so we can set up a fence again |
2268 | * for this object next time we need it. | 2265 | * for this object next time we need it. |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 640f5158effc..79acc4f4c1f8 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -381,11 +381,6 @@ static int intel_crt_set_property(struct drm_connector *connector, | |||
381 | struct drm_property *property, | 381 | struct drm_property *property, |
382 | uint64_t value) | 382 | uint64_t value) |
383 | { | 383 | { |
384 | struct drm_device *dev = connector->dev; | ||
385 | |||
386 | if (property == dev->mode_config.dpms_property && connector->encoder) | ||
387 | intel_crt_dpms(connector->encoder, (uint32_t)(value & 0xf)); | ||
388 | |||
389 | return 0; | 384 | return 0; |
390 | } | 385 | } |
391 | 386 | ||
@@ -402,6 +397,7 @@ static const struct drm_encoder_helper_funcs intel_crt_helper_funcs = { | |||
402 | }; | 397 | }; |
403 | 398 | ||
404 | static const struct drm_connector_funcs intel_crt_connector_funcs = { | 399 | static const struct drm_connector_funcs intel_crt_connector_funcs = { |
400 | .dpms = drm_helper_connector_dpms, | ||
405 | .detect = intel_crt_detect, | 401 | .detect = intel_crt_detect, |
406 | .fill_modes = drm_helper_probe_single_connector_modes, | 402 | .fill_modes = drm_helper_probe_single_connector_modes, |
407 | .destroy = intel_crt_destroy, | 403 | .destroy = intel_crt_destroy, |
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 8b8d6e65cd3f..1ee3007d6ec0 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c | |||
@@ -316,6 +316,7 @@ static const struct drm_encoder_helper_funcs intel_dvo_helper_funcs = { | |||
316 | }; | 316 | }; |
317 | 317 | ||
318 | static const struct drm_connector_funcs intel_dvo_connector_funcs = { | 318 | static const struct drm_connector_funcs intel_dvo_connector_funcs = { |
319 | .dpms = drm_helper_connector_dpms, | ||
319 | .save = intel_dvo_save, | 320 | .save = intel_dvo_save, |
320 | .restore = intel_dvo_restore, | 321 | .restore = intel_dvo_restore, |
321 | .detect = intel_dvo_detect, | 322 | .detect = intel_dvo_detect, |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index d0983bb93a18..7d6bdd705326 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -219,6 +219,7 @@ static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = { | |||
219 | }; | 219 | }; |
220 | 220 | ||
221 | static const struct drm_connector_funcs intel_hdmi_connector_funcs = { | 221 | static const struct drm_connector_funcs intel_hdmi_connector_funcs = { |
222 | .dpms = drm_helper_connector_dpms, | ||
222 | .save = intel_hdmi_save, | 223 | .save = intel_hdmi_save, |
223 | .restore = intel_hdmi_restore, | 224 | .restore = intel_hdmi_restore, |
224 | .detect = intel_hdmi_detect, | 225 | .detect = intel_hdmi_detect, |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 53731f0ffcb5..53cccfa58b95 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -343,11 +343,6 @@ static int intel_lvds_set_property(struct drm_connector *connector, | |||
343 | struct drm_property *property, | 343 | struct drm_property *property, |
344 | uint64_t value) | 344 | uint64_t value) |
345 | { | 345 | { |
346 | struct drm_device *dev = connector->dev; | ||
347 | |||
348 | if (property == dev->mode_config.dpms_property && connector->encoder) | ||
349 | intel_lvds_dpms(connector->encoder, (uint32_t)(value & 0xf)); | ||
350 | |||
351 | return 0; | 346 | return 0; |
352 | } | 347 | } |
353 | 348 | ||
@@ -366,6 +361,7 @@ static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs | |||
366 | }; | 361 | }; |
367 | 362 | ||
368 | static const struct drm_connector_funcs intel_lvds_connector_funcs = { | 363 | static const struct drm_connector_funcs intel_lvds_connector_funcs = { |
364 | .dpms = drm_helper_connector_dpms, | ||
369 | .save = intel_lvds_save, | 365 | .save = intel_lvds_save, |
370 | .restore = intel_lvds_restore, | 366 | .restore = intel_lvds_restore, |
371 | .detect = intel_lvds_detect, | 367 | .detect = intel_lvds_detect, |
@@ -391,7 +387,7 @@ static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id) | |||
391 | } | 387 | } |
392 | 388 | ||
393 | /* These systems claim to have LVDS, but really don't */ | 389 | /* These systems claim to have LVDS, but really don't */ |
394 | static const struct dmi_system_id __initdata intel_no_lvds[] = { | 390 | static const struct dmi_system_id intel_no_lvds[] = { |
395 | { | 391 | { |
396 | .callback = intel_no_lvds_dmi_callback, | 392 | .callback = intel_no_lvds_dmi_callback, |
397 | .ident = "Apple Mac Mini (Core series)", | 393 | .ident = "Apple Mac Mini (Core series)", |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index f3ef6bfd8ffc..3093b4d4a4dd 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -1616,6 +1616,7 @@ static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = { | |||
1616 | }; | 1616 | }; |
1617 | 1617 | ||
1618 | static const struct drm_connector_funcs intel_sdvo_connector_funcs = { | 1618 | static const struct drm_connector_funcs intel_sdvo_connector_funcs = { |
1619 | .dpms = drm_helper_connector_dpms, | ||
1619 | .save = intel_sdvo_save, | 1620 | .save = intel_sdvo_save, |
1620 | .restore = intel_sdvo_restore, | 1621 | .restore = intel_sdvo_restore, |
1621 | .detect = intel_sdvo_detect, | 1622 | .detect = intel_sdvo_detect, |
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index d2c32983242d..98ac0546b7bd 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
@@ -1626,6 +1626,7 @@ static const struct drm_encoder_helper_funcs intel_tv_helper_funcs = { | |||
1626 | }; | 1626 | }; |
1627 | 1627 | ||
1628 | static const struct drm_connector_funcs intel_tv_connector_funcs = { | 1628 | static const struct drm_connector_funcs intel_tv_connector_funcs = { |
1629 | .dpms = drm_helper_connector_dpms, | ||
1629 | .save = intel_tv_save, | 1630 | .save = intel_tv_save, |
1630 | .restore = intel_tv_restore, | 1631 | .restore = intel_tv_restore, |
1631 | .detect = intel_tv_detect, | 1632 | .detect = intel_tv_detect, |
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c index 77a7a4d84650..aff90bb96488 100644 --- a/drivers/gpu/drm/radeon/radeon_cp.c +++ b/drivers/gpu/drm/radeon/radeon_cp.c | |||
@@ -2185,9 +2185,9 @@ void radeon_commit_ring(drm_radeon_private_t *dev_priv) | |||
2185 | 2185 | ||
2186 | /* check if the ring is padded out to 16-dword alignment */ | 2186 | /* check if the ring is padded out to 16-dword alignment */ |
2187 | 2187 | ||
2188 | tail_aligned = dev_priv->ring.tail & 0xf; | 2188 | tail_aligned = dev_priv->ring.tail & (RADEON_RING_ALIGN-1); |
2189 | if (tail_aligned) { | 2189 | if (tail_aligned) { |
2190 | int num_p2 = 16 - tail_aligned; | 2190 | int num_p2 = RADEON_RING_ALIGN - tail_aligned; |
2191 | 2191 | ||
2192 | ring = dev_priv->ring.start; | 2192 | ring = dev_priv->ring.start; |
2193 | /* pad with some CP_PACKET2 */ | 2193 | /* pad with some CP_PACKET2 */ |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h index 8071d965f142..0c6bfc1de153 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.h +++ b/drivers/gpu/drm/radeon/radeon_drv.h | |||
@@ -1964,11 +1964,14 @@ do { \ | |||
1964 | 1964 | ||
1965 | #define RING_LOCALS int write, _nr, _align_nr; unsigned int mask; u32 *ring; | 1965 | #define RING_LOCALS int write, _nr, _align_nr; unsigned int mask; u32 *ring; |
1966 | 1966 | ||
1967 | #define RADEON_RING_ALIGN 16 | ||
1968 | |||
1967 | #define BEGIN_RING( n ) do { \ | 1969 | #define BEGIN_RING( n ) do { \ |
1968 | if ( RADEON_VERBOSE ) { \ | 1970 | if ( RADEON_VERBOSE ) { \ |
1969 | DRM_INFO( "BEGIN_RING( %d )\n", (n)); \ | 1971 | DRM_INFO( "BEGIN_RING( %d )\n", (n)); \ |
1970 | } \ | 1972 | } \ |
1971 | _align_nr = (n + 0xf) & ~0xf; \ | 1973 | _align_nr = RADEON_RING_ALIGN - ((dev_priv->ring.tail + n) & (RADEON_RING_ALIGN-1)); \ |
1974 | _align_nr += n; \ | ||
1972 | if (dev_priv->ring.space <= (_align_nr * sizeof(u32))) { \ | 1975 | if (dev_priv->ring.space <= (_align_nr * sizeof(u32))) { \ |
1973 | COMMIT_RING(); \ | 1976 | COMMIT_RING(); \ |
1974 | radeon_wait_ring( dev_priv, _align_nr * sizeof(u32)); \ | 1977 | radeon_wait_ring( dev_priv, _align_nr * sizeof(u32)); \ |
diff --git a/drivers/media/video/ivtv/ivtv-queue.c b/drivers/media/video/ivtv/ivtv-queue.c index ff7b7deded4f..7fde36e6d227 100644 --- a/drivers/media/video/ivtv/ivtv-queue.c +++ b/drivers/media/video/ivtv/ivtv-queue.c | |||
@@ -230,7 +230,8 @@ int ivtv_stream_alloc(struct ivtv_stream *s) | |||
230 | return -ENOMEM; | 230 | return -ENOMEM; |
231 | } | 231 | } |
232 | if (ivtv_might_use_dma(s)) { | 232 | if (ivtv_might_use_dma(s)) { |
233 | s->sg_handle = pci_map_single(itv->pdev, s->sg_dma, sizeof(struct ivtv_sg_element), s->dma); | 233 | s->sg_handle = pci_map_single(itv->pdev, s->sg_dma, |
234 | sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE); | ||
234 | ivtv_stream_sync_for_cpu(s); | 235 | ivtv_stream_sync_for_cpu(s); |
235 | } | 236 | } |
236 | 237 | ||
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index 0119220de7d0..02700f769b8a 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c | |||
@@ -407,16 +407,17 @@ static int __init nand_davinci_probe(struct platform_device *pdev) | |||
407 | } | 407 | } |
408 | info->chip.ecc.mode = ecc_mode; | 408 | info->chip.ecc.mode = ecc_mode; |
409 | 409 | ||
410 | info->clk = clk_get(&pdev->dev, "AEMIFCLK"); | 410 | info->clk = clk_get(&pdev->dev, "aemif"); |
411 | if (IS_ERR(info->clk)) { | 411 | if (IS_ERR(info->clk)) { |
412 | ret = PTR_ERR(info->clk); | 412 | ret = PTR_ERR(info->clk); |
413 | dev_dbg(&pdev->dev, "unable to get AEMIFCLK, err %d\n", ret); | 413 | dev_dbg(&pdev->dev, "unable to get AEMIF clock, err %d\n", ret); |
414 | goto err_clk; | 414 | goto err_clk; |
415 | } | 415 | } |
416 | 416 | ||
417 | ret = clk_enable(info->clk); | 417 | ret = clk_enable(info->clk); |
418 | if (ret < 0) { | 418 | if (ret < 0) { |
419 | dev_dbg(&pdev->dev, "unable to enable AEMIFCLK, err %d\n", ret); | 419 | dev_dbg(&pdev->dev, "unable to enable AEMIF clock, err %d\n", |
420 | ret); | ||
420 | goto err_clk_enable; | 421 | goto err_clk_enable; |
421 | } | 422 | } |
422 | 423 | ||
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 3e2c7c738f23..35af93355063 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -2622,7 +2622,18 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, | |||
2622 | search_start); | 2622 | search_start); |
2623 | if (block_group && block_group_bits(block_group, data)) { | 2623 | if (block_group && block_group_bits(block_group, data)) { |
2624 | down_read(&space_info->groups_sem); | 2624 | down_read(&space_info->groups_sem); |
2625 | goto have_block_group; | 2625 | if (list_empty(&block_group->list) || |
2626 | block_group->ro) { | ||
2627 | /* | ||
2628 | * someone is removing this block group, | ||
2629 | * we can't jump into the have_block_group | ||
2630 | * target because our list pointers are not | ||
2631 | * valid | ||
2632 | */ | ||
2633 | btrfs_put_block_group(block_group); | ||
2634 | up_read(&space_info->groups_sem); | ||
2635 | } else | ||
2636 | goto have_block_group; | ||
2626 | } else if (block_group) { | 2637 | } else if (block_group) { |
2627 | btrfs_put_block_group(block_group); | 2638 | btrfs_put_block_group(block_group); |
2628 | } | 2639 | } |
@@ -2656,6 +2667,13 @@ have_block_group: | |||
2656 | * people trying to start a new cluster | 2667 | * people trying to start a new cluster |
2657 | */ | 2668 | */ |
2658 | spin_lock(&last_ptr->refill_lock); | 2669 | spin_lock(&last_ptr->refill_lock); |
2670 | if (last_ptr->block_group && | ||
2671 | (last_ptr->block_group->ro || | ||
2672 | !block_group_bits(last_ptr->block_group, data))) { | ||
2673 | offset = 0; | ||
2674 | goto refill_cluster; | ||
2675 | } | ||
2676 | |||
2659 | offset = btrfs_alloc_from_cluster(block_group, last_ptr, | 2677 | offset = btrfs_alloc_from_cluster(block_group, last_ptr, |
2660 | num_bytes, search_start); | 2678 | num_bytes, search_start); |
2661 | if (offset) { | 2679 | if (offset) { |
@@ -2681,10 +2699,17 @@ have_block_group: | |||
2681 | 2699 | ||
2682 | last_ptr_loop = 1; | 2700 | last_ptr_loop = 1; |
2683 | search_start = block_group->key.objectid; | 2701 | search_start = block_group->key.objectid; |
2702 | /* | ||
2703 | * we know this block group is properly | ||
2704 | * in the list because | ||
2705 | * btrfs_remove_block_group, drops the | ||
2706 | * cluster before it removes the block | ||
2707 | * group from the list | ||
2708 | */ | ||
2684 | goto have_block_group; | 2709 | goto have_block_group; |
2685 | } | 2710 | } |
2686 | spin_unlock(&last_ptr->lock); | 2711 | spin_unlock(&last_ptr->lock); |
2687 | 2712 | refill_cluster: | |
2688 | /* | 2713 | /* |
2689 | * this cluster didn't work out, free it and | 2714 | * this cluster didn't work out, free it and |
2690 | * start over | 2715 | * start over |
@@ -5968,6 +5993,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, | |||
5968 | { | 5993 | { |
5969 | struct btrfs_path *path; | 5994 | struct btrfs_path *path; |
5970 | struct btrfs_block_group_cache *block_group; | 5995 | struct btrfs_block_group_cache *block_group; |
5996 | struct btrfs_free_cluster *cluster; | ||
5971 | struct btrfs_key key; | 5997 | struct btrfs_key key; |
5972 | int ret; | 5998 | int ret; |
5973 | 5999 | ||
@@ -5979,6 +6005,21 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, | |||
5979 | 6005 | ||
5980 | memcpy(&key, &block_group->key, sizeof(key)); | 6006 | memcpy(&key, &block_group->key, sizeof(key)); |
5981 | 6007 | ||
6008 | /* make sure this block group isn't part of an allocation cluster */ | ||
6009 | cluster = &root->fs_info->data_alloc_cluster; | ||
6010 | spin_lock(&cluster->refill_lock); | ||
6011 | btrfs_return_cluster_to_free_space(block_group, cluster); | ||
6012 | spin_unlock(&cluster->refill_lock); | ||
6013 | |||
6014 | /* | ||
6015 | * make sure this block group isn't part of a metadata | ||
6016 | * allocation cluster | ||
6017 | */ | ||
6018 | cluster = &root->fs_info->meta_alloc_cluster; | ||
6019 | spin_lock(&cluster->refill_lock); | ||
6020 | btrfs_return_cluster_to_free_space(block_group, cluster); | ||
6021 | spin_unlock(&cluster->refill_lock); | ||
6022 | |||
5982 | path = btrfs_alloc_path(); | 6023 | path = btrfs_alloc_path(); |
5983 | BUG_ON(!path); | 6024 | BUG_ON(!path); |
5984 | 6025 | ||
@@ -5988,7 +6029,11 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, | |||
5988 | spin_unlock(&root->fs_info->block_group_cache_lock); | 6029 | spin_unlock(&root->fs_info->block_group_cache_lock); |
5989 | btrfs_remove_free_space_cache(block_group); | 6030 | btrfs_remove_free_space_cache(block_group); |
5990 | down_write(&block_group->space_info->groups_sem); | 6031 | down_write(&block_group->space_info->groups_sem); |
5991 | list_del(&block_group->list); | 6032 | /* |
6033 | * we must use list_del_init so people can check to see if they | ||
6034 | * are still on the list after taking the semaphore | ||
6035 | */ | ||
6036 | list_del_init(&block_group->list); | ||
5992 | up_write(&block_group->space_info->groups_sem); | 6037 | up_write(&block_group->space_info->groups_sem); |
5993 | 6038 | ||
5994 | spin_lock(&block_group->space_info->lock); | 6039 | spin_lock(&block_group->space_info->lock); |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 5f01dad4b696..a6d35b0054ca 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -1440,6 +1440,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) | |||
1440 | device->io_align = root->sectorsize; | 1440 | device->io_align = root->sectorsize; |
1441 | device->sector_size = root->sectorsize; | 1441 | device->sector_size = root->sectorsize; |
1442 | device->total_bytes = i_size_read(bdev->bd_inode); | 1442 | device->total_bytes = i_size_read(bdev->bd_inode); |
1443 | device->disk_total_bytes = device->total_bytes; | ||
1443 | device->dev_root = root->fs_info->dev_root; | 1444 | device->dev_root = root->fs_info->dev_root; |
1444 | device->bdev = bdev; | 1445 | device->bdev = bdev; |
1445 | device->in_fs_metadata = 1; | 1446 | device->in_fs_metadata = 1; |
diff --git a/fs/buffer.c b/fs/buffer.c index aed297739eb0..49106127a4aa 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -2736,6 +2736,8 @@ has_buffers: | |||
2736 | pos += blocksize; | 2736 | pos += blocksize; |
2737 | } | 2737 | } |
2738 | 2738 | ||
2739 | map_bh.b_size = blocksize; | ||
2740 | map_bh.b_state = 0; | ||
2739 | err = get_block(inode, iblock, &map_bh, 0); | 2741 | err = get_block(inode, iblock, &map_bh, 0); |
2740 | if (err) | 2742 | if (err) |
2741 | goto unlock; | 2743 | goto unlock; |
diff --git a/fs/inode.c b/fs/inode.c index 0571983755dc..bca0c618fdb3 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -219,6 +219,7 @@ static struct inode *alloc_inode(struct super_block *sb) | |||
219 | void destroy_inode(struct inode *inode) | 219 | void destroy_inode(struct inode *inode) |
220 | { | 220 | { |
221 | BUG_ON(inode_has_buffers(inode)); | 221 | BUG_ON(inode_has_buffers(inode)); |
222 | ima_inode_free(inode); | ||
222 | security_inode_free(inode); | 223 | security_inode_free(inode); |
223 | if (inode->i_sb->s_op->destroy_inode) | 224 | if (inode->i_sb->s_op->destroy_inode) |
224 | inode->i_sb->s_op->destroy_inode(inode); | 225 | inode->i_sb->s_op->destroy_inode(inode); |
@@ -1053,13 +1054,22 @@ int insert_inode_locked(struct inode *inode) | |||
1053 | struct super_block *sb = inode->i_sb; | 1054 | struct super_block *sb = inode->i_sb; |
1054 | ino_t ino = inode->i_ino; | 1055 | ino_t ino = inode->i_ino; |
1055 | struct hlist_head *head = inode_hashtable + hash(sb, ino); | 1056 | struct hlist_head *head = inode_hashtable + hash(sb, ino); |
1056 | struct inode *old; | ||
1057 | 1057 | ||
1058 | inode->i_state |= I_LOCK|I_NEW; | 1058 | inode->i_state |= I_LOCK|I_NEW; |
1059 | while (1) { | 1059 | while (1) { |
1060 | struct hlist_node *node; | ||
1061 | struct inode *old = NULL; | ||
1060 | spin_lock(&inode_lock); | 1062 | spin_lock(&inode_lock); |
1061 | old = find_inode_fast(sb, head, ino); | 1063 | hlist_for_each_entry(old, node, head, i_hash) { |
1062 | if (likely(!old)) { | 1064 | if (old->i_ino != ino) |
1065 | continue; | ||
1066 | if (old->i_sb != sb) | ||
1067 | continue; | ||
1068 | if (old->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)) | ||
1069 | continue; | ||
1070 | break; | ||
1071 | } | ||
1072 | if (likely(!node)) { | ||
1063 | hlist_add_head(&inode->i_hash, head); | 1073 | hlist_add_head(&inode->i_hash, head); |
1064 | spin_unlock(&inode_lock); | 1074 | spin_unlock(&inode_lock); |
1065 | return 0; | 1075 | return 0; |
@@ -1081,14 +1091,24 @@ int insert_inode_locked4(struct inode *inode, unsigned long hashval, | |||
1081 | { | 1091 | { |
1082 | struct super_block *sb = inode->i_sb; | 1092 | struct super_block *sb = inode->i_sb; |
1083 | struct hlist_head *head = inode_hashtable + hash(sb, hashval); | 1093 | struct hlist_head *head = inode_hashtable + hash(sb, hashval); |
1084 | struct inode *old; | ||
1085 | 1094 | ||
1086 | inode->i_state |= I_LOCK|I_NEW; | 1095 | inode->i_state |= I_LOCK|I_NEW; |
1087 | 1096 | ||
1088 | while (1) { | 1097 | while (1) { |
1098 | struct hlist_node *node; | ||
1099 | struct inode *old = NULL; | ||
1100 | |||
1089 | spin_lock(&inode_lock); | 1101 | spin_lock(&inode_lock); |
1090 | old = find_inode(sb, head, test, data); | 1102 | hlist_for_each_entry(old, node, head, i_hash) { |
1091 | if (likely(!old)) { | 1103 | if (old->i_sb != sb) |
1104 | continue; | ||
1105 | if (!test(old, data)) | ||
1106 | continue; | ||
1107 | if (old->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)) | ||
1108 | continue; | ||
1109 | break; | ||
1110 | } | ||
1111 | if (likely(!node)) { | ||
1092 | hlist_add_head(&inode->i_hash, head); | 1112 | hlist_add_head(&inode->i_hash, head); |
1093 | spin_unlock(&inode_lock); | 1113 | spin_unlock(&inode_lock); |
1094 | return 0; | 1114 | return 0; |
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 3c1924c010e8..7300fb866767 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h | |||
@@ -471,6 +471,9 @@ struct drm_connector { | |||
471 | u32 property_ids[DRM_CONNECTOR_MAX_PROPERTY]; | 471 | u32 property_ids[DRM_CONNECTOR_MAX_PROPERTY]; |
472 | uint64_t property_values[DRM_CONNECTOR_MAX_PROPERTY]; | 472 | uint64_t property_values[DRM_CONNECTOR_MAX_PROPERTY]; |
473 | 473 | ||
474 | /* requested DPMS state */ | ||
475 | int dpms; | ||
476 | |||
474 | void *helper_private; | 477 | void *helper_private; |
475 | 478 | ||
476 | uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER]; | 479 | uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER]; |
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h index ec073d8288d9..6769ff6c1bc0 100644 --- a/include/drm/drm_crtc_helper.h +++ b/include/drm/drm_crtc_helper.h | |||
@@ -99,6 +99,8 @@ extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, | |||
99 | struct drm_framebuffer *old_fb); | 99 | struct drm_framebuffer *old_fb); |
100 | extern bool drm_helper_crtc_in_use(struct drm_crtc *crtc); | 100 | extern bool drm_helper_crtc_in_use(struct drm_crtc *crtc); |
101 | 101 | ||
102 | extern void drm_helper_connector_dpms(struct drm_connector *connector, int mode); | ||
103 | |||
102 | extern int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb, | 104 | extern int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb, |
103 | struct drm_mode_fb_cmd *mode_cmd); | 105 | struct drm_mode_fb_cmd *mode_cmd); |
104 | 106 | ||
diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index c7aa154f4bfc..eb96603d92db 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h | |||
@@ -259,14 +259,12 @@ static inline void tracehook_finish_clone(struct task_struct *child, | |||
259 | 259 | ||
260 | /** | 260 | /** |
261 | * tracehook_report_clone - in parent, new child is about to start running | 261 | * tracehook_report_clone - in parent, new child is about to start running |
262 | * @trace: return value from tracehook_prepare_clone() | ||
263 | * @regs: parent's user register state | 262 | * @regs: parent's user register state |
264 | * @clone_flags: flags from parent's system call | 263 | * @clone_flags: flags from parent's system call |
265 | * @pid: new child's PID in the parent's namespace | 264 | * @pid: new child's PID in the parent's namespace |
266 | * @child: new child task | 265 | * @child: new child task |
267 | * | 266 | * |
268 | * Called after a child is set up, but before it has been started | 267 | * Called after a child is set up, but before it has been started running. |
269 | * running. @trace is the value returned by tracehook_prepare_clone(). | ||
270 | * This is not a good place to block, because the child has not started | 268 | * This is not a good place to block, because the child has not started |
271 | * yet. Suspend the child here if desired, and then block in | 269 | * yet. Suspend the child here if desired, and then block in |
272 | * tracehook_report_clone_complete(). This must prevent the child from | 270 | * tracehook_report_clone_complete(). This must prevent the child from |
@@ -276,13 +274,14 @@ static inline void tracehook_finish_clone(struct task_struct *child, | |||
276 | * | 274 | * |
277 | * Called with no locks held, but the child cannot run until this returns. | 275 | * Called with no locks held, but the child cannot run until this returns. |
278 | */ | 276 | */ |
279 | static inline void tracehook_report_clone(int trace, struct pt_regs *regs, | 277 | static inline void tracehook_report_clone(struct pt_regs *regs, |
280 | unsigned long clone_flags, | 278 | unsigned long clone_flags, |
281 | pid_t pid, struct task_struct *child) | 279 | pid_t pid, struct task_struct *child) |
282 | { | 280 | { |
283 | if (unlikely(trace) || unlikely(clone_flags & CLONE_PTRACE)) { | 281 | if (unlikely(task_ptrace(child))) { |
284 | /* | 282 | /* |
285 | * The child starts up with an immediate SIGSTOP. | 283 | * It doesn't matter who attached/attaching to this |
284 | * task, the pending SIGSTOP is right in any case. | ||
286 | */ | 285 | */ |
287 | sigaddset(&child->pending.signal, SIGSTOP); | 286 | sigaddset(&child->pending.signal, SIGSTOP); |
288 | set_tsk_thread_flag(child, TIF_SIGPENDING); | 287 | set_tsk_thread_flag(child, TIF_SIGPENDING); |
diff --git a/kernel/fork.c b/kernel/fork.c index b9e2edd00726..875ffbdd96d0 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -1409,7 +1409,7 @@ long do_fork(unsigned long clone_flags, | |||
1409 | } | 1409 | } |
1410 | 1410 | ||
1411 | audit_finish_fork(p); | 1411 | audit_finish_fork(p); |
1412 | tracehook_report_clone(trace, regs, clone_flags, nr, p); | 1412 | tracehook_report_clone(regs, clone_flags, nr, p); |
1413 | 1413 | ||
1414 | /* | 1414 | /* |
1415 | * We set PF_STARTING at creation in case tracing wants to | 1415 | * We set PF_STARTING at creation in case tracing wants to |
diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 0692ab5a0d67..42c317874cfa 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c | |||
@@ -304,6 +304,8 @@ int ptrace_detach(struct task_struct *child, unsigned int data) | |||
304 | if (child->ptrace) { | 304 | if (child->ptrace) { |
305 | child->exit_code = data; | 305 | child->exit_code = data; |
306 | dead = __ptrace_detach(current, child); | 306 | dead = __ptrace_detach(current, child); |
307 | if (!child->exit_state) | ||
308 | wake_up_process(child); | ||
307 | } | 309 | } |
308 | write_unlock_irq(&tasklist_lock); | 310 | write_unlock_irq(&tasklist_lock); |
309 | 311 | ||