From: Greg Kroah-Hartman Date: Wed, 29 Apr 2009 20:40:09 +0000 (-0700) Subject: more .27 patches X-Git-Tag: v2.6.27.22~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=66e442f7f37560589dfbdfaecefe40b110e0d38a;p=thirdparty%2Fkernel%2Fstable-queue.git more .27 patches --- diff --git a/queue-2.6.27/acpi-ec-add-some-basic-check-for-ecdt-data.patch b/queue-2.6.27/acpi-ec-add-some-basic-check-for-ecdt-data.patch new file mode 100644 index 00000000000..e11358f84d9 --- /dev/null +++ b/queue-2.6.27/acpi-ec-add-some-basic-check-for-ecdt-data.patch @@ -0,0 +1,84 @@ +From c5279dee26c0e8d7c4200993bfc4b540d2469598 Mon Sep 17 00:00:00 2001 +From: Alexey Starikovskiy +Date: Wed, 26 Nov 2008 17:11:53 -0500 +Subject: ACPI: EC: Add some basic check for ECDT data + +From: Alexey Starikovskiy + +commit c5279dee26c0e8d7c4200993bfc4b540d2469598 upstream. + +One more ASUS comes with empty ECDT, add a guard for it... + +http://bugzilla.kernel.org/show_bug.cgi?id=11880 + +Signed-off-by: Alexey Starikovskiy +Signed-off-by: Len Brown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/acpi/ec.c | 43 ++++++++++++++++++++++--------------------- + 1 file changed, 22 insertions(+), 21 deletions(-) + +--- a/drivers/acpi/ec.c ++++ b/drivers/acpi/ec.c +@@ -968,7 +968,6 @@ static const struct acpi_device_id ec_de + + int __init acpi_ec_ecdt_probe(void) + { +- int ret; + acpi_status status; + struct acpi_table_ecdt *ecdt_ptr; + +@@ -996,30 +995,32 @@ int __init acpi_ec_ecdt_probe(void) + boot_ec->gpe = ecdt_ptr->gpe; + boot_ec->handle = ACPI_ROOT_OBJECT; + acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle); +- } else { +- /* This workaround is needed only on some broken machines, +- * which require early EC, but fail to provide ECDT */ +- acpi_handle x; +- printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n"); +- status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device, +- boot_ec, NULL); +- /* Check that acpi_get_devices actually find something */ +- if (ACPI_FAILURE(status) || !boot_ec->handle) +- goto error; +- /* We really need to limit this workaround, the only ASUS, +- * which needs it, has fake EC._INI method, so use it as flag. +- * Keep boot_ec struct as it will be needed soon. +- */ +- if (ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", &x))) +- return -ENODEV; ++ /* Add some basic check against completely broken table */ ++ if (boot_ec->data_addr != boot_ec->command_addr) ++ goto install; ++ /* fall through */ + } +- +- ret = ec_install_handlers(boot_ec); +- if (!ret) { ++ /* This workaround is needed only on some broken machines, ++ * which require early EC, but fail to provide ECDT */ ++ acpi_handle x; ++ printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n"); ++ status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device, ++ boot_ec, NULL); ++ /* Check that acpi_get_devices actually find something */ ++ if (ACPI_FAILURE(status) || !boot_ec->handle) ++ goto error; ++ /* We really need to limit this workaround, the only ASUS, ++ * which needs it, has fake EC._INI method, so use it as flag. ++ * Keep boot_ec struct as it will be needed soon. ++ */ ++ if (ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", &x))) ++ return -ENODEV; ++install: ++ if (!ec_install_handlers(boot_ec)) { + first_ec = boot_ec; + return 0; + } +- error: ++error: + kfree(boot_ec); + boot_ec = NULL; + return -ENODEV; diff --git a/queue-2.6.27/acpi-ec-fix-compilation-warning.patch b/queue-2.6.27/acpi-ec-fix-compilation-warning.patch new file mode 100644 index 00000000000..bf571e0c2a8 --- /dev/null +++ b/queue-2.6.27/acpi-ec-fix-compilation-warning.patch @@ -0,0 +1,51 @@ +From 3e54048691bce3f323fd5460695273be379803b9 Mon Sep 17 00:00:00 2001 +From: Hannes Eder +Date: Sat, 29 Nov 2008 07:21:29 +0100 +Subject: ACPI: EC: fix compilation warning + +From: Hannes Eder + +commit 3e54048691bce3f323fd5460695273be379803b9 upstream. + +Fix the warning introduced in commit c5279dee26c0e8d7c4200993bfc4b540d2469598, +and give the dummy variable a more verbose name. + + drivers/acpi/ec.c: In function 'acpi_ec_ecdt_probe': + drivers/acpi/ec.c:1015: warning: ISO C90 forbids mixed declarations and code + +Signed-off-by: Hannes Eder +Acked-by: Alexey Starikovskiy +Signed-off-by: Len Brown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/acpi/ec.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/acpi/ec.c ++++ b/drivers/acpi/ec.c +@@ -970,6 +970,7 @@ int __init acpi_ec_ecdt_probe(void) + { + acpi_status status; + struct acpi_table_ecdt *ecdt_ptr; ++ acpi_handle dummy; + + boot_ec = make_acpi_ec(); + if (!boot_ec) +@@ -1002,7 +1003,6 @@ int __init acpi_ec_ecdt_probe(void) + } + /* This workaround is needed only on some broken machines, + * which require early EC, but fail to provide ECDT */ +- acpi_handle x; + printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n"); + status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device, + boot_ec, NULL); +@@ -1013,7 +1013,7 @@ int __init acpi_ec_ecdt_probe(void) + * which needs it, has fake EC._INI method, so use it as flag. + * Keep boot_ec struct as it will be needed soon. + */ +- if (ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", &x))) ++ if (ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", &dummy))) + return -ENODEV; + install: + if (!ec_install_handlers(boot_ec)) { diff --git a/queue-2.6.27/b44-use-kernel-dma-addresses-for-the-kernel-dma-api.patch b/queue-2.6.27/b44-use-kernel-dma-addresses-for-the-kernel-dma-api.patch new file mode 100644 index 00000000000..0aceff2a5f8 --- /dev/null +++ b/queue-2.6.27/b44-use-kernel-dma-addresses-for-the-kernel-dma-api.patch @@ -0,0 +1,34 @@ +From 37efa239901493694a48f1d6f59f8de17c2c4509 Mon Sep 17 00:00:00 2001 +From: Michael Buesch +Date: Mon, 6 Apr 2009 09:52:27 +0000 +Subject: b44: Use kernel DMA addresses for the kernel DMA API + +From: Michael Buesch + +commit 37efa239901493694a48f1d6f59f8de17c2c4509 upstream. + +We must not use the device DMA addresses for the kernel DMA API, because +device DMA addresses have an additional offset added for the SSB translation. + +Use the original dma_addr_t for the sync operation. + +Cc: stable@kernel.org +Signed-off-by: Michael Buesch +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/b44.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/b44.c ++++ b/drivers/net/b44.c +@@ -750,7 +750,7 @@ static void b44_recycle_rx(struct b44 *b + dest_idx * sizeof(dest_desc), + DMA_BIDIRECTIONAL); + +- ssb_dma_sync_single_for_device(bp->sdev, le32_to_cpu(src_desc->addr), ++ ssb_dma_sync_single_for_device(bp->sdev, dest_map->mapping, + RX_PKT_BUF_SZ, + DMA_FROM_DEVICE); + } diff --git a/queue-2.6.27/crypto-ixp4xx-fix-handling-of-chained-sg-buffers.patch b/queue-2.6.27/crypto-ixp4xx-fix-handling-of-chained-sg-buffers.patch new file mode 100644 index 00000000000..5c0c10808dc --- /dev/null +++ b/queue-2.6.27/crypto-ixp4xx-fix-handling-of-chained-sg-buffers.patch @@ -0,0 +1,390 @@ +From 0d44dc59b2b434b29aafeae581d06f81efac7c83 Mon Sep 17 00:00:00 2001 +From: Christian Hohnstaedt +Date: Fri, 27 Mar 2009 15:09:05 +0800 +Subject: crypto: ixp4xx - Fix handling of chained sg buffers + +From: Christian Hohnstaedt + +commit 0d44dc59b2b434b29aafeae581d06f81efac7c83 upstream. + + - keep dma functions away from chained scatterlists. + Use the existing scatterlist iteration inside the driver + to call dma_map_single() for each chunk and avoid dma_map_sg(). + +Signed-off-by: Christian Hohnstaedt +Tested-By: Karl Hiramoto +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/crypto/ixp4xx_crypto.c | 184 ++++++++++++++--------------------------- + 1 file changed, 64 insertions(+), 120 deletions(-) + +--- a/drivers/crypto/ixp4xx_crypto.c ++++ b/drivers/crypto/ixp4xx_crypto.c +@@ -101,6 +101,7 @@ struct buffer_desc { + u32 phys_addr; + u32 __reserved[4]; + struct buffer_desc *next; ++ enum dma_data_direction dir; + }; + + struct crypt_ctl { +@@ -132,14 +133,10 @@ struct crypt_ctl { + struct ablk_ctx { + struct buffer_desc *src; + struct buffer_desc *dst; +- unsigned src_nents; +- unsigned dst_nents; + }; + + struct aead_ctx { + struct buffer_desc *buffer; +- unsigned short assoc_nents; +- unsigned short src_nents; + struct scatterlist ivlist; + /* used when the hmac is not on one sg entry */ + u8 *hmac_virt; +@@ -312,7 +309,7 @@ static struct crypt_ctl *get_crypt_desc_ + } + } + +-static void free_buf_chain(struct buffer_desc *buf, u32 phys) ++static void free_buf_chain(struct device *dev, struct buffer_desc *buf,u32 phys) + { + while (buf) { + struct buffer_desc *buf1; +@@ -320,6 +317,7 @@ static void free_buf_chain(struct buffer + + buf1 = buf->next; + phys1 = buf->phys_next; ++ dma_unmap_single(dev, buf->phys_next, buf->buf_len, buf->dir); + dma_pool_free(buffer_pool, buf, phys); + buf = buf1; + phys = phys1; +@@ -348,7 +346,6 @@ static void one_packet(dma_addr_t phys) + struct crypt_ctl *crypt; + struct ixp_ctx *ctx; + int failed; +- enum dma_data_direction src_direction = DMA_BIDIRECTIONAL; + + failed = phys & 0x1 ? -EBADMSG : 0; + phys &= ~0x3; +@@ -358,13 +355,8 @@ static void one_packet(dma_addr_t phys) + case CTL_FLAG_PERFORM_AEAD: { + struct aead_request *req = crypt->data.aead_req; + struct aead_ctx *req_ctx = aead_request_ctx(req); +- dma_unmap_sg(dev, req->assoc, req_ctx->assoc_nents, +- DMA_TO_DEVICE); +- dma_unmap_sg(dev, &req_ctx->ivlist, 1, DMA_BIDIRECTIONAL); +- dma_unmap_sg(dev, req->src, req_ctx->src_nents, +- DMA_BIDIRECTIONAL); + +- free_buf_chain(req_ctx->buffer, crypt->src_buf); ++ free_buf_chain(dev, req_ctx->buffer, crypt->src_buf); + if (req_ctx->hmac_virt) { + finish_scattered_hmac(crypt); + } +@@ -374,16 +366,11 @@ static void one_packet(dma_addr_t phys) + case CTL_FLAG_PERFORM_ABLK: { + struct ablkcipher_request *req = crypt->data.ablk_req; + struct ablk_ctx *req_ctx = ablkcipher_request_ctx(req); +- int nents; ++ + if (req_ctx->dst) { +- nents = req_ctx->dst_nents; +- dma_unmap_sg(dev, req->dst, nents, DMA_FROM_DEVICE); +- free_buf_chain(req_ctx->dst, crypt->dst_buf); +- src_direction = DMA_TO_DEVICE; +- } +- nents = req_ctx->src_nents; +- dma_unmap_sg(dev, req->src, nents, src_direction); +- free_buf_chain(req_ctx->src, crypt->src_buf); ++ free_buf_chain(dev, req_ctx->dst, crypt->dst_buf); ++ } ++ free_buf_chain(dev, req_ctx->src, crypt->src_buf); + req->base.complete(&req->base, failed); + break; + } +@@ -748,56 +735,35 @@ static int setup_cipher(struct crypto_tf + return 0; + } + +-static int count_sg(struct scatterlist *sg, int nbytes) +-{ +- int i; +- for (i = 0; nbytes > 0; i++, sg = sg_next(sg)) +- nbytes -= sg->length; +- return i; +-} +- +-static struct buffer_desc *chainup_buffers(struct scatterlist *sg, +- unsigned nbytes, struct buffer_desc *buf, gfp_t flags) ++static struct buffer_desc *chainup_buffers(struct device *dev, ++ struct scatterlist *sg, unsigned nbytes, ++ struct buffer_desc *buf, gfp_t flags, ++ enum dma_data_direction dir) + { +- int nents = 0; +- +- while (nbytes > 0) { ++ for (;nbytes > 0; sg = scatterwalk_sg_next(sg)) { ++ unsigned len = min(nbytes, sg->length); + struct buffer_desc *next_buf; + u32 next_buf_phys; +- unsigned len = min(nbytes, sg_dma_len(sg)); ++ void *ptr; + +- nents++; + nbytes -= len; +- if (!buf->phys_addr) { +- buf->phys_addr = sg_dma_address(sg); +- buf->buf_len = len; +- buf->next = NULL; +- buf->phys_next = 0; +- goto next; +- } +- /* Two consecutive chunks on one page may be handled by the old +- * buffer descriptor, increased by the length of the new one +- */ +- if (sg_dma_address(sg) == buf->phys_addr + buf->buf_len) { +- buf->buf_len += len; +- goto next; +- } ++ ptr = page_address(sg_page(sg)) + sg->offset; + next_buf = dma_pool_alloc(buffer_pool, flags, &next_buf_phys); +- if (!next_buf) +- return NULL; ++ if (!next_buf) { ++ buf = NULL; ++ break; ++ } ++ sg_dma_address(sg) = dma_map_single(dev, ptr, len, dir); + buf->next = next_buf; + buf->phys_next = next_buf_phys; +- + buf = next_buf; +- buf->next = NULL; +- buf->phys_next = 0; ++ + buf->phys_addr = sg_dma_address(sg); + buf->buf_len = len; +-next: +- if (nbytes > 0) { +- sg = sg_next(sg); +- } ++ buf->dir = dir; + } ++ buf->next = NULL; ++ buf->phys_next = 0; + return buf; + } + +@@ -858,12 +824,12 @@ static int ablk_perform(struct ablkciphe + struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); + struct ixp_ctx *ctx = crypto_ablkcipher_ctx(tfm); + unsigned ivsize = crypto_ablkcipher_ivsize(tfm); +- int ret = -ENOMEM; + struct ix_sa_dir *dir; + struct crypt_ctl *crypt; +- unsigned int nbytes = req->nbytes, nents; ++ unsigned int nbytes = req->nbytes; + enum dma_data_direction src_direction = DMA_BIDIRECTIONAL; + struct ablk_ctx *req_ctx = ablkcipher_request_ctx(req); ++ struct buffer_desc src_hook; + gfp_t flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ? + GFP_KERNEL : GFP_ATOMIC; + +@@ -876,7 +842,7 @@ static int ablk_perform(struct ablkciphe + + crypt = get_crypt_desc(); + if (!crypt) +- return ret; ++ return -ENOMEM; + + crypt->data.ablk_req = req; + crypt->crypto_ctx = dir->npe_ctx_phys; +@@ -889,53 +855,41 @@ static int ablk_perform(struct ablkciphe + BUG_ON(ivsize && !req->info); + memcpy(crypt->iv, req->info, ivsize); + if (req->src != req->dst) { ++ struct buffer_desc dst_hook; + crypt->mode |= NPE_OP_NOT_IN_PLACE; +- nents = count_sg(req->dst, nbytes); + /* This was never tested by Intel + * for more than one dst buffer, I think. */ +- BUG_ON(nents != 1); +- req_ctx->dst_nents = nents; +- dma_map_sg(dev, req->dst, nents, DMA_FROM_DEVICE); +- req_ctx->dst = dma_pool_alloc(buffer_pool, flags,&crypt->dst_buf); +- if (!req_ctx->dst) +- goto unmap_sg_dest; +- req_ctx->dst->phys_addr = 0; +- if (!chainup_buffers(req->dst, nbytes, req_ctx->dst, flags)) ++ BUG_ON(req->dst->length < nbytes); ++ req_ctx->dst = NULL; ++ if (!chainup_buffers(dev, req->dst, nbytes, &dst_hook, ++ flags, DMA_FROM_DEVICE)) + goto free_buf_dest; + src_direction = DMA_TO_DEVICE; ++ req_ctx->dst = dst_hook.next; ++ crypt->dst_buf = dst_hook.phys_next; + } else { + req_ctx->dst = NULL; +- req_ctx->dst_nents = 0; + } +- nents = count_sg(req->src, nbytes); +- req_ctx->src_nents = nents; +- dma_map_sg(dev, req->src, nents, src_direction); +- +- req_ctx->src = dma_pool_alloc(buffer_pool, flags, &crypt->src_buf); +- if (!req_ctx->src) +- goto unmap_sg_src; +- req_ctx->src->phys_addr = 0; +- if (!chainup_buffers(req->src, nbytes, req_ctx->src, flags)) ++ req_ctx->src = NULL; ++ if (!chainup_buffers(dev, req->src, nbytes, &src_hook, ++ flags, src_direction)) + goto free_buf_src; + ++ req_ctx->src = src_hook.next; ++ crypt->src_buf = src_hook.phys_next; + crypt->ctl_flags |= CTL_FLAG_PERFORM_ABLK; + qmgr_put_entry(SEND_QID, crypt_virt2phys(crypt)); + BUG_ON(qmgr_stat_overflow(SEND_QID)); + return -EINPROGRESS; + + free_buf_src: +- free_buf_chain(req_ctx->src, crypt->src_buf); +-unmap_sg_src: +- dma_unmap_sg(dev, req->src, req_ctx->src_nents, src_direction); ++ free_buf_chain(dev, req_ctx->src, crypt->src_buf); + free_buf_dest: + if (req->src != req->dst) { +- free_buf_chain(req_ctx->dst, crypt->dst_buf); +-unmap_sg_dest: +- dma_unmap_sg(dev, req->src, req_ctx->dst_nents, +- DMA_FROM_DEVICE); ++ free_buf_chain(dev, req_ctx->dst, crypt->dst_buf); + } + crypt->ctl_flags = CTL_FLAG_UNUSED; +- return ret; ++ return -ENOMEM; + } + + static int ablk_encrypt(struct ablkcipher_request *req) +@@ -983,7 +937,7 @@ static int hmac_inconsistent(struct scat + break; + + offset += sg->length; +- sg = sg_next(sg); ++ sg = scatterwalk_sg_next(sg); + } + return (start + nbytes > offset + sg->length); + } +@@ -995,11 +949,10 @@ static int aead_perform(struct aead_requ + struct ixp_ctx *ctx = crypto_aead_ctx(tfm); + unsigned ivsize = crypto_aead_ivsize(tfm); + unsigned authsize = crypto_aead_authsize(tfm); +- int ret = -ENOMEM; + struct ix_sa_dir *dir; + struct crypt_ctl *crypt; +- unsigned int cryptlen, nents; +- struct buffer_desc *buf; ++ unsigned int cryptlen; ++ struct buffer_desc *buf, src_hook; + struct aead_ctx *req_ctx = aead_request_ctx(req); + gfp_t flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ? + GFP_KERNEL : GFP_ATOMIC; +@@ -1020,7 +973,7 @@ static int aead_perform(struct aead_requ + } + crypt = get_crypt_desc(); + if (!crypt) +- return ret; ++ return -ENOMEM; + + crypt->data.aead_req = req; + crypt->crypto_ctx = dir->npe_ctx_phys; +@@ -1039,31 +992,27 @@ static int aead_perform(struct aead_requ + BUG(); /* -ENOTSUP because of my lazyness */ + } + +- req_ctx->buffer = dma_pool_alloc(buffer_pool, flags, &crypt->src_buf); +- if (!req_ctx->buffer) +- goto out; +- req_ctx->buffer->phys_addr = 0; + /* ASSOC data */ +- nents = count_sg(req->assoc, req->assoclen); +- req_ctx->assoc_nents = nents; +- dma_map_sg(dev, req->assoc, nents, DMA_TO_DEVICE); +- buf = chainup_buffers(req->assoc, req->assoclen, req_ctx->buffer,flags); ++ buf = chainup_buffers(dev, req->assoc, req->assoclen, &src_hook, ++ flags, DMA_TO_DEVICE); ++ req_ctx->buffer = src_hook.next; ++ crypt->src_buf = src_hook.phys_next; + if (!buf) +- goto unmap_sg_assoc; ++ goto out; + /* IV */ + sg_init_table(&req_ctx->ivlist, 1); + sg_set_buf(&req_ctx->ivlist, iv, ivsize); +- dma_map_sg(dev, &req_ctx->ivlist, 1, DMA_BIDIRECTIONAL); +- buf = chainup_buffers(&req_ctx->ivlist, ivsize, buf, flags); ++ buf = chainup_buffers(dev, &req_ctx->ivlist, ivsize, buf, flags, ++ DMA_BIDIRECTIONAL); + if (!buf) +- goto unmap_sg_iv; ++ goto free_chain; + if (unlikely(hmac_inconsistent(req->src, cryptlen, authsize))) { + /* The 12 hmac bytes are scattered, + * we need to copy them into a safe buffer */ + req_ctx->hmac_virt = dma_pool_alloc(buffer_pool, flags, + &crypt->icv_rev_aes); + if (unlikely(!req_ctx->hmac_virt)) +- goto unmap_sg_iv; ++ goto free_chain; + if (!encrypt) { + scatterwalk_map_and_copy(req_ctx->hmac_virt, + req->src, cryptlen, authsize, 0); +@@ -1073,33 +1022,28 @@ static int aead_perform(struct aead_requ + req_ctx->hmac_virt = NULL; + } + /* Crypt */ +- nents = count_sg(req->src, cryptlen + authsize); +- req_ctx->src_nents = nents; +- dma_map_sg(dev, req->src, nents, DMA_BIDIRECTIONAL); +- buf = chainup_buffers(req->src, cryptlen + authsize, buf, flags); ++ buf = chainup_buffers(dev, req->src, cryptlen + authsize, buf, flags, ++ DMA_BIDIRECTIONAL); + if (!buf) +- goto unmap_sg_src; ++ goto free_hmac_virt; + if (!req_ctx->hmac_virt) { + crypt->icv_rev_aes = buf->phys_addr + buf->buf_len - authsize; + } ++ + crypt->ctl_flags |= CTL_FLAG_PERFORM_AEAD; + qmgr_put_entry(SEND_QID, crypt_virt2phys(crypt)); + BUG_ON(qmgr_stat_overflow(SEND_QID)); + return -EINPROGRESS; +-unmap_sg_src: +- dma_unmap_sg(dev, req->src, req_ctx->src_nents, DMA_BIDIRECTIONAL); ++free_hmac_virt: + if (req_ctx->hmac_virt) { + dma_pool_free(buffer_pool, req_ctx->hmac_virt, + crypt->icv_rev_aes); + } +-unmap_sg_iv: +- dma_unmap_sg(dev, &req_ctx->ivlist, 1, DMA_BIDIRECTIONAL); +-unmap_sg_assoc: +- dma_unmap_sg(dev, req->assoc, req_ctx->assoc_nents, DMA_TO_DEVICE); +- free_buf_chain(req_ctx->buffer, crypt->src_buf); ++free_chain: ++ free_buf_chain(dev, req_ctx->buffer, crypt->src_buf); + out: + crypt->ctl_flags = CTL_FLAG_UNUSED; +- return ret; ++ return -ENOMEM; + } + + static int aead_setup(struct crypto_aead *tfm, unsigned int authsize) diff --git a/queue-2.6.27/exit_notify-kill-the-wrong-capable-check.patch b/queue-2.6.27/exit_notify-kill-the-wrong-capable-check.patch new file mode 100644 index 00000000000..36f556d71d4 --- /dev/null +++ b/queue-2.6.27/exit_notify-kill-the-wrong-capable-check.patch @@ -0,0 +1,38 @@ +From 432870dab85a2f69dc417022646cb9a70acf7f94 Mon Sep 17 00:00:00 2001 +From: Oleg Nesterov +Date: Mon, 6 Apr 2009 16:16:02 +0200 +Subject: exit_notify: kill the wrong capable(CAP_KILL) check (CVE-2009-1337) + +From: Oleg Nesterov + +CVE-2009-1337 + +commit 432870dab85a2f69dc417022646cb9a70acf7f94 upstream. + +The CAP_KILL check in exit_notify() looks just wrong, kill it. + +Whatever logic we have to reset ->exit_signal, the malicious user +can bypass it if it execs the setuid application before exiting. + +Signed-off-by: Oleg Nesterov +Acked-by: Serge Hallyn +Acked-by: Roland McGrath +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/exit.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/kernel/exit.c ++++ b/kernel/exit.c +@@ -938,8 +938,7 @@ static void exit_notify(struct task_stru + */ + if (tsk->exit_signal != SIGCHLD && !task_detached(tsk) && + (tsk->parent_exec_id != tsk->real_parent->self_exec_id || +- tsk->self_exec_id != tsk->parent_exec_id) && +- !capable(CAP_KILL)) ++ tsk->self_exec_id != tsk->parent_exec_id)) + tsk->exit_signal = SIGCHLD; + + signal = tracehook_notify_death(tsk, &cookie, group_dead); diff --git a/queue-2.6.27/fix-ptrace-slowness.patch b/queue-2.6.27/fix-ptrace-slowness.patch new file mode 100644 index 00000000000..23a77524a24 --- /dev/null +++ b/queue-2.6.27/fix-ptrace-slowness.patch @@ -0,0 +1,63 @@ +From 53da1d9456fe7f87a920a78fdbdcf1225d197cb7 Mon Sep 17 00:00:00 2001 +From: Miklos Szeredi +Date: Mon, 23 Mar 2009 16:07:24 +0100 +Subject: fix ptrace slowness + +From: Miklos Szeredi + +commit 53da1d9456fe7f87a920a78fdbdcf1225d197cb7 upstream. + +This patch fixes bug #12208: + + Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=12208 + Subject : uml is very slow on 2.6.28 host + +This turned out to be not a scheduler regression, but an already +existing problem in ptrace being triggered by subtle scheduler +changes. + +The problem is this: + + - task A is ptracing task B + - task B stops on a trace event + - task A is woken up and preempts task B + - task A calls ptrace on task B, which does ptrace_check_attach() + - this calls wait_task_inactive(), which sees that task B is still on the runq + - task A goes to sleep for a jiffy + - ... + +Since UML does lots of the above sequences, those jiffies quickly add +up to make it slow as hell. + +This patch solves this by not rescheduling in read_unlock() after +ptrace_stop() has woken up the tracer. + +Thanks to Oleg Nesterov and Ingo Molnar for the feedback. + +Signed-off-by: Miklos Szeredi +CC: stable@kernel.org +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/signal.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/kernel/signal.c ++++ b/kernel/signal.c +@@ -1549,7 +1549,15 @@ static void ptrace_stop(int exit_code, i + read_lock(&tasklist_lock); + if (may_ptrace_stop()) { + do_notify_parent_cldstop(current, CLD_TRAPPED); ++ /* ++ * Don't want to allow preemption here, because ++ * sys_ptrace() needs this task to be inactive. ++ * ++ * XXX: implement read_unlock_no_resched(). ++ */ ++ preempt_disable(); + read_unlock(&tasklist_lock); ++ preempt_enable_no_resched(); + schedule(); + } else { + /* diff --git a/queue-2.6.27/fs-core-fixes.patch b/queue-2.6.27/fs-core-fixes.patch new file mode 100644 index 00000000000..4a130b877ca --- /dev/null +++ b/queue-2.6.27/fs-core-fixes.patch @@ -0,0 +1,210 @@ +From hugh@veritas.com Wed Apr 29 12:45:48 2009 +From: Hugh Dickins +Date: Sat, 25 Apr 2009 17:52:56 +0100 (BST) +Subject: fs core fixes +To: Chris Wright +Cc: Greg Kroah-Hartman , Oleg Nesterov , Joe Malicki , stable@kernel.org, David Howells , Al Viro , Andrew Morton , Linus Torvalds , Alexey Dobriyan , Roland McGrath +Message-ID: + +From: Hugh Dickins + +Please add the following 4 commits to 2.6.27-stable and 2.6.28-stable. +However, there has been a lot of change here between 2.6.28 and 2.6.29: +in particular, fs/exec.c's unsafe_exec() grew into the more complicated +check_unsafe_exec(). So applying the original patches gives too many +rejects: at the bottom is the diffstat and the combined patch required. + +1 +Commit: 53e9309e01277ec99c38e84e0ca16921287cf470 +Author: Hugh Dickins +Date: Sat, 28 Mar 2009 23:16:03 +0000 (+0000) +Subject: compat_do_execve should unshare_files + +2 +Commit: e426b64c412aaa3e9eb3e4b261dc5be0d5a83e78 +Author: Hugh Dickins +Date: Sat, 28 Mar 2009 23:20:19 +0000 (+0000) +Subject: fix setuid sometimes doesn't + +3 +Commit: 7c2c7d993044cddc5010f6f429b100c63bc7dffb +Author: Hugh Dickins +Date: Sat, 28 Mar 2009 23:21:27 +0000 (+0000) +Subject: fix setuid sometimes wouldn't + +4 +Commit: f1191b50ec11c8e2ca766d6d99eb5bb9d2c084a3 +Author: Al Viro +Date: Mon, 30 Mar 2009 11:35:18 +0000 (-0400) +Subject: check_unsafe_exec() doesn't care about signal handlers sharing + +Signed-off-by: Hugh Dickins +Signed-off-by: Greg Kroah-Hartman + +--- + fs/compat.c | 12 +++++++++++- + fs/exec.c | 4 +--- + fs/proc/base.c | 50 ++++++++++++++++---------------------------------- + 3 files changed, 28 insertions(+), 38 deletions(-) + +--- a/fs/compat.c ++++ b/fs/compat.c +@@ -1353,12 +1353,17 @@ int compat_do_execve(char * filename, + { + struct linux_binprm *bprm; + struct file *file; ++ struct files_struct *displaced; + int retval; + ++ retval = unshare_files(&displaced); ++ if (retval) ++ goto out_ret; ++ + retval = -ENOMEM; + bprm = kzalloc(sizeof(*bprm), GFP_KERNEL); + if (!bprm) +- goto out_ret; ++ goto out_files; + + file = open_exec(filename); + retval = PTR_ERR(file); +@@ -1410,6 +1415,8 @@ int compat_do_execve(char * filename, + security_bprm_free(bprm); + acct_update_integrals(current); + free_bprm(bprm); ++ if (displaced) ++ put_files_struct(displaced); + return retval; + } + +@@ -1430,6 +1437,9 @@ out_file: + out_kfree: + free_bprm(bprm); + ++out_files: ++ if (displaced) ++ reset_files_struct(displaced); + out_ret: + return retval; + } +--- a/fs/exec.c ++++ b/fs/exec.c +@@ -1089,9 +1089,7 @@ static int unsafe_exec(struct task_struc + { + int unsafe = tracehook_unsafe_exec(p); + +- if (atomic_read(&p->fs->count) > 1 || +- atomic_read(&p->files->count) > 1 || +- atomic_read(&p->sighand->count) > 1) ++ if (atomic_read(&p->fs->count) > 1) + unsafe |= LSM_UNSAFE_SHARE; + + return unsafe; +--- a/fs/proc/base.c ++++ b/fs/proc/base.c +@@ -151,15 +151,22 @@ static unsigned int pid_entry_count_dirs + int maps_protect; + EXPORT_SYMBOL(maps_protect); + +-static struct fs_struct *get_fs_struct(struct task_struct *task) ++static int get_fs_path(struct task_struct *task, struct path *path, bool root) + { + struct fs_struct *fs; ++ int result = -ENOENT; ++ + task_lock(task); + fs = task->fs; +- if(fs) +- atomic_inc(&fs->count); ++ if (fs) { ++ read_lock(&fs->lock); ++ *path = root ? fs->root : fs->pwd; ++ path_get(path); ++ read_unlock(&fs->lock); ++ result = 0; ++ } + task_unlock(task); +- return fs; ++ return result; + } + + static int get_nr_threads(struct task_struct *tsk) +@@ -178,42 +185,24 @@ static int get_nr_threads(struct task_st + static int proc_cwd_link(struct inode *inode, struct path *path) + { + struct task_struct *task = get_proc_task(inode); +- struct fs_struct *fs = NULL; + int result = -ENOENT; + + if (task) { +- fs = get_fs_struct(task); ++ result = get_fs_path(task, path, 0); + put_task_struct(task); + } +- if (fs) { +- read_lock(&fs->lock); +- *path = fs->pwd; +- path_get(&fs->pwd); +- read_unlock(&fs->lock); +- result = 0; +- put_fs_struct(fs); +- } + return result; + } + + static int proc_root_link(struct inode *inode, struct path *path) + { + struct task_struct *task = get_proc_task(inode); +- struct fs_struct *fs = NULL; + int result = -ENOENT; + + if (task) { +- fs = get_fs_struct(task); ++ result = get_fs_path(task, path, 1); + put_task_struct(task); + } +- if (fs) { +- read_lock(&fs->lock); +- *path = fs->root; +- path_get(&fs->root); +- read_unlock(&fs->lock); +- result = 0; +- put_fs_struct(fs); +- } + return result; + } + +@@ -575,7 +564,6 @@ static int mounts_open_common(struct ino + struct task_struct *task = get_proc_task(inode); + struct nsproxy *nsp; + struct mnt_namespace *ns = NULL; +- struct fs_struct *fs = NULL; + struct path root; + struct proc_mounts *p; + int ret = -EINVAL; +@@ -589,22 +577,16 @@ static int mounts_open_common(struct ino + get_mnt_ns(ns); + } + rcu_read_unlock(); +- if (ns) +- fs = get_fs_struct(task); ++ if (ns && get_fs_path(task, &root, 1) == 0) ++ ret = 0; + put_task_struct(task); + } + + if (!ns) + goto err; +- if (!fs) ++ if (ret) + goto err_put_ns; + +- read_lock(&fs->lock); +- root = fs->root; +- path_get(&root); +- read_unlock(&fs->lock); +- put_fs_struct(fs); +- + ret = -ENOMEM; + p = kmalloc(sizeof(struct proc_mounts), GFP_KERNEL); + if (!p) diff --git a/queue-2.6.27/pci-fix-incorrect-mask-of-pm-no_soft_reset-bit.patch b/queue-2.6.27/pci-fix-incorrect-mask-of-pm-no_soft_reset-bit.patch new file mode 100644 index 00000000000..5016a48688f --- /dev/null +++ b/queue-2.6.27/pci-fix-incorrect-mask-of-pm-no_soft_reset-bit.patch @@ -0,0 +1,29 @@ +From 998dd7c719f62dcfa91d7bf7f4eb9c160e03d817 Mon Sep 17 00:00:00 2001 +From: Yu Zhao +Date: Wed, 25 Feb 2009 13:15:52 +0800 +Subject: PCI: fix incorrect mask of PM No_Soft_Reset bit + +From: Yu Zhao + +commit 998dd7c719f62dcfa91d7bf7f4eb9c160e03d817 upstream. + +Reviewed-by: Matthew Wilcox +Signed-off-by: Yu Zhao +Signed-off-by: Jesse Barnes +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/pci_regs.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/include/linux/pci_regs.h ++++ b/include/linux/pci_regs.h +@@ -234,7 +234,7 @@ + #define PCI_PM_CAP_PME_SHIFT 11 /* Start of the PME Mask in PMC */ + #define PCI_PM_CTRL 4 /* PM control and status register */ + #define PCI_PM_CTRL_STATE_MASK 0x0003 /* Current power state (D0 to D3) */ +-#define PCI_PM_CTRL_NO_SOFT_RESET 0x0004 /* No reset for D3hot->D0 */ ++#define PCI_PM_CTRL_NO_SOFT_RESET 0x0008 /* No reset for D3hot->D0 */ + #define PCI_PM_CTRL_PME_ENABLE 0x0100 /* PME pin enable */ + #define PCI_PM_CTRL_DATA_SEL_MASK 0x1e00 /* Data select (??) */ + #define PCI_PM_CTRL_DATA_SCALE_MASK 0x6000 /* Data scale (??) */ diff --git a/queue-2.6.27/series b/queue-2.6.27/series index dc9521a1367..bd10a4c8ce5 100644 --- a/queue-2.6.27/series +++ b/queue-2.6.27/series @@ -47,3 +47,12 @@ mm-check-for-no-mmaps-in-exit_mmap.patch powerpc-sanitize-stack-pointer-in-signal-handling-code.patch ath9k-implement-io-serialization.patch ath9k-ar9280-pci-devices-must-serialize-io-as-well.patch +b44-use-kernel-dma-addresses-for-the-kernel-dma-api.patch +crypto-ixp4xx-fix-handling-of-chained-sg-buffers.patch +exit_notify-kill-the-wrong-capable-check.patch +fix-ptrace-slowness.patch +fs-core-fixes.patch +pci-fix-incorrect-mask-of-pm-no_soft_reset-bit.patch +thinkpad-acpi-fix-led-blinking-through-timer-trigger.patch +acpi-ec-add-some-basic-check-for-ecdt-data.patch +acpi-ec-fix-compilation-warning.patch diff --git a/queue-2.6.27/thinkpad-acpi-fix-led-blinking-through-timer-trigger.patch b/queue-2.6.27/thinkpad-acpi-fix-led-blinking-through-timer-trigger.patch new file mode 100644 index 00000000000..2ecab4014ee --- /dev/null +++ b/queue-2.6.27/thinkpad-acpi-fix-led-blinking-through-timer-trigger.patch @@ -0,0 +1,132 @@ +From 75bd3bf2ade9d548be0d2bde60b5ee0fdce0b127 Mon Sep 17 00:00:00 2001 +From: Henrique de Moraes Holschuh +Date: Tue, 14 Apr 2009 02:44:11 +0000 +Subject: thinkpad-acpi: fix LED blinking through timer trigger + +From: Henrique de Moraes Holschuh + +commit 75bd3bf2ade9d548be0d2bde60b5ee0fdce0b127 upstream. + +The set_blink hook code in the LED subdriver would never manage to get +a LED to blink, and instead it would just turn it on. The consequence +of this is that the "timer" trigger would not cause the LED to blink +if given default parameters. + +This problem exists since 2.6.26-rc1. + +To fix it, switch the deferred LED work handling to use the +thinkpad-acpi-specific LED status (off/on/blink) directly. + +This also makes the code easier to read, and to extend later. + +Signed-off-by: Henrique de Moraes Holschuh +Cc: stable@kernel.org +Signed-off-by: Len Brown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/misc/thinkpad_acpi.c | 41 +++++++++++++++++++---------------------- + 1 file changed, 19 insertions(+), 22 deletions(-) + +--- a/drivers/misc/thinkpad_acpi.c ++++ b/drivers/misc/thinkpad_acpi.c +@@ -282,11 +282,17 @@ static u32 dbg_level; + + static struct workqueue_struct *tpacpi_wq; + ++enum led_status_t { ++ TPACPI_LED_OFF = 0, ++ TPACPI_LED_ON, ++ TPACPI_LED_BLINK, ++}; ++ + /* Special LED class that can defer work */ + struct tpacpi_led_classdev { + struct led_classdev led_classdev; + struct work_struct work; +- enum led_brightness new_brightness; ++ enum led_status_t new_state; + unsigned int led; + }; + +@@ -3478,7 +3484,7 @@ static void light_set_status_worker(stru + container_of(work, struct tpacpi_led_classdev, work); + + if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING)) +- light_set_status((data->new_brightness != LED_OFF)); ++ light_set_status((data->new_state != TPACPI_LED_OFF)); + } + + static void light_sysfs_set(struct led_classdev *led_cdev, +@@ -3488,7 +3494,8 @@ static void light_sysfs_set(struct led_c + container_of(led_cdev, + struct tpacpi_led_classdev, + led_classdev); +- data->new_brightness = brightness; ++ data->new_state = (brightness != LED_OFF) ? ++ TPACPI_LED_ON : TPACPI_LED_OFF; + queue_work(tpacpi_wq, &data->work); + } + +@@ -3995,12 +4002,6 @@ enum { /* For TPACPI_LED_OLD */ + TPACPI_LED_EC_HLMS = 0x0e, /* EC reg to select led to command */ + }; + +-enum led_status_t { +- TPACPI_LED_OFF = 0, +- TPACPI_LED_ON, +- TPACPI_LED_BLINK, +-}; +- + static enum led_access_mode led_supported; + + TPACPI_HANDLE(led, ec, "SLED", /* 570 */ +@@ -4094,23 +4095,13 @@ static int led_set_status(const unsigned + return rc; + } + +-static void led_sysfs_set_status(unsigned int led, +- enum led_brightness brightness) +-{ +- led_set_status(led, +- (brightness == LED_OFF) ? +- TPACPI_LED_OFF : +- (tpacpi_led_state_cache[led] == TPACPI_LED_BLINK) ? +- TPACPI_LED_BLINK : TPACPI_LED_ON); +-} +- + static void led_set_status_worker(struct work_struct *work) + { + struct tpacpi_led_classdev *data = + container_of(work, struct tpacpi_led_classdev, work); + + if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING)) +- led_sysfs_set_status(data->led, data->new_brightness); ++ led_set_status(data->led, data->new_state); + } + + static void led_sysfs_set(struct led_classdev *led_cdev, +@@ -4119,7 +4110,13 @@ static void led_sysfs_set(struct led_cla + struct tpacpi_led_classdev *data = container_of(led_cdev, + struct tpacpi_led_classdev, led_classdev); + +- data->new_brightness = brightness; ++ if (brightness == LED_OFF) ++ data->new_state = TPACPI_LED_OFF; ++ else if (tpacpi_led_state_cache[data->led] != TPACPI_LED_BLINK) ++ data->new_state = TPACPI_LED_ON; ++ else ++ data->new_state = TPACPI_LED_BLINK; ++ + queue_work(tpacpi_wq, &data->work); + } + +@@ -4137,7 +4134,7 @@ static int led_sysfs_blink_set(struct le + } else if ((*delay_on != 500) || (*delay_off != 500)) + return -EINVAL; + +- data->new_brightness = TPACPI_LED_BLINK; ++ data->new_state = TPACPI_LED_BLINK; + queue_work(tpacpi_wq, &data->work); + + return 0;