--- /dev/null
+From c5279dee26c0e8d7c4200993bfc4b540d2469598 Mon Sep 17 00:00:00 2001
+From: Alexey Starikovskiy <astarikovskiy@suse.de>
+Date: Wed, 26 Nov 2008 17:11:53 -0500
+Subject: ACPI: EC: Add some basic check for ECDT data
+
+From: Alexey Starikovskiy <astarikovskiy@suse.de>
+
+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 <astarikovskiy@suse.de>
+Signed-off-by: Len Brown <len.brown@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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;
--- /dev/null
+From 3e54048691bce3f323fd5460695273be379803b9 Mon Sep 17 00:00:00 2001
+From: Hannes Eder <hannes@hanneseder.net>
+Date: Sat, 29 Nov 2008 07:21:29 +0100
+Subject: ACPI: EC: fix compilation warning
+
+From: Hannes Eder <hannes@hanneseder.net>
+
+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 <hannes@hanneseder.net>
+Acked-by: Alexey Starikovskiy <astarikovskiy@suse.de>
+Signed-off-by: Len Brown <len.brown@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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)) {
--- /dev/null
+From 37efa239901493694a48f1d6f59f8de17c2c4509 Mon Sep 17 00:00:00 2001
+From: Michael Buesch <mb@bu3sch.de>
+Date: Mon, 6 Apr 2009 09:52:27 +0000
+Subject: b44: Use kernel DMA addresses for the kernel DMA API
+
+From: Michael Buesch <mb@bu3sch.de>
+
+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 <mb@bu3sch.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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);
+ }
--- /dev/null
+From 0d44dc59b2b434b29aafeae581d06f81efac7c83 Mon Sep 17 00:00:00 2001
+From: Christian Hohnstaedt <chohnstaedt@innominate.com>
+Date: Fri, 27 Mar 2009 15:09:05 +0800
+Subject: crypto: ixp4xx - Fix handling of chained sg buffers
+
+From: Christian Hohnstaedt <chohnstaedt@innominate.com>
+
+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 <chohnstaedt@innominate.com>
+Tested-By: Karl Hiramoto <karl@hiramoto.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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)
--- /dev/null
+From 432870dab85a2f69dc417022646cb9a70acf7f94 Mon Sep 17 00:00:00 2001
+From: Oleg Nesterov <oleg@redhat.com>
+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 <oleg@redhat.com>
+
+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 <oleg@redhat.com>
+Acked-by: Serge Hallyn <serue@us.ibm.com>
+Acked-by: Roland McGrath <roland@redhat.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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);
--- /dev/null
+From 53da1d9456fe7f87a920a78fdbdcf1225d197cb7 Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@suse.cz>
+Date: Mon, 23 Mar 2009 16:07:24 +0100
+Subject: fix ptrace slowness
+
+From: Miklos Szeredi <mszeredi@suse.cz>
+
+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 <mszeredi@suse.cz>
+CC: stable@kernel.org
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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 {
+ /*
--- /dev/null
+From hugh@veritas.com Wed Apr 29 12:45:48 2009
+From: Hugh Dickins <hugh@veritas.com>
+Date: Sat, 25 Apr 2009 17:52:56 +0100 (BST)
+Subject: fs core fixes
+To: Chris Wright <chrisw@sous-sol.org>
+Cc: Greg Kroah-Hartman <gregkh@suse.de>, Oleg Nesterov <oleg@redhat.com>, Joe Malicki <jmalicki@metatcarta.com>, stable@kernel.org, David Howells <dhowells@redhat.com>, Al Viro <viro@zeniv.linux.org.uk>, Andrew Morton <akpm@linux-foundation.org>, Linus Torvalds <torvalds@linux-foundation.org>, Alexey Dobriyan <adobriyan@gmail.com>, Roland McGrath <roland@redhat.com>
+Message-ID: <Pine.LNX.4.64.0904251751200.2298@blonde.anvils>
+
+From: Hugh Dickins <hugh@veritas.com>
+
+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 <hugh@veritas.com>
+Date: Sat, 28 Mar 2009 23:16:03 +0000 (+0000)
+Subject: compat_do_execve should unshare_files
+
+2
+Commit: e426b64c412aaa3e9eb3e4b261dc5be0d5a83e78
+Author: Hugh Dickins <hugh@veritas.com>
+Date: Sat, 28 Mar 2009 23:20:19 +0000 (+0000)
+Subject: fix setuid sometimes doesn't
+
+3
+Commit: 7c2c7d993044cddc5010f6f429b100c63bc7dffb
+Author: Hugh Dickins <hugh@veritas.com>
+Date: Sat, 28 Mar 2009 23:21:27 +0000 (+0000)
+Subject: fix setuid sometimes wouldn't
+
+4
+Commit: f1191b50ec11c8e2ca766d6d99eb5bb9d2c084a3
+Author: Al Viro <viro@zeniv.linux.org.uk>
+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 <hugh@veritas.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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)
--- /dev/null
+From 998dd7c719f62dcfa91d7bf7f4eb9c160e03d817 Mon Sep 17 00:00:00 2001
+From: Yu Zhao <yu.zhao@intel.com>
+Date: Wed, 25 Feb 2009 13:15:52 +0800
+Subject: PCI: fix incorrect mask of PM No_Soft_Reset bit
+
+From: Yu Zhao <yu.zhao@intel.com>
+
+commit 998dd7c719f62dcfa91d7bf7f4eb9c160e03d817 upstream.
+
+Reviewed-by: Matthew Wilcox <matthew@wil.cx>
+Signed-off-by: Yu Zhao <yu.zhao@intel.com>
+Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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 (??) */
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
--- /dev/null
+From 75bd3bf2ade9d548be0d2bde60b5ee0fdce0b127 Mon Sep 17 00:00:00 2001
+From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
+Date: Tue, 14 Apr 2009 02:44:11 +0000
+Subject: thinkpad-acpi: fix LED blinking through timer trigger
+
+From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
+
+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 <hmh@hmh.eng.br>
+Cc: stable@kernel.org
+Signed-off-by: Len Brown <len.brown@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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;