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)) |