diff options
| -rw-r--r-- | arch/powerpc/kernel/vdso.c | 2 | ||||
| -rw-r--r-- | drivers/ata/Kconfig | 10 | ||||
| -rw-r--r-- | drivers/ata/ahci.c | 23 | ||||
| -rw-r--r-- | drivers/ata/ata_piix.c | 7 | ||||
| -rw-r--r-- | drivers/ata/libata-core.c | 4 | ||||
| -rw-r--r-- | drivers/ata/libata-scsi.c | 16 | ||||
| -rw-r--r-- | drivers/ata/libata.h | 2 | ||||
| -rw-r--r-- | drivers/ata/sata_mv.c | 21 | ||||
| -rw-r--r-- | drivers/watchdog/hpwdt.c | 155 | ||||
| -rw-r--r-- | mm/memory.c | 17 | ||||
| -rw-r--r-- | mm/migrate.c | 10 |
11 files changed, 171 insertions, 96 deletions
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c index c21a626af676..ce245a850db2 100644 --- a/arch/powerpc/kernel/vdso.c +++ b/arch/powerpc/kernel/vdso.c | |||
| @@ -142,7 +142,7 @@ static void dump_one_vdso_page(struct page *pg, struct page *upg) | |||
| 142 | printk("kpg: %p (c:%d,f:%08lx)", __va(page_to_pfn(pg) << PAGE_SHIFT), | 142 | printk("kpg: %p (c:%d,f:%08lx)", __va(page_to_pfn(pg) << PAGE_SHIFT), |
| 143 | page_count(pg), | 143 | page_count(pg), |
| 144 | pg->flags); | 144 | pg->flags); |
| 145 | if (upg/* && pg != upg*/) { | 145 | if (upg && !IS_ERR(upg) /* && pg != upg*/) { |
| 146 | printk(" upg: %p (c:%d,f:%08lx)", __va(page_to_pfn(upg) | 146 | printk(" upg: %p (c:%d,f:%08lx)", __va(page_to_pfn(upg) |
| 147 | << PAGE_SHIFT), | 147 | << PAGE_SHIFT), |
| 148 | page_count(upg), | 148 | page_count(upg), |
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 9bf2986a2788..ae8494944c45 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
| @@ -651,9 +651,17 @@ config PATA_WINBOND_VLB | |||
| 651 | Support for the Winbond W83759A controller on Vesa Local Bus | 651 | Support for the Winbond W83759A controller on Vesa Local Bus |
| 652 | systems. | 652 | systems. |
| 653 | 653 | ||
| 654 | config HAVE_PATA_PLATFORM | ||
| 655 | bool | ||
| 656 | help | ||
| 657 | This is an internal configuration node for any machine that | ||
| 658 | uses pata-platform driver to enable the relevant driver in the | ||
| 659 | configuration structure without having to submit endless patches | ||
| 660 | to update the PATA_PLATFORM entry. | ||
| 661 | |||
| 654 | config PATA_PLATFORM | 662 | config PATA_PLATFORM |
| 655 | tristate "Generic platform device PATA support" | 663 | tristate "Generic platform device PATA support" |
| 656 | depends on EMBEDDED || ARCH_RPC || PPC | 664 | depends on EMBEDDED || ARCH_RPC || PPC || HAVE_PATA_PLATFORM |
| 657 | help | 665 | help |
| 658 | This option enables support for generic directly connected ATA | 666 | This option enables support for generic directly connected ATA |
| 659 | devices commonly found on embedded systems. | 667 | devices commonly found on embedded systems. |
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 966ab401e523..6a4a2a25d97a 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
| @@ -90,6 +90,7 @@ enum { | |||
| 90 | board_ahci_mv = 4, | 90 | board_ahci_mv = 4, |
| 91 | board_ahci_sb700 = 5, | 91 | board_ahci_sb700 = 5, |
| 92 | board_ahci_mcp65 = 6, | 92 | board_ahci_mcp65 = 6, |
| 93 | board_ahci_nopmp = 7, | ||
| 93 | 94 | ||
| 94 | /* global controller registers */ | 95 | /* global controller registers */ |
| 95 | HOST_CAP = 0x00, /* host capabilities */ | 96 | HOST_CAP = 0x00, /* host capabilities */ |
| @@ -401,6 +402,14 @@ static const struct ata_port_info ahci_port_info[] = { | |||
| 401 | .udma_mask = ATA_UDMA6, | 402 | .udma_mask = ATA_UDMA6, |
| 402 | .port_ops = &ahci_ops, | 403 | .port_ops = &ahci_ops, |
| 403 | }, | 404 | }, |
| 405 | /* board_ahci_nopmp */ | ||
| 406 | { | ||
| 407 | AHCI_HFLAGS (AHCI_HFLAG_NO_PMP), | ||
| 408 | .flags = AHCI_FLAG_COMMON, | ||
| 409 | .pio_mask = 0x1f, /* pio0-4 */ | ||
| 410 | .udma_mask = ATA_UDMA6, | ||
| 411 | .port_ops = &ahci_ops, | ||
| 412 | }, | ||
| 404 | }; | 413 | }; |
| 405 | 414 | ||
| 406 | static const struct pci_device_id ahci_pci_tbl[] = { | 415 | static const struct pci_device_id ahci_pci_tbl[] = { |
| @@ -525,9 +534,9 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
| 525 | { PCI_VDEVICE(NVIDIA, 0x0bc7), board_ahci }, /* MCP7B */ | 534 | { PCI_VDEVICE(NVIDIA, 0x0bc7), board_ahci }, /* MCP7B */ |
| 526 | 535 | ||
| 527 | /* SiS */ | 536 | /* SiS */ |
| 528 | { PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */ | 537 | { PCI_VDEVICE(SI, 0x1184), board_ahci_nopmp }, /* SiS 966 */ |
| 529 | { PCI_VDEVICE(SI, 0x1185), board_ahci }, /* SiS 966 */ | 538 | { PCI_VDEVICE(SI, 0x1185), board_ahci_nopmp }, /* SiS 968 */ |
| 530 | { PCI_VDEVICE(SI, 0x0186), board_ahci }, /* SiS 968 */ | 539 | { PCI_VDEVICE(SI, 0x0186), board_ahci_nopmp }, /* SiS 968 */ |
| 531 | 540 | ||
| 532 | /* Marvell */ | 541 | /* Marvell */ |
| 533 | { PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv }, /* 6145 */ | 542 | { PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv }, /* 6145 */ |
| @@ -653,6 +662,14 @@ static void ahci_save_initial_config(struct pci_dev *pdev, | |||
| 653 | cap &= ~HOST_CAP_PMP; | 662 | cap &= ~HOST_CAP_PMP; |
| 654 | } | 663 | } |
| 655 | 664 | ||
| 665 | if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361 && | ||
| 666 | port_map != 1) { | ||
| 667 | dev_printk(KERN_INFO, &pdev->dev, | ||
| 668 | "JMB361 has only one port, port_map 0x%x -> 0x%x\n", | ||
| 669 | port_map, 1); | ||
| 670 | port_map = 1; | ||
| 671 | } | ||
| 672 | |||
| 656 | /* | 673 | /* |
| 657 | * Temporary Marvell 6145 hack: PATA port presence | 674 | * Temporary Marvell 6145 hack: PATA port presence |
| 658 | * is asserted through the standard AHCI port | 675 | * is asserted through the standard AHCI port |
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 81b7ae376951..a90ae03f56b2 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c | |||
| @@ -1043,6 +1043,13 @@ static int piix_broken_suspend(void) | |||
| 1043 | }, | 1043 | }, |
| 1044 | }, | 1044 | }, |
| 1045 | { | 1045 | { |
| 1046 | .ident = "TECRA M4", | ||
| 1047 | .matches = { | ||
| 1048 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
| 1049 | DMI_MATCH(DMI_PRODUCT_NAME, "TECRA M4"), | ||
| 1050 | }, | ||
| 1051 | }, | ||
| 1052 | { | ||
| 1046 | .ident = "TECRA M5", | 1053 | .ident = "TECRA M5", |
| 1047 | .matches = { | 1054 | .matches = { |
| 1048 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | 1055 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index cc816ca623d3..303fc0d2b978 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
| @@ -4297,7 +4297,7 @@ void ata_sg_clean(struct ata_queued_cmd *qc) | |||
| 4297 | } | 4297 | } |
| 4298 | 4298 | ||
| 4299 | /** | 4299 | /** |
| 4300 | * ata_check_atapi_dma - Check whether ATAPI DMA can be supported | 4300 | * atapi_check_dma - Check whether ATAPI DMA can be supported |
| 4301 | * @qc: Metadata associated with taskfile to check | 4301 | * @qc: Metadata associated with taskfile to check |
| 4302 | * | 4302 | * |
| 4303 | * Allow low-level driver to filter ATA PACKET commands, returning | 4303 | * Allow low-level driver to filter ATA PACKET commands, returning |
| @@ -4310,7 +4310,7 @@ void ata_sg_clean(struct ata_queued_cmd *qc) | |||
| 4310 | * RETURNS: 0 when ATAPI DMA can be used | 4310 | * RETURNS: 0 when ATAPI DMA can be used |
| 4311 | * nonzero otherwise | 4311 | * nonzero otherwise |
| 4312 | */ | 4312 | */ |
| 4313 | int ata_check_atapi_dma(struct ata_queued_cmd *qc) | 4313 | int atapi_check_dma(struct ata_queued_cmd *qc) |
| 4314 | { | 4314 | { |
| 4315 | struct ata_port *ap = qc->ap; | 4315 | struct ata_port *ap = qc->ap; |
| 4316 | 4316 | ||
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 2e6e1622dc6d..57a43649a461 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
| @@ -2343,8 +2343,8 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc) | |||
| 2343 | { | 2343 | { |
| 2344 | struct scsi_cmnd *scmd = qc->scsicmd; | 2344 | struct scsi_cmnd *scmd = qc->scsicmd; |
| 2345 | struct ata_device *dev = qc->dev; | 2345 | struct ata_device *dev = qc->dev; |
| 2346 | int using_pio = (dev->flags & ATA_DFLAG_PIO); | ||
| 2347 | int nodata = (scmd->sc_data_direction == DMA_NONE); | 2346 | int nodata = (scmd->sc_data_direction == DMA_NONE); |
| 2347 | int using_pio = !nodata && (dev->flags & ATA_DFLAG_PIO); | ||
| 2348 | unsigned int nbytes; | 2348 | unsigned int nbytes; |
| 2349 | 2349 | ||
| 2350 | memset(qc->cdb, 0, dev->cdb_len); | 2350 | memset(qc->cdb, 0, dev->cdb_len); |
| @@ -2362,7 +2362,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc) | |||
| 2362 | ata_qc_set_pc_nbytes(qc); | 2362 | ata_qc_set_pc_nbytes(qc); |
| 2363 | 2363 | ||
| 2364 | /* check whether ATAPI DMA is safe */ | 2364 | /* check whether ATAPI DMA is safe */ |
| 2365 | if (!using_pio && ata_check_atapi_dma(qc)) | 2365 | if (!nodata && !using_pio && atapi_check_dma(qc)) |
| 2366 | using_pio = 1; | 2366 | using_pio = 1; |
| 2367 | 2367 | ||
| 2368 | /* Some controller variants snoop this value for Packet | 2368 | /* Some controller variants snoop this value for Packet |
| @@ -2402,13 +2402,11 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc) | |||
| 2402 | qc->tf.lbam = (nbytes & 0xFF); | 2402 | qc->tf.lbam = (nbytes & 0xFF); |
| 2403 | qc->tf.lbah = (nbytes >> 8); | 2403 | qc->tf.lbah = (nbytes >> 8); |
| 2404 | 2404 | ||
| 2405 | if (using_pio || nodata) { | 2405 | if (nodata) |
| 2406 | /* no data, or PIO data xfer */ | 2406 | qc->tf.protocol = ATAPI_PROT_NODATA; |
| 2407 | if (nodata) | 2407 | else if (using_pio) |
| 2408 | qc->tf.protocol = ATAPI_PROT_NODATA; | 2408 | qc->tf.protocol = ATAPI_PROT_PIO; |
| 2409 | else | 2409 | else { |
| 2410 | qc->tf.protocol = ATAPI_PROT_PIO; | ||
| 2411 | } else { | ||
| 2412 | /* DMA data xfer */ | 2410 | /* DMA data xfer */ |
| 2413 | qc->tf.protocol = ATAPI_PROT_DMA; | 2411 | qc->tf.protocol = ATAPI_PROT_DMA; |
| 2414 | qc->tf.feature |= ATAPI_PKT_DMA; | 2412 | qc->tf.feature |= ATAPI_PKT_DMA; |
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 4514283937ea..1cf803adbc95 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h | |||
| @@ -106,7 +106,7 @@ extern void ata_sg_clean(struct ata_queued_cmd *qc); | |||
| 106 | extern void ata_qc_free(struct ata_queued_cmd *qc); | 106 | extern void ata_qc_free(struct ata_queued_cmd *qc); |
| 107 | extern void ata_qc_issue(struct ata_queued_cmd *qc); | 107 | extern void ata_qc_issue(struct ata_queued_cmd *qc); |
| 108 | extern void __ata_qc_complete(struct ata_queued_cmd *qc); | 108 | extern void __ata_qc_complete(struct ata_queued_cmd *qc); |
| 109 | extern int ata_check_atapi_dma(struct ata_queued_cmd *qc); | 109 | extern int atapi_check_dma(struct ata_queued_cmd *qc); |
| 110 | extern void swap_buf_le16(u16 *buf, unsigned int buf_words); | 110 | extern void swap_buf_le16(u16 *buf, unsigned int buf_words); |
| 111 | extern void ata_dev_init(struct ata_device *dev); | 111 | extern void ata_dev_init(struct ata_device *dev); |
| 112 | extern void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp); | 112 | extern void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp); |
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 60391e9a84db..28092bc50146 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
| @@ -1322,6 +1322,9 @@ static int mv_port_start(struct ata_port *ap) | |||
| 1322 | goto out_port_free_dma_mem; | 1322 | goto out_port_free_dma_mem; |
| 1323 | memset(pp->crpb, 0, MV_CRPB_Q_SZ); | 1323 | memset(pp->crpb, 0, MV_CRPB_Q_SZ); |
| 1324 | 1324 | ||
| 1325 | /* 6041/6081 Rev. "C0" (and newer) are okay with async notify */ | ||
| 1326 | if (hpriv->hp_flags & MV_HP_ERRATA_60X1C0) | ||
| 1327 | ap->flags |= ATA_FLAG_AN; | ||
| 1325 | /* | 1328 | /* |
| 1326 | * For GEN_I, there's no NCQ, so we only allocate a single sg_tbl. | 1329 | * For GEN_I, there's no NCQ, so we only allocate a single sg_tbl. |
| 1327 | * For later hardware, we need one unique sg_tbl per NCQ tag. | 1330 | * For later hardware, we need one unique sg_tbl per NCQ tag. |
| @@ -1592,6 +1595,24 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) | |||
| 1592 | 1595 | ||
| 1593 | if ((qc->tf.protocol != ATA_PROT_DMA) && | 1596 | if ((qc->tf.protocol != ATA_PROT_DMA) && |
| 1594 | (qc->tf.protocol != ATA_PROT_NCQ)) { | 1597 | (qc->tf.protocol != ATA_PROT_NCQ)) { |
| 1598 | static int limit_warnings = 10; | ||
| 1599 | /* | ||
| 1600 | * Errata SATA#16, SATA#24: warn if multiple DRQs expected. | ||
| 1601 | * | ||
| 1602 | * Someday, we might implement special polling workarounds | ||
| 1603 | * for these, but it all seems rather unnecessary since we | ||
| 1604 | * normally use only DMA for commands which transfer more | ||
| 1605 | * than a single block of data. | ||
| 1606 | * | ||
| 1607 | * Much of the time, this could just work regardless. | ||
| 1608 | * So for now, just log the incident, and allow the attempt. | ||
| 1609 | */ | ||
| 1610 | if (limit_warnings && (qc->nbytes / qc->sect_size) > 1) { | ||
| 1611 | --limit_warnings; | ||
| 1612 | ata_link_printk(qc->dev->link, KERN_WARNING, DRV_NAME | ||
| 1613 | ": attempting PIO w/multiple DRQ: " | ||
| 1614 | "this may fail due to h/w errata\n"); | ||
| 1615 | } | ||
| 1595 | /* | 1616 | /* |
| 1596 | * We're about to send a non-EDMA capable command to the | 1617 | * We're about to send a non-EDMA capable command to the |
| 1597 | * port. Turn off EDMA so there won't be problems accessing | 1618 | * port. Turn off EDMA so there won't be problems accessing |
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index 2686f3eaeedf..eaa3f2a79ff5 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c | |||
| @@ -140,49 +140,53 @@ static struct pci_device_id hpwdt_devices[] = { | |||
| 140 | }; | 140 | }; |
| 141 | MODULE_DEVICE_TABLE(pci, hpwdt_devices); | 141 | MODULE_DEVICE_TABLE(pci, hpwdt_devices); |
| 142 | 142 | ||
| 143 | extern asmlinkage void asminline_call(struct cmn_registers *pi86Regs, unsigned long *pRomEntry); | ||
| 144 | |||
| 143 | #ifndef CONFIG_X86_64 | 145 | #ifndef CONFIG_X86_64 |
| 144 | /* --32 Bit Bios------------------------------------------------------------ */ | 146 | /* --32 Bit Bios------------------------------------------------------------ */ |
| 145 | 147 | ||
| 146 | #define HPWDT_ARCH 32 | 148 | #define HPWDT_ARCH 32 |
| 147 | 149 | ||
| 148 | asmlinkage void asminline_call(struct cmn_registers *pi86Regs, | 150 | asm(".text \n\t" |
| 149 | unsigned long *pRomEntry) | 151 | ".align 4 \n" |
| 150 | { | 152 | "asminline_call: \n\t" |
| 151 | asm("pushl %ebp \n\t" | 153 | "pushl %ebp \n\t" |
| 152 | "movl %esp, %ebp \n\t" | 154 | "movl %esp, %ebp \n\t" |
| 153 | "pusha \n\t" | 155 | "pusha \n\t" |
| 154 | "pushf \n\t" | 156 | "pushf \n\t" |
| 155 | "push %es \n\t" | 157 | "push %es \n\t" |
| 156 | "push %ds \n\t" | 158 | "push %ds \n\t" |
| 157 | "pop %es \n\t" | 159 | "pop %es \n\t" |
| 158 | "movl 8(%ebp),%eax \n\t" | 160 | "movl 8(%ebp),%eax \n\t" |
| 159 | "movl 4(%eax),%ebx \n\t" | 161 | "movl 4(%eax),%ebx \n\t" |
| 160 | "movl 8(%eax),%ecx \n\t" | 162 | "movl 8(%eax),%ecx \n\t" |
| 161 | "movl 12(%eax),%edx \n\t" | 163 | "movl 12(%eax),%edx \n\t" |
| 162 | "movl 16(%eax),%esi \n\t" | 164 | "movl 16(%eax),%esi \n\t" |
| 163 | "movl 20(%eax),%edi \n\t" | 165 | "movl 20(%eax),%edi \n\t" |
| 164 | "movl (%eax),%eax \n\t" | 166 | "movl (%eax),%eax \n\t" |
| 165 | "push %cs \n\t" | 167 | "push %cs \n\t" |
| 166 | "call *12(%ebp) \n\t" | 168 | "call *12(%ebp) \n\t" |
| 167 | "pushf \n\t" | 169 | "pushf \n\t" |
| 168 | "pushl %eax \n\t" | 170 | "pushl %eax \n\t" |
| 169 | "movl 8(%ebp),%eax \n\t" | 171 | "movl 8(%ebp),%eax \n\t" |
| 170 | "movl %ebx,4(%eax) \n\t" | 172 | "movl %ebx,4(%eax) \n\t" |
| 171 | "movl %ecx,8(%eax) \n\t" | 173 | "movl %ecx,8(%eax) \n\t" |
| 172 | "movl %edx,12(%eax) \n\t" | 174 | "movl %edx,12(%eax) \n\t" |
| 173 | "movl %esi,16(%eax) \n\t" | 175 | "movl %esi,16(%eax) \n\t" |
| 174 | "movl %edi,20(%eax) \n\t" | 176 | "movl %edi,20(%eax) \n\t" |
| 175 | "movw %ds,24(%eax) \n\t" | 177 | "movw %ds,24(%eax) \n\t" |
| 176 | "movw %es,26(%eax) \n\t" | 178 | "movw %es,26(%eax) \n\t" |
| 177 | "popl %ebx \n\t" | 179 | "popl %ebx \n\t" |
| 178 | "movl %ebx,(%eax) \n\t" | 180 | "movl %ebx,(%eax) \n\t" |
| 179 | "popl %ebx \n\t" | 181 | "popl %ebx \n\t" |
| 180 | "movl %ebx,28(%eax) \n\t" | 182 | "movl %ebx,28(%eax) \n\t" |
| 181 | "pop %es \n\t" | 183 | "pop %es \n\t" |
| 182 | "popf \n\t" | 184 | "popf \n\t" |
| 183 | "popa \n\t" | 185 | "popa \n\t" |
| 184 | "leave \n\t" "ret"); | 186 | "leave \n\t" |
| 185 | } | 187 | "ret \n\t" |
| 188 | ".previous"); | ||
| 189 | |||
| 186 | 190 | ||
| 187 | /* | 191 | /* |
| 188 | * cru_detect | 192 | * cru_detect |
| @@ -333,43 +337,44 @@ static int __devinit detect_cru_service(void) | |||
| 333 | 337 | ||
| 334 | #define HPWDT_ARCH 64 | 338 | #define HPWDT_ARCH 64 |
| 335 | 339 | ||
| 336 | asmlinkage void asminline_call(struct cmn_registers *pi86Regs, | 340 | asm(".text \n\t" |
| 337 | unsigned long *pRomEntry) | 341 | ".align 4 \n" |
| 338 | { | 342 | "asminline_call: \n\t" |
| 339 | asm("pushq %rbp \n\t" | 343 | "pushq %rbp \n\t" |
| 340 | "movq %rsp, %rbp \n\t" | 344 | "movq %rsp, %rbp \n\t" |
| 341 | "pushq %rax \n\t" | 345 | "pushq %rax \n\t" |
| 342 | "pushq %rbx \n\t" | 346 | "pushq %rbx \n\t" |
| 343 | "pushq %rdx \n\t" | 347 | "pushq %rdx \n\t" |
| 344 | "pushq %r12 \n\t" | 348 | "pushq %r12 \n\t" |
| 345 | "pushq %r9 \n\t" | 349 | "pushq %r9 \n\t" |
| 346 | "movq %rsi, %r12 \n\t" | 350 | "movq %rsi, %r12 \n\t" |
| 347 | "movq %rdi, %r9 \n\t" | 351 | "movq %rdi, %r9 \n\t" |
| 348 | "movl 4(%r9),%ebx \n\t" | 352 | "movl 4(%r9),%ebx \n\t" |
| 349 | "movl 8(%r9),%ecx \n\t" | 353 | "movl 8(%r9),%ecx \n\t" |
| 350 | "movl 12(%r9),%edx \n\t" | 354 | "movl 12(%r9),%edx \n\t" |
| 351 | "movl 16(%r9),%esi \n\t" | 355 | "movl 16(%r9),%esi \n\t" |
| 352 | "movl 20(%r9),%edi \n\t" | 356 | "movl 20(%r9),%edi \n\t" |
| 353 | "movl (%r9),%eax \n\t" | 357 | "movl (%r9),%eax \n\t" |
| 354 | "call *%r12 \n\t" | 358 | "call *%r12 \n\t" |
| 355 | "pushfq \n\t" | 359 | "pushfq \n\t" |
| 356 | "popq %r12 \n\t" | 360 | "popq %r12 \n\t" |
| 357 | "popfq \n\t" | 361 | "popfq \n\t" |
| 358 | "movl %eax, (%r9) \n\t" | 362 | "movl %eax, (%r9) \n\t" |
| 359 | "movl %ebx, 4(%r9) \n\t" | 363 | "movl %ebx, 4(%r9) \n\t" |
| 360 | "movl %ecx, 8(%r9) \n\t" | 364 | "movl %ecx, 8(%r9) \n\t" |
| 361 | "movl %edx, 12(%r9) \n\t" | 365 | "movl %edx, 12(%r9) \n\t" |
| 362 | "movl %esi, 16(%r9) \n\t" | 366 | "movl %esi, 16(%r9) \n\t" |
| 363 | "movl %edi, 20(%r9) \n\t" | 367 | "movl %edi, 20(%r9) \n\t" |
| 364 | "movq %r12, %rax \n\t" | 368 | "movq %r12, %rax \n\t" |
| 365 | "movl %eax, 28(%r9) \n\t" | 369 | "movl %eax, 28(%r9) \n\t" |
| 366 | "popq %r9 \n\t" | 370 | "popq %r9 \n\t" |
| 367 | "popq %r12 \n\t" | 371 | "popq %r12 \n\t" |
| 368 | "popq %rdx \n\t" | 372 | "popq %rdx \n\t" |
| 369 | "popq %rbx \n\t" | 373 | "popq %rbx \n\t" |
| 370 | "popq %rax \n\t" | 374 | "popq %rax \n\t" |
| 371 | "leave \n\t" "ret"); | 375 | "leave \n\t" |
| 372 | } | 376 | "ret \n\t" |
| 377 | ".previous"); | ||
| 373 | 378 | ||
| 374 | /* | 379 | /* |
| 375 | * dmi_find_cru | 380 | * dmi_find_cru |
diff --git a/mm/memory.c b/mm/memory.c index 19e0ae9beecb..9aefaae46858 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
| @@ -999,17 +999,15 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address, | |||
| 999 | goto no_page_table; | 999 | goto no_page_table; |
| 1000 | 1000 | ||
| 1001 | ptep = pte_offset_map_lock(mm, pmd, address, &ptl); | 1001 | ptep = pte_offset_map_lock(mm, pmd, address, &ptl); |
| 1002 | if (!ptep) | ||
| 1003 | goto out; | ||
| 1004 | 1002 | ||
| 1005 | pte = *ptep; | 1003 | pte = *ptep; |
| 1006 | if (!pte_present(pte)) | 1004 | if (!pte_present(pte)) |
| 1007 | goto unlock; | 1005 | goto no_page; |
| 1008 | if ((flags & FOLL_WRITE) && !pte_write(pte)) | 1006 | if ((flags & FOLL_WRITE) && !pte_write(pte)) |
| 1009 | goto unlock; | 1007 | goto unlock; |
| 1010 | page = vm_normal_page(vma, address, pte); | 1008 | page = vm_normal_page(vma, address, pte); |
| 1011 | if (unlikely(!page)) | 1009 | if (unlikely(!page)) |
| 1012 | goto unlock; | 1010 | goto bad_page; |
| 1013 | 1011 | ||
| 1014 | if (flags & FOLL_GET) | 1012 | if (flags & FOLL_GET) |
| 1015 | get_page(page); | 1013 | get_page(page); |
| @@ -1024,6 +1022,15 @@ unlock: | |||
| 1024 | out: | 1022 | out: |
| 1025 | return page; | 1023 | return page; |
| 1026 | 1024 | ||
| 1025 | bad_page: | ||
| 1026 | pte_unmap_unlock(ptep, ptl); | ||
| 1027 | return ERR_PTR(-EFAULT); | ||
| 1028 | |||
| 1029 | no_page: | ||
| 1030 | pte_unmap_unlock(ptep, ptl); | ||
| 1031 | if (!pte_none(pte)) | ||
| 1032 | return page; | ||
| 1033 | /* Fall through to ZERO_PAGE handling */ | ||
| 1027 | no_page_table: | 1034 | no_page_table: |
| 1028 | /* | 1035 | /* |
| 1029 | * When core dumping an enormous anonymous area that nobody | 1036 | * When core dumping an enormous anonymous area that nobody |
| @@ -1159,6 +1166,8 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | |||
| 1159 | 1166 | ||
| 1160 | cond_resched(); | 1167 | cond_resched(); |
| 1161 | } | 1168 | } |
| 1169 | if (IS_ERR(page)) | ||
| 1170 | return i ? i : PTR_ERR(page); | ||
| 1162 | if (pages) { | 1171 | if (pages) { |
| 1163 | pages[i] = page; | 1172 | pages[i] = page; |
| 1164 | 1173 | ||
diff --git a/mm/migrate.c b/mm/migrate.c index 449d77d409f5..112bcaeaa104 100644 --- a/mm/migrate.c +++ b/mm/migrate.c | |||
| @@ -865,6 +865,11 @@ static int do_move_pages(struct mm_struct *mm, struct page_to_node *pm, | |||
| 865 | goto set_status; | 865 | goto set_status; |
| 866 | 866 | ||
| 867 | page = follow_page(vma, pp->addr, FOLL_GET); | 867 | page = follow_page(vma, pp->addr, FOLL_GET); |
| 868 | |||
| 869 | err = PTR_ERR(page); | ||
| 870 | if (IS_ERR(page)) | ||
| 871 | goto set_status; | ||
| 872 | |||
| 868 | err = -ENOENT; | 873 | err = -ENOENT; |
| 869 | if (!page) | 874 | if (!page) |
| 870 | goto set_status; | 875 | goto set_status; |
| @@ -928,6 +933,11 @@ static int do_pages_stat(struct mm_struct *mm, struct page_to_node *pm) | |||
| 928 | goto set_status; | 933 | goto set_status; |
| 929 | 934 | ||
| 930 | page = follow_page(vma, pm->addr, 0); | 935 | page = follow_page(vma, pm->addr, 0); |
| 936 | |||
| 937 | err = PTR_ERR(page); | ||
| 938 | if (IS_ERR(page)) | ||
| 939 | goto set_status; | ||
| 940 | |||
| 931 | err = -ENOENT; | 941 | err = -ENOENT; |
| 932 | /* Use PageReserved to check for zero page */ | 942 | /* Use PageReserved to check for zero page */ |
| 933 | if (!page || PageReserved(page)) | 943 | if (!page || PageReserved(page)) |
