From: Greg Kroah-Hartman Date: Wed, 16 Dec 2009 00:53:48 +0000 (-0800) Subject: .32 patches X-Git-Tag: v2.6.27.42~18 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0c52b71a948fa8c873651c2e1c3fa53aa5cec55d;p=thirdparty%2Fkernel%2Fstable-queue.git .32 patches --- diff --git a/queue-2.6.32/dm-avoid-_hash_lock-deadlock.patch b/queue-2.6.32/dm-avoid-_hash_lock-deadlock.patch new file mode 100644 index 00000000000..61f8df046df --- /dev/null +++ b/queue-2.6.32/dm-avoid-_hash_lock-deadlock.patch @@ -0,0 +1,134 @@ +From 6076905b5ef39e0ea58db32583c9e0036c05e47b Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Thu, 10 Dec 2009 23:51:52 +0000 +Subject: dm: avoid _hash_lock deadlock + +From: Mikulas Patocka + +commit 6076905b5ef39e0ea58db32583c9e0036c05e47b upstream. + +Fix a reported deadlock if there are still unprocessed multipath events +on a device that is being removed. + +_hash_lock is held during dev_remove while trying to send the +outstanding events. Sending the events requests the _hash_lock +again in dm_copy_name_and_uuid. + +This patch introduces a separate lock around regions that modify the +link to the hash table (dm_set_mdptr) or the name or uuid so that +dm_copy_name_and_uuid no longer needs _hash_lock. + +Additionally, dm_copy_name_and_uuid can only be called if md exists +so we can drop the dm_get() and dm_put() which can lead to a BUG() +while md is being freed. + +The deadlock: + #0 [ffff8106298dfb48] schedule at ffffffff80063035 + #1 [ffff8106298dfc20] __down_read at ffffffff8006475d + #2 [ffff8106298dfc60] dm_copy_name_and_uuid at ffffffff8824f740 + #3 [ffff8106298dfc90] dm_send_uevents at ffffffff88252685 + #4 [ffff8106298dfcd0] event_callback at ffffffff8824c678 + #5 [ffff8106298dfd00] dm_table_event at ffffffff8824dd01 + #6 [ffff8106298dfd10] __hash_remove at ffffffff882507ad + #7 [ffff8106298dfd30] dev_remove at ffffffff88250865 + #8 [ffff8106298dfd60] ctl_ioctl at ffffffff88250d80 + #9 [ffff8106298dfee0] do_ioctl at ffffffff800418c4 +#10 [ffff8106298dff00] vfs_ioctl at ffffffff8002fab9 +#11 [ffff8106298dff40] sys_ioctl at ffffffff8004bdaf +#12 [ffff8106298dff80] tracesys at ffffffff8005d28d (via system_call) + +Reported-by: guy keren +Signed-off-by: Mikulas Patocka +Signed-off-by: Alasdair G Kergon +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-ioctl.c | 17 +++++++++++++---- + drivers/md/dm-uevent.c | 9 ++++----- + 2 files changed, 17 insertions(+), 9 deletions(-) + +--- a/drivers/md/dm-ioctl.c ++++ b/drivers/md/dm-ioctl.c +@@ -56,6 +56,11 @@ static void dm_hash_remove_all(int keep_ + */ + static DECLARE_RWSEM(_hash_lock); + ++/* ++ * Protects use of mdptr to obtain hash cell name and uuid from mapped device. ++ */ ++static DEFINE_MUTEX(dm_hash_cells_mutex); ++ + static void init_buckets(struct list_head *buckets) + { + unsigned int i; +@@ -206,7 +211,9 @@ static int dm_hash_insert(const char *na + list_add(&cell->uuid_list, _uuid_buckets + hash_str(uuid)); + } + dm_get(md); ++ mutex_lock(&dm_hash_cells_mutex); + dm_set_mdptr(md, cell); ++ mutex_unlock(&dm_hash_cells_mutex); + up_write(&_hash_lock); + + return 0; +@@ -224,7 +231,9 @@ static void __hash_remove(struct hash_ce + /* remove from the dev hash */ + list_del(&hc->uuid_list); + list_del(&hc->name_list); ++ mutex_lock(&dm_hash_cells_mutex); + dm_set_mdptr(hc->md, NULL); ++ mutex_unlock(&dm_hash_cells_mutex); + + table = dm_get_table(hc->md); + if (table) { +@@ -321,7 +330,9 @@ static int dm_hash_rename(uint32_t cooki + */ + list_del(&hc->name_list); + old_name = hc->name; ++ mutex_lock(&dm_hash_cells_mutex); + hc->name = new_name; ++ mutex_unlock(&dm_hash_cells_mutex); + list_add(&hc->name_list, _name_buckets + hash_str(new_name)); + + /* +@@ -1582,8 +1593,7 @@ int dm_copy_name_and_uuid(struct mapped_ + if (!md) + return -ENXIO; + +- dm_get(md); +- down_read(&_hash_lock); ++ mutex_lock(&dm_hash_cells_mutex); + hc = dm_get_mdptr(md); + if (!hc || hc->md != md) { + r = -ENXIO; +@@ -1596,8 +1606,7 @@ int dm_copy_name_and_uuid(struct mapped_ + strcpy(uuid, hc->uuid ? : ""); + + out: +- up_read(&_hash_lock); +- dm_put(md); ++ mutex_unlock(&dm_hash_cells_mutex); + + return r; + } +--- a/drivers/md/dm-uevent.c ++++ b/drivers/md/dm-uevent.c +@@ -139,14 +139,13 @@ void dm_send_uevents(struct list_head *e + list_del_init(&event->elist); + + /* +- * Need to call dm_copy_name_and_uuid from here for now. +- * Context of previous var adds and locking used for +- * hash_cell not compatable. ++ * When a device is being removed this copy fails and we ++ * discard these unsent events. + */ + if (dm_copy_name_and_uuid(event->md, event->name, + event->uuid)) { +- DMERR("%s: dm_copy_name_and_uuid() failed", +- __func__); ++ DMINFO("%s: skipping sending uevent for lost device", ++ __func__); + goto uevent_free; + } + diff --git a/queue-2.6.32/dm-crypt-make-wipe-message-also-wipe-essiv-key.patch b/queue-2.6.32/dm-crypt-make-wipe-message-also-wipe-essiv-key.patch new file mode 100644 index 00000000000..76f28d87599 --- /dev/null +++ b/queue-2.6.32/dm-crypt-make-wipe-message-also-wipe-essiv-key.patch @@ -0,0 +1,107 @@ +From 542da317668c35036e8471822a564b609d05af66 Mon Sep 17 00:00:00 2001 +From: Milan Broz +Date: Thu, 10 Dec 2009 23:51:57 +0000 +Subject: dm crypt: make wipe message also wipe essiv key + +From: Milan Broz + +commit 542da317668c35036e8471822a564b609d05af66 upstream. + +The "wipe key" message is used to wipe the volume key from memory +temporarily, for example when suspending to RAM. + +But the initialisation vector in ESSIV mode is calculated from the +hashed volume key, so the wipe message should wipe this IV key too and +reinitialise it when the volume key is reinstated. + +This patch adds an IV wipe method called from a wipe message callback. +ESSIV is then reinitialised using the init function added by the +last patch. + +Signed-off-by: Milan Broz +Signed-off-by: Alasdair G Kergon +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-crypt.c | 34 ++++++++++++++++++++++++++++++---- + 1 file changed, 30 insertions(+), 4 deletions(-) + +--- a/drivers/md/dm-crypt.c ++++ b/drivers/md/dm-crypt.c +@@ -1,7 +1,7 @@ + /* + * Copyright (C) 2003 Christophe Saout + * Copyright (C) 2004 Clemens Fruhwirth +- * Copyright (C) 2006-2008 Red Hat, Inc. All rights reserved. ++ * Copyright (C) 2006-2009 Red Hat, Inc. All rights reserved. + * + * This file is released under the GPL. + */ +@@ -72,6 +72,7 @@ struct crypt_iv_operations { + const char *opts); + void (*dtr)(struct crypt_config *cc); + int (*init)(struct crypt_config *cc); ++ int (*wipe)(struct crypt_config *cc); + int (*generator)(struct crypt_config *cc, u8 *iv, sector_t sector); + }; + +@@ -199,6 +200,17 @@ static int crypt_iv_essiv_init(struct cr + crypto_hash_digestsize(essiv->hash_tfm)); + } + ++/* Wipe salt and reset key derived from volume key */ ++static int crypt_iv_essiv_wipe(struct crypt_config *cc) ++{ ++ struct iv_essiv_private *essiv = &cc->iv_gen_private.essiv; ++ unsigned salt_size = crypto_hash_digestsize(essiv->hash_tfm); ++ ++ memset(essiv->salt, 0, salt_size); ++ ++ return crypto_cipher_setkey(essiv->tfm, essiv->salt, salt_size); ++} ++ + static void crypt_iv_essiv_dtr(struct crypt_config *cc) + { + struct iv_essiv_private *essiv = &cc->iv_gen_private.essiv; +@@ -334,6 +346,7 @@ static struct crypt_iv_operations crypt_ + .ctr = crypt_iv_essiv_ctr, + .dtr = crypt_iv_essiv_dtr, + .init = crypt_iv_essiv_init, ++ .wipe = crypt_iv_essiv_wipe, + .generator = crypt_iv_essiv_gen + }; + +@@ -1310,6 +1323,7 @@ static void crypt_resume(struct dm_targe + static int crypt_message(struct dm_target *ti, unsigned argc, char **argv) + { + struct crypt_config *cc = ti->private; ++ int ret = -EINVAL; + + if (argc < 2) + goto error; +@@ -1319,10 +1333,22 @@ static int crypt_message(struct dm_targe + DMWARN("not suspended during key manipulation."); + return -EINVAL; + } +- if (argc == 3 && !strnicmp(argv[1], MESG_STR("set"))) +- return crypt_set_key(cc, argv[2]); +- if (argc == 2 && !strnicmp(argv[1], MESG_STR("wipe"))) ++ if (argc == 3 && !strnicmp(argv[1], MESG_STR("set"))) { ++ ret = crypt_set_key(cc, argv[2]); ++ if (ret) ++ return ret; ++ if (cc->iv_gen_ops && cc->iv_gen_ops->init) ++ ret = cc->iv_gen_ops->init(cc); ++ return ret; ++ } ++ if (argc == 2 && !strnicmp(argv[1], MESG_STR("wipe"))) { ++ if (cc->iv_gen_ops && cc->iv_gen_ops->wipe) { ++ ret = cc->iv_gen_ops->wipe(cc); ++ if (ret) ++ return ret; ++ } + return crypt_wipe_key(cc); ++ } + } + + error: diff --git a/queue-2.6.32/dm-crypt-move-private-iv-fields-to-structs.patch b/queue-2.6.32/dm-crypt-move-private-iv-fields-to-structs.patch new file mode 100644 index 00000000000..4163259a034 --- /dev/null +++ b/queue-2.6.32/dm-crypt-move-private-iv-fields-to-structs.patch @@ -0,0 +1,113 @@ +From 6047359277517c4e56d8bfd6ea4966d7a3924151 Mon Sep 17 00:00:00 2001 +From: Milan Broz +Date: Thu, 10 Dec 2009 23:51:55 +0000 +Subject: dm crypt: move private iv fields to structs + +From: Milan Broz + +commit 6047359277517c4e56d8bfd6ea4966d7a3924151 upstream. + +Define private structures for IV so it's easy to add further attributes +in a following patch which fixes the way key material is wiped from +memory. Also move ESSIV destructor and remove unnecessary 'status' +operation. + +There are no functional changes in this patch. + +Signed-off-by: Milan Broz +Signed-off-by: Alasdair G Kergon +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-crypt.c | 35 ++++++++++++++++++++++------------- + 1 file changed, 22 insertions(+), 13 deletions(-) + +--- a/drivers/md/dm-crypt.c ++++ b/drivers/md/dm-crypt.c +@@ -71,10 +71,17 @@ struct crypt_iv_operations { + int (*ctr)(struct crypt_config *cc, struct dm_target *ti, + const char *opts); + void (*dtr)(struct crypt_config *cc); +- const char *(*status)(struct crypt_config *cc); + int (*generator)(struct crypt_config *cc, u8 *iv, sector_t sector); + }; + ++struct iv_essiv_private { ++ struct crypto_cipher *tfm; ++}; ++ ++struct iv_benbi_private { ++ int shift; ++}; ++ + /* + * Crypt: maps a linear range of a block device + * and encrypts / decrypts at the same time. +@@ -102,8 +109,8 @@ struct crypt_config { + struct crypt_iv_operations *iv_gen_ops; + char *iv_mode; + union { +- struct crypto_cipher *essiv_tfm; +- int benbi_shift; ++ struct iv_essiv_private essiv; ++ struct iv_benbi_private benbi; + } iv_gen_private; + sector_t iv_offset; + unsigned int iv_size; +@@ -169,6 +176,14 @@ static int crypt_iv_plain_gen(struct cry + return 0; + } + ++static void crypt_iv_essiv_dtr(struct crypt_config *cc) ++{ ++ struct iv_essiv_private *essiv = &cc->iv_gen_private.essiv; ++ ++ crypto_free_cipher(essiv->tfm); ++ essiv->tfm = NULL; ++} ++ + static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti, + const char *opts) + { +@@ -236,21 +251,15 @@ static int crypt_iv_essiv_ctr(struct cry + } + kfree(salt); + +- cc->iv_gen_private.essiv_tfm = essiv_tfm; ++ cc->iv_gen_private.essiv.tfm = essiv_tfm; + return 0; + } + +-static void crypt_iv_essiv_dtr(struct crypt_config *cc) +-{ +- crypto_free_cipher(cc->iv_gen_private.essiv_tfm); +- cc->iv_gen_private.essiv_tfm = NULL; +-} +- + static int crypt_iv_essiv_gen(struct crypt_config *cc, u8 *iv, sector_t sector) + { + memset(iv, 0, cc->iv_size); + *(u64 *)iv = cpu_to_le64(sector); +- crypto_cipher_encrypt_one(cc->iv_gen_private.essiv_tfm, iv, iv); ++ crypto_cipher_encrypt_one(cc->iv_gen_private.essiv.tfm, iv, iv); + return 0; + } + +@@ -273,7 +282,7 @@ static int crypt_iv_benbi_ctr(struct cry + return -EINVAL; + } + +- cc->iv_gen_private.benbi_shift = 9 - log; ++ cc->iv_gen_private.benbi.shift = 9 - log; + + return 0; + } +@@ -288,7 +297,7 @@ static int crypt_iv_benbi_gen(struct cry + + memset(iv, 0, cc->iv_size - sizeof(u64)); /* rest is cleared below */ + +- val = cpu_to_be64(((u64)sector << cc->iv_gen_private.benbi_shift) + 1); ++ val = cpu_to_be64(((u64)sector << cc->iv_gen_private.benbi.shift) + 1); + put_unaligned(val, (__be64 *)(iv + cc->iv_size - sizeof(u64))); + + return 0; diff --git a/queue-2.6.32/dm-crypt-restructure-essiv-error-path.patch b/queue-2.6.32/dm-crypt-restructure-essiv-error-path.patch new file mode 100644 index 00000000000..ae5ba5937f0 --- /dev/null +++ b/queue-2.6.32/dm-crypt-restructure-essiv-error-path.patch @@ -0,0 +1,123 @@ +From 5861f1be00b3b70f8ab5e5a81392a6cf69666cd2 Mon Sep 17 00:00:00 2001 +From: Milan Broz +Date: Thu, 10 Dec 2009 23:51:56 +0000 +Subject: dm crypt: restructure essiv error path + +From: Milan Broz + +commit 5861f1be00b3b70f8ab5e5a81392a6cf69666cd2 upstream. + +Use kzfree for salt deallocation because it is derived from the volume +key. Use a common error path in ESSIV constructor. + +Required by a later patch which fixes the way key material is wiped +from memory. + +Signed-off-by: Milan Broz +Signed-off-by: Alasdair G Kergon +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-crypt.c | 46 ++++++++++++++++++++++++++-------------------- + 1 file changed, 26 insertions(+), 20 deletions(-) + +--- a/drivers/md/dm-crypt.c ++++ b/drivers/md/dm-crypt.c +@@ -187,15 +187,15 @@ static void crypt_iv_essiv_dtr(struct cr + static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti, + const char *opts) + { +- struct crypto_cipher *essiv_tfm; +- struct crypto_hash *hash_tfm; ++ struct crypto_cipher *essiv_tfm = NULL; ++ struct crypto_hash *hash_tfm = NULL; + struct hash_desc desc; + struct scatterlist sg; + unsigned int saltsize; +- u8 *salt; ++ u8 *salt = NULL; + int err; + +- if (opts == NULL) { ++ if (!opts) { + ti->error = "Digest algorithm missing for ESSIV mode"; + return -EINVAL; + } +@@ -204,15 +204,16 @@ static int crypt_iv_essiv_ctr(struct cry + hash_tfm = crypto_alloc_hash(opts, 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(hash_tfm)) { + ti->error = "Error initializing ESSIV hash"; +- return PTR_ERR(hash_tfm); ++ err = PTR_ERR(hash_tfm); ++ goto bad; + } + + saltsize = crypto_hash_digestsize(hash_tfm); +- salt = kmalloc(saltsize, GFP_KERNEL); +- if (salt == NULL) { ++ salt = kzalloc(saltsize, GFP_KERNEL); ++ if (!salt) { + ti->error = "Error kmallocing salt storage in ESSIV"; +- crypto_free_hash(hash_tfm); +- return -ENOMEM; ++ err = -ENOMEM; ++ goto bad; + } + + sg_init_one(&sg, cc->key, cc->key_size); +@@ -220,39 +221,44 @@ static int crypt_iv_essiv_ctr(struct cry + desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; + err = crypto_hash_digest(&desc, &sg, cc->key_size, salt); + crypto_free_hash(hash_tfm); ++ hash_tfm = NULL; + + if (err) { + ti->error = "Error calculating hash in ESSIV"; +- kfree(salt); +- return err; ++ goto bad; + } + + /* Setup the essiv_tfm with the given salt */ + essiv_tfm = crypto_alloc_cipher(cc->cipher, 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(essiv_tfm)) { + ti->error = "Error allocating crypto tfm for ESSIV"; +- kfree(salt); +- return PTR_ERR(essiv_tfm); ++ err = PTR_ERR(essiv_tfm); ++ goto bad; + } + if (crypto_cipher_blocksize(essiv_tfm) != + crypto_ablkcipher_ivsize(cc->tfm)) { + ti->error = "Block size of ESSIV cipher does " + "not match IV size of block cipher"; +- crypto_free_cipher(essiv_tfm); +- kfree(salt); +- return -EINVAL; ++ err = -EINVAL; ++ goto bad; + } + err = crypto_cipher_setkey(essiv_tfm, salt, saltsize); + if (err) { + ti->error = "Failed to set key for ESSIV cipher"; +- crypto_free_cipher(essiv_tfm); +- kfree(salt); +- return err; ++ goto bad; + } +- kfree(salt); ++ kzfree(salt); + + cc->iv_gen_private.essiv.tfm = essiv_tfm; + return 0; ++ ++bad: ++ if (essiv_tfm && !IS_ERR(essiv_tfm)) ++ crypto_free_cipher(essiv_tfm); ++ if (hash_tfm && !IS_ERR(hash_tfm)) ++ crypto_free_hash(hash_tfm); ++ kzfree(salt); ++ return err; + } + + static int crypt_iv_essiv_gen(struct crypt_config *cc, u8 *iv, sector_t sector) diff --git a/queue-2.6.32/dm-crypt-separate-essiv-allocation-from-initialisation.patch b/queue-2.6.32/dm-crypt-separate-essiv-allocation-from-initialisation.patch new file mode 100644 index 00000000000..fcc4174b4e7 --- /dev/null +++ b/queue-2.6.32/dm-crypt-separate-essiv-allocation-from-initialisation.patch @@ -0,0 +1,179 @@ +From b95bf2d3d5a48b095bffe2a0cd8c40453cf59557 Mon Sep 17 00:00:00 2001 +From: Milan Broz +Date: Thu, 10 Dec 2009 23:51:56 +0000 +Subject: dm crypt: separate essiv allocation from initialisation + +From: Milan Broz + +commit b95bf2d3d5a48b095bffe2a0cd8c40453cf59557 upstream. + +This patch separates the construction of IV from its initialisation. +(For ESSIV it is a hash calculation based on volume key.) + +Constructor code now preallocates hash tfm and salt array +and saves it in a private IV structure. + +The next patch requires this to reinitialise the wiped IV +without reallocating memory when resuming a suspended device. + +Signed-off-by: Milan Broz +Signed-off-by: Alasdair G Kergon +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-crypt.c | 69 +++++++++++++++++++++++++++++++------------------- + 1 file changed, 43 insertions(+), 26 deletions(-) + +--- a/drivers/md/dm-crypt.c ++++ b/drivers/md/dm-crypt.c +@@ -71,11 +71,14 @@ struct crypt_iv_operations { + int (*ctr)(struct crypt_config *cc, struct dm_target *ti, + const char *opts); + void (*dtr)(struct crypt_config *cc); ++ int (*init)(struct crypt_config *cc); + int (*generator)(struct crypt_config *cc, u8 *iv, sector_t sector); + }; + + struct iv_essiv_private { + struct crypto_cipher *tfm; ++ struct crypto_hash *hash_tfm; ++ u8 *salt; + }; + + struct iv_benbi_private { +@@ -176,12 +179,38 @@ static int crypt_iv_plain_gen(struct cry + return 0; + } + ++/* Initialise ESSIV - compute salt but no local memory allocations */ ++static int crypt_iv_essiv_init(struct crypt_config *cc) ++{ ++ struct iv_essiv_private *essiv = &cc->iv_gen_private.essiv; ++ struct hash_desc desc; ++ struct scatterlist sg; ++ int err; ++ ++ sg_init_one(&sg, cc->key, cc->key_size); ++ desc.tfm = essiv->hash_tfm; ++ desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; ++ ++ err = crypto_hash_digest(&desc, &sg, cc->key_size, essiv->salt); ++ if (err) ++ return err; ++ ++ return crypto_cipher_setkey(essiv->tfm, essiv->salt, ++ crypto_hash_digestsize(essiv->hash_tfm)); ++} ++ + static void crypt_iv_essiv_dtr(struct crypt_config *cc) + { + struct iv_essiv_private *essiv = &cc->iv_gen_private.essiv; + + crypto_free_cipher(essiv->tfm); + essiv->tfm = NULL; ++ ++ crypto_free_hash(essiv->hash_tfm); ++ essiv->hash_tfm = NULL; ++ ++ kzfree(essiv->salt); ++ essiv->salt = NULL; + } + + static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti, +@@ -189,9 +218,6 @@ static int crypt_iv_essiv_ctr(struct cry + { + struct crypto_cipher *essiv_tfm = NULL; + struct crypto_hash *hash_tfm = NULL; +- struct hash_desc desc; +- struct scatterlist sg; +- unsigned int saltsize; + u8 *salt = NULL; + int err; + +@@ -200,7 +226,7 @@ static int crypt_iv_essiv_ctr(struct cry + return -EINVAL; + } + +- /* Hash the cipher key with the given hash algorithm */ ++ /* Allocate hash algorithm */ + hash_tfm = crypto_alloc_hash(opts, 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(hash_tfm)) { + ti->error = "Error initializing ESSIV hash"; +@@ -208,27 +234,14 @@ static int crypt_iv_essiv_ctr(struct cry + goto bad; + } + +- saltsize = crypto_hash_digestsize(hash_tfm); +- salt = kzalloc(saltsize, GFP_KERNEL); ++ salt = kzalloc(crypto_hash_digestsize(hash_tfm), GFP_KERNEL); + if (!salt) { + ti->error = "Error kmallocing salt storage in ESSIV"; + err = -ENOMEM; + goto bad; + } + +- sg_init_one(&sg, cc->key, cc->key_size); +- desc.tfm = hash_tfm; +- desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; +- err = crypto_hash_digest(&desc, &sg, cc->key_size, salt); +- crypto_free_hash(hash_tfm); +- hash_tfm = NULL; +- +- if (err) { +- ti->error = "Error calculating hash in ESSIV"; +- goto bad; +- } +- +- /* Setup the essiv_tfm with the given salt */ ++ /* Allocate essiv_tfm */ + essiv_tfm = crypto_alloc_cipher(cc->cipher, 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(essiv_tfm)) { + ti->error = "Error allocating crypto tfm for ESSIV"; +@@ -242,14 +255,11 @@ static int crypt_iv_essiv_ctr(struct cry + err = -EINVAL; + goto bad; + } +- err = crypto_cipher_setkey(essiv_tfm, salt, saltsize); +- if (err) { +- ti->error = "Failed to set key for ESSIV cipher"; +- goto bad; +- } +- kzfree(salt); + ++ cc->iv_gen_private.essiv.salt = salt; + cc->iv_gen_private.essiv.tfm = essiv_tfm; ++ cc->iv_gen_private.essiv.hash_tfm = hash_tfm; ++ + return 0; + + bad: +@@ -257,7 +267,7 @@ bad: + crypto_free_cipher(essiv_tfm); + if (hash_tfm && !IS_ERR(hash_tfm)) + crypto_free_hash(hash_tfm); +- kzfree(salt); ++ kfree(salt); + return err; + } + +@@ -323,6 +333,7 @@ static struct crypt_iv_operations crypt_ + static struct crypt_iv_operations crypt_iv_essiv_ops = { + .ctr = crypt_iv_essiv_ctr, + .dtr = crypt_iv_essiv_dtr, ++ .init = crypt_iv_essiv_init, + .generator = crypt_iv_essiv_gen + }; + +@@ -1054,6 +1065,12 @@ static int crypt_ctr(struct dm_target *t + cc->iv_gen_ops->ctr(cc, ti, ivopts) < 0) + goto bad_ivmode; + ++ if (cc->iv_gen_ops && cc->iv_gen_ops->init && ++ cc->iv_gen_ops->init(cc) < 0) { ++ ti->error = "Error initialising IV"; ++ goto bad_slab_pool; ++ } ++ + cc->iv_size = crypto_ablkcipher_ivsize(tfm); + if (cc->iv_size) + /* at least a 64 bit sector number should fit in our buffer */ diff --git a/queue-2.6.32/dm-exception-store-free-tmp_store-on-persistent-flag-error.patch b/queue-2.6.32/dm-exception-store-free-tmp_store-on-persistent-flag-error.patch new file mode 100644 index 00000000000..aa5e71a7948 --- /dev/null +++ b/queue-2.6.32/dm-exception-store-free-tmp_store-on-persistent-flag-error.patch @@ -0,0 +1,31 @@ +From 613978f8711c7fd4d0aa856872375d2abd7c92ff Mon Sep 17 00:00:00 2001 +From: Julia Lawall +Date: Thu, 10 Dec 2009 23:51:52 +0000 +Subject: dm exception store: free tmp_store on persistent flag error + +From: Julia Lawall + +commit 613978f8711c7fd4d0aa856872375d2abd7c92ff upstream. + +Error handling code following a kmalloc should free the allocated data. + +Signed-off-by: Julia Lawall +Signed-off-by: Alasdair G Kergon +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-exception-store.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/md/dm-exception-store.c ++++ b/drivers/md/dm-exception-store.c +@@ -216,7 +216,8 @@ int dm_exception_store_create(struct dm_ + type = get_type("N"); + else { + ti->error = "Persistent flag is not P or N"; +- return -EINVAL; ++ r = -EINVAL; ++ goto bad_type; + } + + if (!type) { diff --git a/queue-2.6.32/dm-snapshot-cope-with-chunk-size-larger-than-origin.patch b/queue-2.6.32/dm-snapshot-cope-with-chunk-size-larger-than-origin.patch new file mode 100644 index 00000000000..0021d1c4efd --- /dev/null +++ b/queue-2.6.32/dm-snapshot-cope-with-chunk-size-larger-than-origin.patch @@ -0,0 +1,38 @@ +From 8e87b9b81b3c370f7e53c1ab6e1c3519ef37a644 Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Thu, 10 Dec 2009 23:51:54 +0000 +Subject: dm snapshot: cope with chunk size larger than origin + +From: Mikulas Patocka + +commit 8e87b9b81b3c370f7e53c1ab6e1c3519ef37a644 upstream. + +Under some special conditions the snapshot hash_size is calculated as zero. +This patch instead sets a minimum value of 64, the same as for the +pending exception table. + +rounddown_pow_of_two(0) is an undefined operation (it expands to shift +by -1). init_exception_table with an argument of 0 would fail with -ENOMEM. + +The way to trigger the problem is to create a snapshot with a chunk size +that is larger than the origin device. + +Signed-off-by: Mikulas Patocka +Signed-off-by: Alasdair G Kergon +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-snap.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/md/dm-snap.c ++++ b/drivers/md/dm-snap.c +@@ -553,6 +553,8 @@ static int init_hash_tables(struct dm_sn + hash_size = min(origin_dev_size, cow_dev_size) >> s->store->chunk_shift; + hash_size = min(hash_size, max_buckets); + ++ if (hash_size < 64) ++ hash_size = 64; + hash_size = rounddown_pow_of_two(hash_size); + if (init_exception_table(&s->complete, hash_size, + DM_CHUNK_CONSECUTIVE_BITS)) diff --git a/queue-2.6.32/dm-snapshot-only-take-lock-for-statustype-info-not-table.patch b/queue-2.6.32/dm-snapshot-only-take-lock-for-statustype-info-not-table.patch new file mode 100644 index 00000000000..8eac69a183a --- /dev/null +++ b/queue-2.6.32/dm-snapshot-only-take-lock-for-statustype-info-not-table.patch @@ -0,0 +1,61 @@ +From 94e76572b5dd37b1f0f4b3742ee8a565daead932 Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Thu, 10 Dec 2009 23:51:53 +0000 +Subject: dm snapshot: only take lock for statustype info not table + +From: Mikulas Patocka + +commit 94e76572b5dd37b1f0f4b3742ee8a565daead932 upstream. + +Take snapshot lock only for STATUSTYPE_INFO, not STATUSTYPE_TABLE. + +Commit 4c6fff445d7aa753957856278d4d93bcad6e2c14 +(dm-snapshot-lock-snapshot-while-supplying-status.patch) +introduced this use of the lock, but userspace applications using +libdevmapper have been found to request STATUSTYPE_TABLE while the device +is suspended and the lock is already held, leading to deadlock. Since +the lock is not necessary in this case, don't try to take it. + +Signed-off-by: Mikulas Patocka +Signed-off-by: Alasdair G Kergon +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-snap.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/drivers/md/dm-snap.c ++++ b/drivers/md/dm-snap.c +@@ -1152,10 +1152,11 @@ static int snapshot_status(struct dm_tar + unsigned sz = 0; + struct dm_snapshot *snap = ti->private; + +- down_write(&snap->lock); +- + switch (type) { + case STATUSTYPE_INFO: ++ ++ down_write(&snap->lock); ++ + if (!snap->valid) + DMEMIT("Invalid"); + else { +@@ -1171,6 +1172,9 @@ static int snapshot_status(struct dm_tar + else + DMEMIT("Unknown"); + } ++ ++ up_write(&snap->lock); ++ + break; + + case STATUSTYPE_TABLE: +@@ -1185,8 +1189,6 @@ static int snapshot_status(struct dm_tar + break; + } + +- up_write(&snap->lock); +- + return 0; + } + diff --git a/queue-2.6.32/driver-core-fix-race-in-dev_driver_string.patch b/queue-2.6.32/driver-core-fix-race-in-dev_driver_string.patch new file mode 100644 index 00000000000..c0d79ff68ae --- /dev/null +++ b/queue-2.6.32/driver-core-fix-race-in-dev_driver_string.patch @@ -0,0 +1,39 @@ +From 3589972e51fac1e02d0aaa576fa47f568cb94d40 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Fri, 4 Dec 2009 11:06:57 -0500 +Subject: Driver core: fix race in dev_driver_string + +From: Alan Stern + +commit 3589972e51fac1e02d0aaa576fa47f568cb94d40 upstream. + +This patch (as1310) works around a race in dev_driver_string(). If +the device is unbound while the function is running, dev->driver might +become NULL after we test it and before we dereference it. + +Signed-off-by: Alan Stern +Cc: Oliver Neukum +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/base/core.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/base/core.c ++++ b/drivers/base/core.c +@@ -56,7 +56,14 @@ static inline int device_is_not_partitio + */ + const char *dev_driver_string(const struct device *dev) + { +- return dev->driver ? dev->driver->name : ++ struct device_driver *drv; ++ ++ /* dev->driver can change to NULL underneath us because of unbinding, ++ * so be careful about accessing it. dev->bus and dev->class should ++ * never change once they are set, so they don't need special care. ++ */ ++ drv = ACCESS_ONCE(dev->driver); ++ return drv ? drv->name : + (dev->bus ? dev->bus->name : + (dev->class ? dev->class->name : "")); + } diff --git a/queue-2.6.32/drm-i915-add-the-missing-clonemask-for-display-port-on-ironlake.patch b/queue-2.6.32/drm-i915-add-the-missing-clonemask-for-display-port-on-ironlake.patch new file mode 100644 index 00000000000..8e661cc8c6e --- /dev/null +++ b/queue-2.6.32/drm-i915-add-the-missing-clonemask-for-display-port-on-ironlake.patch @@ -0,0 +1,37 @@ +From 652af9d74e1a3a10bb10f0d8e8f42ddac26bbc1a Mon Sep 17 00:00:00 2001 +From: Zhao Yakui +Date: Wed, 2 Dec 2009 10:03:33 +0800 +Subject: drm/i915: Add the missing clonemask for display port on Ironlake + +From: Zhao Yakui + +commit 652af9d74e1a3a10bb10f0d8e8f42ddac26bbc1a upstream. + +Add the missing clonemask for display port on Ironlake. + +Signed-off-by: Zhao Yakui +Reviewed-by: Zhenyu Wang +Signed-off-by: Eric Anholt +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_dp.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/drm/i915/intel_dp.c ++++ b/drivers/gpu/drm/i915/intel_dp.c +@@ -1254,11 +1254,11 @@ intel_dp_init(struct drm_device *dev, in + else + intel_output->type = INTEL_OUTPUT_DISPLAYPORT; + +- if (output_reg == DP_B) ++ if (output_reg == DP_B || output_reg == PCH_DP_B) + intel_output->clone_mask = (1 << INTEL_DP_B_CLONE_BIT); +- else if (output_reg == DP_C) ++ else if (output_reg == DP_C || output_reg == PCH_DP_C) + intel_output->clone_mask = (1 << INTEL_DP_C_CLONE_BIT); +- else if (output_reg == DP_D) ++ else if (output_reg == DP_D || output_reg == PCH_DP_D) + intel_output->clone_mask = (1 << INTEL_DP_D_CLONE_BIT); + + if (IS_eDP(intel_output)) { diff --git a/queue-2.6.32/drm-i915-set-the-error-code-after-failing-to-insert-new-offset-into-mm-ht.patch b/queue-2.6.32/drm-i915-set-the-error-code-after-failing-to-insert-new-offset-into-mm-ht.patch new file mode 100644 index 00000000000..cadb73e643d --- /dev/null +++ b/queue-2.6.32/drm-i915-set-the-error-code-after-failing-to-insert-new-offset-into-mm-ht.patch @@ -0,0 +1,27 @@ +From 5618ca6abc2d6f475b258badc017a5254cf43d1b Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Wed, 2 Dec 2009 15:15:30 +0000 +Subject: drm/i915: Set the error code after failing to insert new offset into mm ht. + +From: Chris Wilson + +commit 5618ca6abc2d6f475b258badc017a5254cf43d1b upstream. + +Signed-off-by: Chris Wilson +Signed-off-by: Eric Anholt +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/i915_gem.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -1288,6 +1288,7 @@ i915_gem_create_mmap_offset(struct drm_g + list->hash.key = list->file_offset_node->start; + if (drm_ht_insert_item(&mm->offset_hash, &list->hash)) { + DRM_ERROR("failed to add to map hash\n"); ++ ret = -ENOMEM; + goto out_free_mm; + } + diff --git a/queue-2.6.32/drm-radeon-kms-add-quirk-for-his-x1300-board.patch b/queue-2.6.32/drm-radeon-kms-add-quirk-for-his-x1300-board.patch new file mode 100644 index 00000000000..b946fb2b43f --- /dev/null +++ b/queue-2.6.32/drm-radeon-kms-add-quirk-for-his-x1300-board.patch @@ -0,0 +1,36 @@ +From 4e3f9b78ff917cc5c833858fdb5d96bc262e0bf3 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Tue, 1 Dec 2009 14:49:50 -0500 +Subject: drm/radeon/kms: Add quirk for HIS X1300 board + +From: Alex Deucher + +commit 4e3f9b78ff917cc5c833858fdb5d96bc262e0bf3 upstream. + +Board is DVI+VGA, not DVI+DVI + +Signed-off-by: Alex Deucher +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/radeon_atombios.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/gpu/drm/radeon/radeon_atombios.c ++++ b/drivers/gpu/drm/radeon/radeon_atombios.c +@@ -135,6 +135,14 @@ static bool radeon_atom_apply_quirks(str + } + } + ++ /* HIS X1300 is DVI+VGA, not DVI+DVI */ ++ if ((dev->pdev->device == 0x7146) && ++ (dev->pdev->subsystem_vendor == 0x17af) && ++ (dev->pdev->subsystem_device == 0x2058)) { ++ if (supported_device == ATOM_DEVICE_DFP1_SUPPORT) ++ return false; ++ } ++ + /* Funky macbooks */ + if ((dev->pdev->device == 0x71C5) && + (dev->pdev->subsystem_vendor == 0x106b) && diff --git a/queue-2.6.32/drm-radeon-kms-fix-legacy-crtc2-dpms.patch b/queue-2.6.32/drm-radeon-kms-fix-legacy-crtc2-dpms.patch new file mode 100644 index 00000000000..1288f07bc46 --- /dev/null +++ b/queue-2.6.32/drm-radeon-kms-fix-legacy-crtc2-dpms.patch @@ -0,0 +1,49 @@ +From 8de21525439e6b5bb8d8c81e49094d867bf82f6d Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Thu, 3 Dec 2009 12:15:54 -0500 +Subject: drm/radeon/kms: fix legacy crtc2 dpms + +From: Alex Deucher + +commit 8de21525439e6b5bb8d8c81e49094d867bf82f6d upstream. + +noticed by Matthijs Kooijman on fdo bug 22140 + +Signed-off-by: Alex Deucher +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/radeon_legacy_crtc.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c ++++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +@@ -292,8 +292,7 @@ void radeon_crtc_dpms(struct drm_crtc *c + uint32_t mask; + + if (radeon_crtc->crtc_id) +- mask = (RADEON_CRTC2_EN | +- RADEON_CRTC2_DISP_DIS | ++ mask = (RADEON_CRTC2_DISP_DIS | + RADEON_CRTC2_VSYNC_DIS | + RADEON_CRTC2_HSYNC_DIS | + RADEON_CRTC2_DISP_REQ_EN_B); +@@ -305,7 +304,7 @@ void radeon_crtc_dpms(struct drm_crtc *c + switch (mode) { + case DRM_MODE_DPMS_ON: + if (radeon_crtc->crtc_id) +- WREG32_P(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_EN, ~mask); ++ WREG32_P(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_EN, ~(RADEON_CRTC2_EN | mask)); + else { + WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_EN, ~(RADEON_CRTC_EN | + RADEON_CRTC_DISP_REQ_EN_B)); +@@ -319,7 +318,7 @@ void radeon_crtc_dpms(struct drm_crtc *c + case DRM_MODE_DPMS_OFF: + drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id); + if (radeon_crtc->crtc_id) +- WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~mask); ++ WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~(RADEON_CRTC2_EN | mask)); + else { + WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~(RADEON_CRTC_EN | + RADEON_CRTC_DISP_REQ_EN_B)); diff --git a/queue-2.6.32/drm-radeon-kms-fix-vram-setup-on-rs600.patch b/queue-2.6.32/drm-radeon-kms-fix-vram-setup-on-rs600.patch new file mode 100644 index 00000000000..4adbe86ec75 --- /dev/null +++ b/queue-2.6.32/drm-radeon-kms-fix-vram-setup-on-rs600.patch @@ -0,0 +1,61 @@ +From 722f29434e72188b2d20f9b41f4b5952073ed568 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Thu, 3 Dec 2009 16:18:19 -0500 +Subject: drm/radeon/kms: fix vram setup on rs600 + +From: Alex Deucher + +commit 722f29434e72188b2d20f9b41f4b5952073ed568 upstream. + +also fix up rs690 mem width. + +should fix fdo bug 25408 + +Signed-off-by: Alex Deucher +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/rs600.c | 6 ++++++ + drivers/gpu/drm/radeon/rs690.c | 10 ++-------- + 2 files changed, 8 insertions(+), 8 deletions(-) + +--- a/drivers/gpu/drm/radeon/rs600.c ++++ b/drivers/gpu/drm/radeon/rs600.c +@@ -315,6 +315,12 @@ void rs600_vram_info(struct radeon_devic + /* FIXME: to do or is these values sane ? */ + rdev->mc.vram_is_ddr = true; + rdev->mc.vram_width = 128; ++ ++ rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE); ++ rdev->mc.mc_vram_size = rdev->mc.real_vram_size; ++ ++ rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); ++ rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); + } + + void rs600_bandwidth_update(struct radeon_device *rdev) +--- a/drivers/gpu/drm/radeon/rs690.c ++++ b/drivers/gpu/drm/radeon/rs690.c +@@ -131,19 +131,13 @@ void rs690_pm_info(struct radeon_device + + void rs690_vram_info(struct radeon_device *rdev) + { +- uint32_t tmp; + fixed20_12 a; + + rs400_gart_adjust_size(rdev); + /* DDR for all card after R300 & IGP */ + rdev->mc.vram_is_ddr = true; +- /* FIXME: is this correct for RS690/RS740 ? */ +- tmp = RREG32(RADEON_MEM_CNTL); +- if (tmp & R300_MEM_NUM_CHANNELS_MASK) { +- rdev->mc.vram_width = 128; +- } else { +- rdev->mc.vram_width = 64; +- } ++ rdev->mc.vram_width = 128; ++ + rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE); + rdev->mc.mc_vram_size = rdev->mc.real_vram_size; + diff --git a/queue-2.6.32/drm-radeon-kms-handle-vblanks-properly-with-dpms-on.patch b/queue-2.6.32/drm-radeon-kms-handle-vblanks-properly-with-dpms-on.patch new file mode 100644 index 00000000000..9fc23a62c35 --- /dev/null +++ b/queue-2.6.32/drm-radeon-kms-handle-vblanks-properly-with-dpms-on.patch @@ -0,0 +1,55 @@ +From 500b758725314ab1b5316eb0caa5b0fa26740e6b Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Wed, 2 Dec 2009 11:46:52 -0500 +Subject: drm/radeon/kms: handle vblanks properly with dpms on + +From: Alex Deucher + +commit 500b758725314ab1b5316eb0caa5b0fa26740e6b upstream. + +avivo chips + +Copied from pre-avivo code. + +Signed-off-by: Alex Deucher +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/atombios_crtc.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/radeon/atombios_crtc.c ++++ b/drivers/gpu/drm/radeon/atombios_crtc.c +@@ -241,6 +241,7 @@ void atombios_crtc_dpms(struct drm_crtc + { + struct drm_device *dev = crtc->dev; + struct radeon_device *rdev = dev->dev_private; ++ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); + + switch (mode) { + case DRM_MODE_DPMS_ON: +@@ -248,20 +249,19 @@ void atombios_crtc_dpms(struct drm_crtc + if (ASIC_IS_DCE3(rdev)) + atombios_enable_crtc_memreq(crtc, 1); + atombios_blank_crtc(crtc, 0); ++ drm_vblank_post_modeset(dev, radeon_crtc->crtc_id); ++ radeon_crtc_load_lut(crtc); + break; + case DRM_MODE_DPMS_STANDBY: + case DRM_MODE_DPMS_SUSPEND: + case DRM_MODE_DPMS_OFF: ++ drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id); + atombios_blank_crtc(crtc, 1); + if (ASIC_IS_DCE3(rdev)) + atombios_enable_crtc_memreq(crtc, 0); + atombios_enable_crtc(crtc, 0); + break; + } +- +- if (mode != DRM_MODE_DPMS_OFF) { +- radeon_crtc_load_lut(crtc); +- } + } + + static void diff --git a/queue-2.6.32/drm-radeon-kms-rs6xx-rs740-clamp-vram-to-aperture-size.patch b/queue-2.6.32/drm-radeon-kms-rs6xx-rs740-clamp-vram-to-aperture-size.patch new file mode 100644 index 00000000000..f39a6f0e430 --- /dev/null +++ b/queue-2.6.32/drm-radeon-kms-rs6xx-rs740-clamp-vram-to-aperture-size.patch @@ -0,0 +1,76 @@ +From 0088dbdb809e8799cb8f26da5ac64b15201fa99d Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Thu, 3 Dec 2009 16:28:02 -0500 +Subject: drm/radeon/kms: rs6xx/rs740: clamp vram to aperture size + +From: Alex Deucher + +commit 0088dbdb809e8799cb8f26da5ac64b15201fa99d upstream. + +Signed-off-by: Alex Deucher +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/rs600.c | 9 ++++++--- + drivers/gpu/drm/radeon/rs690.c | 9 ++++++++- + 2 files changed, 14 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/radeon/rs600.c ++++ b/drivers/gpu/drm/radeon/rs600.c +@@ -301,9 +301,7 @@ int rs600_mc_wait_for_idle(struct radeon + + void rs600_gpu_init(struct radeon_device *rdev) + { +- /* FIXME: HDP same place on rs600 ? */ + r100_hdp_reset(rdev); +- /* FIXME: is this correct ? */ + r420_pipes_init(rdev); + /* Wait for mc idle */ + if (rs600_mc_wait_for_idle(rdev)) +@@ -312,7 +310,6 @@ void rs600_gpu_init(struct radeon_device + + void rs600_vram_info(struct radeon_device *rdev) + { +- /* FIXME: to do or is these values sane ? */ + rdev->mc.vram_is_ddr = true; + rdev->mc.vram_width = 128; + +@@ -321,6 +318,12 @@ void rs600_vram_info(struct radeon_devic + + rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); + rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); ++ ++ if (rdev->mc.mc_vram_size > rdev->mc.aper_size) ++ rdev->mc.mc_vram_size = rdev->mc.aper_size; ++ ++ if (rdev->mc.real_vram_size > rdev->mc.aper_size) ++ rdev->mc.real_vram_size = rdev->mc.aper_size; + } + + void rs600_bandwidth_update(struct radeon_device *rdev) +--- a/drivers/gpu/drm/radeon/rs690.c ++++ b/drivers/gpu/drm/radeon/rs690.c +@@ -134,7 +134,7 @@ void rs690_vram_info(struct radeon_devic + fixed20_12 a; + + rs400_gart_adjust_size(rdev); +- /* DDR for all card after R300 & IGP */ ++ + rdev->mc.vram_is_ddr = true; + rdev->mc.vram_width = 128; + +@@ -143,6 +143,13 @@ void rs690_vram_info(struct radeon_devic + + rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); + rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); ++ ++ if (rdev->mc.mc_vram_size > rdev->mc.aper_size) ++ rdev->mc.mc_vram_size = rdev->mc.aper_size; ++ ++ if (rdev->mc.real_vram_size > rdev->mc.aper_size) ++ rdev->mc.real_vram_size = rdev->mc.aper_size; ++ + rs690_pm_info(rdev); + /* FIXME: we should enforce default clock in case GPU is not in + * default setup diff --git a/queue-2.6.32/drm-ttm-fix-build-failure-due-to-missing-struct-page.patch b/queue-2.6.32/drm-ttm-fix-build-failure-due-to-missing-struct-page.patch new file mode 100644 index 00000000000..8372dc92112 --- /dev/null +++ b/queue-2.6.32/drm-ttm-fix-build-failure-due-to-missing-struct-page.patch @@ -0,0 +1,38 @@ +From c3a73ba13bac7fd96030f39202b2d37fb19c46a6 Mon Sep 17 00:00:00 2001 +From: Martin Michlmayr +Date: Thu, 19 Nov 2009 16:29:45 +0000 +Subject: drm/ttm: Fix build failure due to missing struct page + +From: Martin Michlmayr + +commit c3a73ba13bac7fd96030f39202b2d37fb19c46a6 upstream. + +drm/ttm fails to build on MIPS because "struct page" is not known: +| In file included from drivers/gpu/drm/ttm/ttm_memory.c:28: +| include/drm/ttm/ttm_memory.h:154: warning: 'struct page' declared inside parameter list +| include/drm/ttm/ttm_memory.h:154: warning: its scope is only this definition or declaration, which is probably not what you want +| include/drm/ttm/ttm_memory.h:156: warning: 'struct page' declared inside parameter list +| drivers/gpu/drm/ttm/ttm_memory.c:540: error: conflicting types for 'ttm_mem_global_alloc_page' +| include/drm/ttm/ttm_memory.h:154: error: previous declaration of 'ttm_mem_global_alloc_page' was here +| drivers/gpu/drm/ttm/ttm_memory.c:561: error: conflicting types for 'ttm_mem_global_free_page' +| include/drm/ttm/ttm_memory.h:156: error: previous declaration of 'ttm_mem_global_free_page' was here + +Signed-off-by: Martin Michlmayr +Acked-by: Thomas Hellstrom +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + include/drm/ttm/ttm_memory.h | 1 + + 1 file changed, 1 insertion(+) + +--- a/include/drm/ttm/ttm_memory.h ++++ b/include/drm/ttm/ttm_memory.h +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + + /** + * struct ttm_mem_shrink - callback to shrink TTM memory usage. diff --git a/queue-2.6.32/mac80211-fix-bug-in-computing-crc-over-dynamic-ies-in-beacon.patch b/queue-2.6.32/mac80211-fix-bug-in-computing-crc-over-dynamic-ies-in-beacon.patch new file mode 100644 index 00000000000..431d80d1eb7 --- /dev/null +++ b/queue-2.6.32/mac80211-fix-bug-in-computing-crc-over-dynamic-ies-in-beacon.patch @@ -0,0 +1,37 @@ +From 1814077fd12a9cdf478c10076e9c42094e9d9250 Mon Sep 17 00:00:00 2001 +From: Vasanthakumar Thiagarajan +Date: Fri, 4 Dec 2009 17:41:34 +0530 +Subject: mac80211: Fix bug in computing crc over dynamic IEs in beacon + +From: Vasanthakumar Thiagarajan + +commit 1814077fd12a9cdf478c10076e9c42094e9d9250 upstream. + +On a 32-bit machine, BIT() macro does not give the required +bit value if the bit is mroe than 31. In ieee802_11_parse_elems_crc(), +BIT() is suppossed to get the bit value more than 31 (42 (id of ERP_INFO_IE), +37 (CHANNEL_SWITCH_IE), (42), 32 (POWER_CONSTRAINT_IE), 45 (HT_CAP_IE), +61 (HT_INFO_IE)). As we do not get the required bit value for the above +IEs, crc over these IEs are never calculated, so any dynamic change in these +IEs after the association is not really handled on 32-bit platforms. +This patch fixes this issue. + +Signed-off-by: Vasanthakumar Thiagarajan +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/util.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -579,7 +579,7 @@ u32 ieee802_11_parse_elems_crc(u8 *start + if (elen > left) + break; + +- if (calc_crc && id < 64 && (filter & BIT(id))) ++ if (calc_crc && id < 64 && (filter & (1ULL << id))) + crc = crc32_be(crc, pos - 2, elen + 2); + + switch (id) { diff --git a/queue-2.6.32/mac80211-fix-scan-abort-sanity-checks.patch b/queue-2.6.32/mac80211-fix-scan-abort-sanity-checks.patch new file mode 100644 index 00000000000..ef532b69119 --- /dev/null +++ b/queue-2.6.32/mac80211-fix-scan-abort-sanity-checks.patch @@ -0,0 +1,47 @@ +From 6d3560d4fc9c5b9fe1a07a63926ea70512c69c32 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Sat, 31 Oct 2009 07:44:08 +0100 +Subject: mac80211: fix scan abort sanity checks + +From: Johannes Berg + +commit 6d3560d4fc9c5b9fe1a07a63926ea70512c69c32 upstream. + +Since sometimes mac80211 queues up a scan request +to only act on it later, it must be allowed to +(internally) cancel a not-yet-running scan, e.g. +when the interface is taken down. This condition +was missing since we always checked only the +local->scanning variable which isn't yet set in +that situation. + +Reported-by: Luis R. Rodriguez +Signed-off-by: Johannes Berg +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/scan.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +--- a/net/mac80211/scan.c ++++ b/net/mac80211/scan.c +@@ -264,10 +264,14 @@ void ieee80211_scan_completed(struct iee + + mutex_lock(&local->scan_mtx); + +- if (WARN_ON(!local->scanning)) { +- mutex_unlock(&local->scan_mtx); +- return; +- } ++ /* ++ * It's ok to abort a not-yet-running scan (that ++ * we have one at all will be verified by checking ++ * local->scan_req next), but not to complete it ++ * successfully. ++ */ ++ if (WARN_ON(!local->scanning && !aborted)) ++ aborted = true; + + if (WARN_ON(!local->scan_req)) { + mutex_unlock(&local->scan_mtx); diff --git a/queue-2.6.32/mac80211-fixed-bug-in-mesh-portal-paths.patch b/queue-2.6.32/mac80211-fixed-bug-in-mesh-portal-paths.patch new file mode 100644 index 00000000000..009634a8537 --- /dev/null +++ b/queue-2.6.32/mac80211-fixed-bug-in-mesh-portal-paths.patch @@ -0,0 +1,32 @@ +From 5d618cb81aeea19879975cd1f9a1e707694dfd7c Mon Sep 17 00:00:00 2001 +From: Javier Cardona +Date: Wed, 9 Dec 2009 18:43:00 -0800 +Subject: mac80211: Fixed bug in mesh portal paths + +From: Javier Cardona + +commit 5d618cb81aeea19879975cd1f9a1e707694dfd7c upstream. + +Paths to mesh portals were being timed out immediately after each use in +intermediate forwarding nodes. mppath->exp_time is set to the expiration time +so assigning it to jiffies was marking the path as expired. + +Signed-off-by: Javier Cardona +Signed-off-by: Andrey Yurovsky +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/rx.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -1514,7 +1514,6 @@ ieee80211_rx_h_mesh_fwding(struct ieee80 + mpp_path_add(mesh_hdr->eaddr2, hdr->addr4, sdata); + } else { + spin_lock_bh(&mppath->state_lock); +- mppath->exp_time = jiffies; + if (compare_ether_addr(mppath->mpp, hdr->addr4) != 0) + memcpy(mppath->mpp, hdr->addr4, ETH_ALEN); + spin_unlock_bh(&mppath->state_lock); diff --git a/queue-2.6.32/mac80211-revert-use-correct-sign-for-mesh-active-path-refresh.patch b/queue-2.6.32/mac80211-revert-use-correct-sign-for-mesh-active-path-refresh.patch new file mode 100644 index 00000000000..923e3b08fc5 --- /dev/null +++ b/queue-2.6.32/mac80211-revert-use-correct-sign-for-mesh-active-path-refresh.patch @@ -0,0 +1,48 @@ +From 7b324d28a94dac5a451e8cba66e8d324601e5b9a Mon Sep 17 00:00:00 2001 +From: Javier Cardona +Date: Wed, 9 Dec 2009 18:43:01 -0800 +Subject: mac80211: Revert 'Use correct sign for mesh active path refresh' + +From: Javier Cardona + +commit 7b324d28a94dac5a451e8cba66e8d324601e5b9a upstream. + +The patch ("mac80211: Use correct sign for mesh active path +refresh.") was actually a bug. Reverted it and improved the +explanation of how mesh path refresh works. + +Signed-off-by: Javier Cardona +Signed-off-by: Andrey Yurovsky +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/mesh.h | 5 +++-- + net/mac80211/mesh_hwmp.c | 2 +- + 2 files changed, 4 insertions(+), 3 deletions(-) + +--- a/net/mac80211/mesh.h ++++ b/net/mac80211/mesh.h +@@ -186,8 +186,9 @@ struct mesh_rmc { + */ + #define MESH_PREQ_MIN_INT 10 + #define MESH_DIAM_TRAVERSAL_TIME 50 +-/* Paths will be refreshed if they are closer than PATH_REFRESH_TIME to their +- * expiration ++/* A path will be refreshed if it is used PATH_REFRESH_TIME milliseconds before ++ * timing out. This way it will remain ACTIVE and no data frames will be ++ * unnecesarily held in the pending queue. + */ + #define MESH_PATH_REFRESH_TIME 1000 + #define MESH_MIN_DISCOVERY_TIMEOUT (2 * MESH_DIAM_TRAVERSAL_TIME) +--- a/net/mac80211/mesh_hwmp.c ++++ b/net/mac80211/mesh_hwmp.c +@@ -813,7 +813,7 @@ int mesh_nexthop_lookup(struct sk_buff * + } + + if (mpath->flags & MESH_PATH_ACTIVE) { +- if (time_after(jiffies, mpath->exp_time + ++ if (time_after(jiffies, mpath->exp_time - + msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) + && !memcmp(sdata->dev->dev_addr, hdr->addr4, + ETH_ALEN) diff --git a/queue-2.6.32/mm-hugetlb-fix-hugepage-memory-leak-in-mincore.patch b/queue-2.6.32/mm-hugetlb-fix-hugepage-memory-leak-in-mincore.patch new file mode 100644 index 00000000000..1f49c8c3a55 --- /dev/null +++ b/queue-2.6.32/mm-hugetlb-fix-hugepage-memory-leak-in-mincore.patch @@ -0,0 +1,148 @@ +From 4f16fc107d9c9b8a72aa19b189a9216e90a7aaef Mon Sep 17 00:00:00 2001 +From: Naoya Horiguchi +Date: Mon, 14 Dec 2009 17:59:58 -0800 +Subject: mm: hugetlb: fix hugepage memory leak in mincore() + +From: Naoya Horiguchi + +commit 4f16fc107d9c9b8a72aa19b189a9216e90a7aaef upstream. + +Most callers of pmd_none_or_clear_bad() check whether the target page is +in a hugepage or not, but mincore() and walk_page_range() do not check it. + So if we use mincore() on a hugepage on x86 machine, the hugepage memory +is leaked as shown below. This patch fixes it by extending mincore() +system call to support hugepages. + +Details +======= +My test program (leak_mincore) works as follows: + - creat() and mmap() a file on hugetlbfs (file size is 200MB == 100 hugepages,) + - read()/write() something on it, + - call mincore() for first ten pages and printf() the values of *vec + - munmap() and unlink() the file on hugetlbfs + +Without my patch +---------------- +$ cat /proc/meminfo| grep "HugePage" +HugePages_Total: 1000 +HugePages_Free: 1000 +HugePages_Rsvd: 0 +HugePages_Surp: 0 +$ ./leak_mincore +vec[0] 0 +vec[1] 0 +vec[2] 0 +vec[3] 0 +vec[4] 0 +vec[5] 0 +vec[6] 0 +vec[7] 0 +vec[8] 0 +vec[9] 0 +$ cat /proc/meminfo |grep "HugePage" +HugePages_Total: 1000 +HugePages_Free: 999 +HugePages_Rsvd: 0 +HugePages_Surp: 0 +$ ls /hugetlbfs/ +$ + +Return values in *vec from mincore() are set to 0, while the hugepage +should be in memory, and 1 hugepage is still accounted as used while +there is no file on hugetlbfs. + +With my patch +------------- +$ cat /proc/meminfo| grep "HugePage" +HugePages_Total: 1000 +HugePages_Free: 1000 +HugePages_Rsvd: 0 +HugePages_Surp: 0 +$ ./leak_mincore +vec[0] 1 +vec[1] 1 +vec[2] 1 +vec[3] 1 +vec[4] 1 +vec[5] 1 +vec[6] 1 +vec[7] 1 +vec[8] 1 +vec[9] 1 +$ cat /proc/meminfo |grep "HugePage" +HugePages_Total: 1000 +HugePages_Free: 1000 +HugePages_Rsvd: 0 +HugePages_Surp: 0 +$ ls /hugetlbfs/ +$ + +Return value in *vec set to 1 and no memory leaks. + +[akpm@linux-foundation.org: cleanup] +[akpm@linux-foundation.org: build fix] +Signed-off-by: Naoya Horiguchi +Cc: Andi Kleen +Cc: Wu Fengguang +Cc: Hugh Dickins +Cc: Mel Gorman +Cc: Lee Schermerhorn +Cc: Andy Whitcroft +Cc: David Rientjes +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- a/mm/mincore.c ++++ b/mm/mincore.c +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -72,6 +73,42 @@ static long do_mincore(unsigned long addr, unsigned char *vec, unsigned long pag + if (!vma || addr < vma->vm_start) + return -ENOMEM; + ++#ifdef CONFIG_HUGETLB_PAGE ++ if (is_vm_hugetlb_page(vma)) { ++ struct hstate *h; ++ unsigned long nr_huge; ++ unsigned char present; ++ ++ i = 0; ++ nr = min(pages, (vma->vm_end - addr) >> PAGE_SHIFT); ++ h = hstate_vma(vma); ++ nr_huge = ((addr + pages * PAGE_SIZE - 1) >> huge_page_shift(h)) ++ - (addr >> huge_page_shift(h)) + 1; ++ nr_huge = min(nr_huge, ++ (vma->vm_end - addr) >> huge_page_shift(h)); ++ while (1) { ++ /* hugepage always in RAM for now, ++ * but generally it needs to be check */ ++ ptep = huge_pte_offset(current->mm, ++ addr & huge_page_mask(h)); ++ present = !!(ptep && ++ !huge_pte_none(huge_ptep_get(ptep))); ++ while (1) { ++ vec[i++] = present; ++ addr += PAGE_SIZE; ++ /* reach buffer limit */ ++ if (i == nr) ++ return nr; ++ /* check hugepage border */ ++ if (!((addr & ~huge_page_mask(h)) ++ >> PAGE_SHIFT)) ++ break; ++ } ++ } ++ return nr; ++ } ++#endif ++ + /* + * Calculate how many pages there are left in the last level of the + * PTE array for our address. diff --git a/queue-2.6.32/mm-hugetlb-fix-hugepage-memory-leak-in-walk_page_range.patch b/queue-2.6.32/mm-hugetlb-fix-hugepage-memory-leak-in-walk_page_range.patch new file mode 100644 index 00000000000..e457391de47 --- /dev/null +++ b/queue-2.6.32/mm-hugetlb-fix-hugepage-memory-leak-in-walk_page_range.patch @@ -0,0 +1,127 @@ +From d33b9f45bd24a6391bc05e2b5a13c1b5787ca9c2 Mon Sep 17 00:00:00 2001 +From: Naoya Horiguchi +Date: Mon, 14 Dec 2009 17:59:59 -0800 +Subject: mm: hugetlb: fix hugepage memory leak in walk_page_range() + +From: Naoya Horiguchi + +commit d33b9f45bd24a6391bc05e2b5a13c1b5787ca9c2 upstream. + +Most callers of pmd_none_or_clear_bad() check whether the target page is +in a hugepage or not, but walk_page_range() do not check it. So if we +read /proc/pid/pagemap for the hugepage on x86 machine, the hugepage +memory is leaked as shown below. This patch fixes it. + +Details +======= +My test program (leak_pagemap) works as follows: + - creat() and mmap() a file on hugetlbfs (file size is 200MB == 100 hugepages,) + - read()/write() something on it, + - call page-types with option -p (walk around the page tables), + - munmap() and unlink() the file on hugetlbfs + +Without my patches +------------------ +$ cat /proc/meminfo |grep "HugePage" +HugePages_Total: 1000 +HugePages_Free: 1000 +HugePages_Rsvd: 0 +HugePages_Surp: 0 +$ ./leak_pagemap +[snip output] +$ cat /proc/meminfo |grep "HugePage" +HugePages_Total: 1000 +HugePages_Free: 900 +HugePages_Rsvd: 0 +HugePages_Surp: 0 +$ ls /hugetlbfs/ +$ + +100 hugepages are accounted as used while there is no file on hugetlbfs. + +With my patches +--------------- +$ cat /proc/meminfo |grep "HugePage" +HugePages_Total: 1000 +HugePages_Free: 1000 +HugePages_Rsvd: 0 +HugePages_Surp: 0 +$ ./leak_pagemap +[snip output] +$ cat /proc/meminfo |grep "HugePage" +HugePages_Total: 1000 +HugePages_Free: 1000 +HugePages_Rsvd: 0 +HugePages_Surp: 0 +$ ls /hugetlbfs +$ + +No memory leaks. + +Signed-off-by: Naoya Horiguchi +Cc: Andi Kleen +Cc: Wu Fengguang +Cc: Hugh Dickins +Cc: Mel Gorman +Cc: Lee Schermerhorn +Cc: Andy Whitcroft +Cc: David Rientjes +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/pagewalk.c | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +--- a/mm/pagewalk.c ++++ b/mm/pagewalk.c +@@ -1,6 +1,7 @@ + #include + #include + #include ++#include + + static int walk_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, + struct mm_walk *walk) +@@ -107,6 +108,7 @@ int walk_page_range(unsigned long addr, + pgd_t *pgd; + unsigned long next; + int err = 0; ++ struct vm_area_struct *vma; + + if (addr >= end) + return err; +@@ -117,11 +119,22 @@ int walk_page_range(unsigned long addr, + pgd = pgd_offset(walk->mm, addr); + do { + next = pgd_addr_end(addr, end); ++ ++ /* skip hugetlb vma to avoid hugepage PMD being cleared ++ * in pmd_none_or_clear_bad(). */ ++ vma = find_vma(walk->mm, addr); ++ if (vma && is_vm_hugetlb_page(vma)) { ++ if (vma->vm_end < next) ++ next = vma->vm_end; ++ continue; ++ } ++ + if (pgd_none_or_clear_bad(pgd)) { + if (walk->pte_hole) + err = walk->pte_hole(addr, next, walk); + if (err) + break; ++ pgd++; + continue; + } + if (walk->pgd_entry) +@@ -131,7 +144,8 @@ int walk_page_range(unsigned long addr, + err = walk_pud_range(pgd, addr, next, walk); + if (err) + break; +- } while (pgd++, addr = next, addr != end); ++ pgd++; ++ } while (addr = next, addr != end); + + return err; + } diff --git a/queue-2.6.32/powerpc-fix-usage-of-64-bit-instruction-in-32-bit-altivec-code.patch b/queue-2.6.32/powerpc-fix-usage-of-64-bit-instruction-in-32-bit-altivec-code.patch new file mode 100644 index 00000000000..bac5eff6802 --- /dev/null +++ b/queue-2.6.32/powerpc-fix-usage-of-64-bit-instruction-in-32-bit-altivec-code.patch @@ -0,0 +1,34 @@ +From e090aa80321b64c3b793f3b047e31ecf1af9538d Mon Sep 17 00:00:00 2001 +From: Benjamin Herrenschmidt +Date: Tue, 8 Dec 2009 18:45:45 +0000 +Subject: powerpc: Fix usage of 64-bit instruction in 32-bit altivec code + +From: Benjamin Herrenschmidt + +commit e090aa80321b64c3b793f3b047e31ecf1af9538d upstream. + +e821ea70f3b4873b50056a1e0f74befed1014c09 introduced a bug by copying +some 64-bit originated code as-is to be used by both 32 and 64-bit +but this code contains a 64-bit ony "cmpdi" instruction. + +This changes it to cmpwi, which is fine since VRSAVE can only contains +a 32-bit value anyway. + +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kernel/vector.S | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/powerpc/kernel/vector.S ++++ b/arch/powerpc/kernel/vector.S +@@ -58,7 +58,7 @@ _GLOBAL(load_up_altivec) + * all 1's + */ + mfspr r4,SPRN_VRSAVE +- cmpdi 0,r4,0 ++ cmpwi 0,r4,0 + bne+ 1f + li r4,-1 + mtspr SPRN_VRSAVE,r4 diff --git a/queue-2.6.32/powerpc-therm_adt746x-record-pwm-invert-bit-at-module-load-time.patch b/queue-2.6.32/powerpc-therm_adt746x-record-pwm-invert-bit-at-module-load-time.patch new file mode 100644 index 00000000000..c98a07b4489 --- /dev/null +++ b/queue-2.6.32/powerpc-therm_adt746x-record-pwm-invert-bit-at-module-load-time.patch @@ -0,0 +1,77 @@ +From 1496e89ae2a0962748e55165a590fa3209c6f158 Mon Sep 17 00:00:00 2001 +From: Darrick J. Wong +Date: Thu, 3 Dec 2009 16:19:59 +0000 +Subject: powerpc/therm_adt746x: Record pwm invert bit at module load time] + +From: Darrick J. Wong + +commit 1496e89ae2a0962748e55165a590fa3209c6f158 upstream. + +In commit 0512a9a8e277a9de2820211eef964473b714ae65, we unilaterally zero the +"pwm invert" bit in the fan behavior configuration register. On my PowerBook +G4, this results in the fans going to full speed at low temperature and +shutting off at high temperature because the pwm invert bit is supposed to be +set. + +Therefore, record the pwm invert bit at driver load time, and write the bit +into the fan behavior control register. This restores correct behavior on my +PBG4 and should work around the bit being set to the wrong value after +suspend/resume (which is what the original patch was trying to fix). It also +fixes a minor omission where the pwm invert bit correction is NOT performed +when switching into automatic mode. + +Signed-off-by: Darrick J. Wong +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/macintosh/therm_adt746x.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +--- a/drivers/macintosh/therm_adt746x.c ++++ b/drivers/macintosh/therm_adt746x.c +@@ -79,6 +79,7 @@ struct thermostat { + u8 limits[3]; + int last_speed[2]; + int last_var[2]; ++ int pwm_inv[2]; + }; + + static enum {ADT7460, ADT7467} therm_type; +@@ -229,19 +230,23 @@ static void write_fan_speed(struct therm + + if (speed >= 0) { + manual = read_reg(th, MANUAL_MODE[fan]); ++ manual &= ~INVERT_MASK; + write_reg(th, MANUAL_MODE[fan], +- (manual|MANUAL_MASK) & (~INVERT_MASK)); ++ manual | MANUAL_MASK | th->pwm_inv[fan]); + write_reg(th, FAN_SPD_SET[fan], speed); + } else { + /* back to automatic */ + if(therm_type == ADT7460) { + manual = read_reg(th, + MANUAL_MODE[fan]) & (~MANUAL_MASK); +- ++ manual &= ~INVERT_MASK; ++ manual |= th->pwm_inv[fan]; + write_reg(th, + MANUAL_MODE[fan], manual|REM_CONTROL[fan]); + } else { + manual = read_reg(th, MANUAL_MODE[fan]); ++ manual &= ~INVERT_MASK; ++ manual |= th->pwm_inv[fan]; + write_reg(th, MANUAL_MODE[fan], manual&(~AUTO_MASK)); + } + } +@@ -418,6 +423,10 @@ static int probe_thermostat(struct i2c_c + + thermostat = th; + ++ /* record invert bit status because fw can corrupt it after suspend */ ++ th->pwm_inv[0] = read_reg(th, MANUAL_MODE[0]) & INVERT_MASK; ++ th->pwm_inv[1] = read_reg(th, MANUAL_MODE[1]) & INVERT_MASK; ++ + /* be sure to really write fan speed the first time */ + th->last_speed[0] = -2; + th->last_speed[1] = -2; diff --git a/queue-2.6.32/powerpc-windfarm-add-detection-for-second-cpu-pump.patch b/queue-2.6.32/powerpc-windfarm-add-detection-for-second-cpu-pump.patch new file mode 100644 index 00000000000..f3831d69a4a --- /dev/null +++ b/queue-2.6.32/powerpc-windfarm-add-detection-for-second-cpu-pump.patch @@ -0,0 +1,30 @@ +From 529586dc39b0ec47c6290c4e7bed6ea3ffd1d8fb Mon Sep 17 00:00:00 2001 +From: Bolko Maass +Date: Fri, 27 Nov 2009 05:44:33 +0000 +Subject: powerpc/windfarm: Add detection for second cpu pump + +From: Bolko Maass + +commit 529586dc39b0ec47c6290c4e7bed6ea3ffd1d8fb upstream. + +Windfarm SMU control is explicitly missing support for a second CPU pump in G5 PowerMacs. Such machines actually exist (specifically Quads with a second pump), so this patch adds detection for it. + +Signed-off by: Bolko Maass +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/macintosh/windfarm_smu_controls.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/macintosh/windfarm_smu_controls.c ++++ b/drivers/macintosh/windfarm_smu_controls.c +@@ -202,6 +202,8 @@ static struct smu_fan_control *smu_fan_c + fct->ctrl.name = "cpu-front-fan-1"; + else if (!strcmp(l, "CPU A PUMP")) + fct->ctrl.name = "cpu-pump-0"; ++ else if (!strcmp(l, "CPU B PUMP")) ++ fct->ctrl.name = "cpu-pump-1"; + else if (!strcmp(l, "Slots Fan") || !strcmp(l, "Slots fan") || + !strcmp(l, "EXPANSION SLOTS INTAKE")) + fct->ctrl.name = "slots-fan"; diff --git a/queue-2.6.32/rtl8187-fix-wrong-rfkill-switch-mask-for-some-models.patch b/queue-2.6.32/rtl8187-fix-wrong-rfkill-switch-mask-for-some-models.patch new file mode 100644 index 00000000000..fba81a9632b --- /dev/null +++ b/queue-2.6.32/rtl8187-fix-wrong-rfkill-switch-mask-for-some-models.patch @@ -0,0 +1,110 @@ +From 70d57139f932b9ca21026253d02af71cf53d764a Mon Sep 17 00:00:00 2001 +From: Larry Finger +Date: Sat, 5 Dec 2009 19:25:22 -0600 +Subject: rtl8187: Fix wrong rfkill switch mask for some models +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Larry Finger + +commit 70d57139f932b9ca21026253d02af71cf53d764a upstream. + +There are different bits used to convey the setting of the rfkill +switch to the driver. The current driver only supports one of these +possibilities. These changes were derived from the latest version +of the vendor driver. + +This patch fixes the regression noted in kernel Bugzilla #14743. + +Signed-off-by: Larry Finger +Reported-and-tested-by: Antti Kaijanmäki +Tested-by: Hin-Tak Leung +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/rtl818x/rtl8187.h | 5 +++++ + drivers/net/wireless/rtl818x/rtl8187_dev.c | 12 ++++++++++-- + drivers/net/wireless/rtl818x/rtl8187_rfkill.c | 4 ++-- + 3 files changed, 17 insertions(+), 4 deletions(-) + +--- a/drivers/net/wireless/rtl818x/rtl8187_dev.c ++++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c +@@ -1329,6 +1329,7 @@ static int __devinit rtl8187_probe(struc + struct ieee80211_channel *channel; + const char *chip_name; + u16 txpwr, reg; ++ u16 product_id = le16_to_cpu(udev->descriptor.idProduct); + int err, i; + + dev = ieee80211_alloc_hw(sizeof(*priv), &rtl8187_ops); +@@ -1488,6 +1489,13 @@ static int __devinit rtl8187_probe(struc + (*channel++).hw_value = txpwr & 0xFF; + (*channel++).hw_value = txpwr >> 8; + } ++ /* Handle the differing rfkill GPIO bit in different models */ ++ priv->rfkill_mask = RFKILL_MASK_8187_89_97; ++ if (product_id == 0x8197 || product_id == 0x8198) { ++ eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_SELECT_GPIO, ®); ++ if (reg & 0xFF00) ++ priv->rfkill_mask = RFKILL_MASK_8198; ++ } + + /* + * XXX: Once this driver supports anything that requires +@@ -1516,9 +1524,9 @@ static int __devinit rtl8187_probe(struc + mutex_init(&priv->conf_mutex); + skb_queue_head_init(&priv->b_tx_status.queue); + +- printk(KERN_INFO "%s: hwaddr %pM, %s V%d + %s\n", ++ printk(KERN_INFO "%s: hwaddr %pM, %s V%d + %s, rfkill mask %d\n", + wiphy_name(dev->wiphy), dev->wiphy->perm_addr, +- chip_name, priv->asic_rev, priv->rf->name); ++ chip_name, priv->asic_rev, priv->rf->name, priv->rfkill_mask); + + #ifdef CONFIG_RTL8187_LEDS + eeprom_93cx6_read(&eeprom, 0x3F, ®); +--- a/drivers/net/wireless/rtl818x/rtl8187.h ++++ b/drivers/net/wireless/rtl818x/rtl8187.h +@@ -23,6 +23,7 @@ + #define RTL8187_EEPROM_TXPWR_CHAN_1 0x16 /* 3 channels */ + #define RTL8187_EEPROM_TXPWR_CHAN_6 0x1B /* 2 channels */ + #define RTL8187_EEPROM_TXPWR_CHAN_4 0x3D /* 2 channels */ ++#define RTL8187_EEPROM_SELECT_GPIO 0x3B + + #define RTL8187_REQT_READ 0xC0 + #define RTL8187_REQT_WRITE 0x40 +@@ -31,6 +32,9 @@ + + #define RTL8187_MAX_RX 0x9C4 + ++#define RFKILL_MASK_8187_89_97 0x2 ++#define RFKILL_MASK_8198 0x4 ++ + struct rtl8187_rx_info { + struct urb *urb; + struct ieee80211_hw *dev; +@@ -123,6 +127,7 @@ struct rtl8187_priv { + u8 noise; + u8 slot_time; + u8 aifsn[4]; ++ u8 rfkill_mask; + struct { + __le64 buf; + struct sk_buff_head queue; +--- a/drivers/net/wireless/rtl818x/rtl8187_rfkill.c ++++ b/drivers/net/wireless/rtl818x/rtl8187_rfkill.c +@@ -25,10 +25,10 @@ static bool rtl8187_is_radio_enabled(str + u8 gpio; + + gpio = rtl818x_ioread8(priv, &priv->map->GPIO0); +- rtl818x_iowrite8(priv, &priv->map->GPIO0, gpio & ~0x02); ++ rtl818x_iowrite8(priv, &priv->map->GPIO0, gpio & ~priv->rfkill_mask); + gpio = rtl818x_ioread8(priv, &priv->map->GPIO1); + +- return gpio & 0x02; ++ return gpio & priv->rfkill_mask; + } + + void rtl8187_rfkill_init(struct ieee80211_hw *hw) diff --git a/queue-2.6.32/serial-do-not-read-iir-in-serial8250_start_tx-when-uart_bug_txen.patch b/queue-2.6.32/serial-do-not-read-iir-in-serial8250_start_tx-when-uart_bug_txen.patch new file mode 100644 index 00000000000..d854c102b52 --- /dev/null +++ b/queue-2.6.32/serial-do-not-read-iir-in-serial8250_start_tx-when-uart_bug_txen.patch @@ -0,0 +1,45 @@ +From 68cb4f8e246bbbc649980be0628cae9265870a91 Mon Sep 17 00:00:00 2001 +From: Ian Jackson +Date: Wed, 18 Nov 2009 11:08:11 +0100 +Subject: Serial: Do not read IIR in serial8250_start_tx when UART_BUG_TXEN + +From: Ian Jackson + +commit 68cb4f8e246bbbc649980be0628cae9265870a91 upstream. + +Do not read IIR in serial8250_start_tx when UART_BUG_TXEN + +Reading the IIR clears some oustanding interrupts so it is not safe. +Instead, simply transmit immediately if the buffer is empty without +regard to IIR. + +Signed-off-by: Ian Jackson +Reviewed-by: Markus Armbruster +Reviewed-by: Jiri Kosina +Cc: Alan Cox +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/serial/8250.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +--- a/drivers/serial/8250.c ++++ b/drivers/serial/8250.c +@@ -1339,14 +1339,12 @@ static void serial8250_start_tx(struct u + serial_out(up, UART_IER, up->ier); + + if (up->bugs & UART_BUG_TXEN) { +- unsigned char lsr, iir; ++ unsigned char lsr; + lsr = serial_in(up, UART_LSR); + up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; +- iir = serial_in(up, UART_IIR) & 0x0f; + if ((up->port.type == PORT_RM9000) ? +- (lsr & UART_LSR_THRE && +- (iir == UART_IIR_NO_INT || iir == UART_IIR_THRI)) : +- (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT)) ++ (lsr & UART_LSR_THRE) : ++ (lsr & UART_LSR_TEMT)) + transmit_chars(up); + } + } diff --git a/queue-2.6.32/series b/queue-2.6.32/series index 8153abf11d1..0fdcd1234fe 100644 --- a/queue-2.6.32/series +++ b/queue-2.6.32/series @@ -59,3 +59,48 @@ md-bitmap-protect-against-bitmap-removal-while-being-updated.patch futex-take-mmap_sem-for-get_user_pages-in-fault_in_user_writeable.patch devpts_get_tty-should-validate-inode.patch debugfs-fix-create-mutex-racy-fops-and-private-data.patch +driver-core-fix-race-in-dev_driver_string.patch +serial-do-not-read-iir-in-serial8250_start_tx-when-uart_bug_txen.patch +mac80211-fix-bug-in-computing-crc-over-dynamic-ies-in-beacon.patch +mac80211-fixed-bug-in-mesh-portal-paths.patch +mac80211-revert-use-correct-sign-for-mesh-active-path-refresh.patch +mac80211-fix-scan-abort-sanity-checks.patch +wireless-correctly-report-signal-value-for-ieee80211_hw_signal_unspec.patch +rtl8187-fix-wrong-rfkill-switch-mask-for-some-models.patch +x86-fix-bogus-warning-in-apic_noop.apic_write.patch +mm-hugetlb-fix-hugepage-memory-leak-in-mincore.patch +mm-hugetlb-fix-hugepage-memory-leak-in-walk_page_range.patch +powerpc-windfarm-add-detection-for-second-cpu-pump.patch +powerpc-therm_adt746x-record-pwm-invert-bit-at-module-load-time.patch +powerpc-fix-usage-of-64-bit-instruction-in-32-bit-altivec-code.patch +drm-radeon-kms-add-quirk-for-his-x1300-board.patch +drm-radeon-kms-handle-vblanks-properly-with-dpms-on.patch +drm-radeon-kms-fix-legacy-crtc2-dpms.patch +drm-radeon-kms-fix-vram-setup-on-rs600.patch +drm-radeon-kms-rs6xx-rs740-clamp-vram-to-aperture-size.patch +drm-ttm-fix-build-failure-due-to-missing-struct-page.patch +drm-i915-set-the-error-code-after-failing-to-insert-new-offset-into-mm-ht.patch +drm-i915-add-the-missing-clonemask-for-display-port-on-ironlake.patch +xen-xenbus-make-device_attr-s-static.patch +xen-re-register-runstate-area-earlier-on-resume.patch +xen-restore-runstate_info-even-if-have_vcpu_info_placement.patch +xen-correctly-restore-pfn_to_mfn_list_list-after-resume.patch +xen-register-timer-interrupt-with-irqf_timer.patch +xen-register-runstate-on-secondary-cpus.patch +xen-don-t-call-dpm_resume_noirq-with-interrupts-disabled.patch +xen-register-runstate-info-for-boot-cpu-early.patch +xen-call-clock-resume-notifier-on-all-cpus.patch +xen-improve-error-handling-in-do_suspend.patch +xen-don-t-leak-irqs-over-suspend-resume.patch +xen-use-iret-for-return-from-64b-kernel-to-32b-usermode.patch +xen-explicitly-create-destroy-stop_machine-workqueues-outside-suspend-resume-region.patch +xen-balloon-fix-totalram_pages-counting.patch +xen-try-harder-to-balloon-up-under-memory-pressure.patch +dm-exception-store-free-tmp_store-on-persistent-flag-error.patch +dm-snapshot-only-take-lock-for-statustype-info-not-table.patch +dm-crypt-move-private-iv-fields-to-structs.patch +dm-crypt-restructure-essiv-error-path.patch +dm-avoid-_hash_lock-deadlock.patch +dm-snapshot-cope-with-chunk-size-larger-than-origin.patch +dm-crypt-separate-essiv-allocation-from-initialisation.patch +dm-crypt-make-wipe-message-also-wipe-essiv-key.patch diff --git a/queue-2.6.32/wireless-correctly-report-signal-value-for-ieee80211_hw_signal_unspec.patch b/queue-2.6.32/wireless-correctly-report-signal-value-for-ieee80211_hw_signal_unspec.patch new file mode 100644 index 00000000000..55e53f2cce0 --- /dev/null +++ b/queue-2.6.32/wireless-correctly-report-signal-value-for-ieee80211_hw_signal_unspec.patch @@ -0,0 +1,32 @@ +From 19deffbeba930030cfaf000b920333c6ba99ad52 Mon Sep 17 00:00:00 2001 +From: John W. Linville +Date: Tue, 8 Dec 2009 17:10:13 -0500 +Subject: wireless: correctly report signal value for IEEE80211_HW_SIGNAL_UNSPEC + +From: John W. Linville + +commit 19deffbeba930030cfaf000b920333c6ba99ad52 upstream. + +This part was missed in "cfg80211: implement get_wireless_stats", +probably because sta_set_sinfo already existed and was only handling +dBm signals. + +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/cfg.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -338,7 +338,8 @@ static void sta_set_sinfo(struct sta_inf + sinfo->rx_packets = sta->rx_packets; + sinfo->tx_packets = sta->tx_packets; + +- if (sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) { ++ if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || ++ (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { + sinfo->filled |= STATION_INFO_SIGNAL; + sinfo->signal = (s8)sta->last_signal; + } diff --git a/queue-2.6.32/x86-fix-bogus-warning-in-apic_noop.apic_write.patch b/queue-2.6.32/x86-fix-bogus-warning-in-apic_noop.apic_write.patch new file mode 100644 index 00000000000..e55d9ab533d --- /dev/null +++ b/queue-2.6.32/x86-fix-bogus-warning-in-apic_noop.apic_write.patch @@ -0,0 +1,41 @@ +From a946d8f11f0da9cfc714248036fcfd3a794d1e27 Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Mon, 7 Dec 2009 12:59:46 +0100 +Subject: x86: Fix bogus warning in apic_noop.apic_write() + +From: Thomas Gleixner + +commit a946d8f11f0da9cfc714248036fcfd3a794d1e27 upstream. + +apic_noop is used to provide dummy apic functions. It's installed +when the CPU has no APIC or when the APIC is disabled on the kernel +command line. + +The apic_noop implementation of apic_write() warns when the CPU has +an APIC or when the APIC is not disabled. + +That's bogus. The warning should only happen when the CPU has an +APIC _AND_ the APIC is not disabled. apic_noop.apic_read() has the +correct check. + +Signed-off-by: Thomas Gleixner +Cc: Cyrill Gorcunov +LKML-Reference: +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/apic/apic.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/kernel/apic/apic.c ++++ b/arch/x86/kernel/apic/apic.c +@@ -246,7 +246,7 @@ static int modern_apic(void) + */ + static void native_apic_write_dummy(u32 reg, u32 v) + { +- WARN_ON_ONCE((cpu_has_apic || !disable_apic)); ++ WARN_ON_ONCE(cpu_has_apic && !disable_apic); + } + + static u32 native_apic_read_dummy(u32 reg) diff --git a/queue-2.6.32/xen-balloon-fix-totalram_pages-counting.patch b/queue-2.6.32/xen-balloon-fix-totalram_pages-counting.patch new file mode 100644 index 00000000000..51272ba58a7 --- /dev/null +++ b/queue-2.6.32/xen-balloon-fix-totalram_pages-counting.patch @@ -0,0 +1,65 @@ +From 3d65c9488cadd2f11bd4d60c7266e639ece5d0d6 Mon Sep 17 00:00:00 2001 +From: Gianluca Guida +Date: Thu, 30 Jul 2009 22:54:36 +0100 +Subject: Xen balloon: fix totalram_pages counting. + +From: Gianluca Guida + +commit 3d65c9488cadd2f11bd4d60c7266e639ece5d0d6 upstream. + +Change totalram_pages when a single page is added/removed to the +ballooned list. This avoid totalram_pages to be set erroneously to +max_pfn at boot. + +Signed-off-by: Gianluca Guida +Signed-off-by: Jeremy Fitzhardinge +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/xen/balloon.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/xen/balloon.c ++++ b/drivers/xen/balloon.c +@@ -136,6 +136,8 @@ static void balloon_append(struct page * + list_add(&page->lru, &ballooned_pages); + balloon_stats.balloon_low++; + } ++ ++ totalram_pages--; + } + + /* balloon_retrieve: rescue a page from the balloon, if it is not empty. */ +@@ -156,6 +158,8 @@ static struct page *balloon_retrieve(voi + else + balloon_stats.balloon_low--; + ++ totalram_pages++; ++ + return page; + } + +@@ -260,7 +264,6 @@ static int increase_reservation(unsigned + } + + balloon_stats.current_pages += nr_pages; +- totalram_pages = balloon_stats.current_pages; + + out: + spin_unlock_irqrestore(&balloon_lock, flags); +@@ -323,7 +326,6 @@ static int decrease_reservation(unsigned + BUG_ON(ret != nr_pages); + + balloon_stats.current_pages -= nr_pages; +- totalram_pages = balloon_stats.current_pages; + + spin_unlock_irqrestore(&balloon_lock, flags); + +@@ -422,7 +424,6 @@ static int __init balloon_init(void) + pr_info("xen_balloon: Initialising balloon driver.\n"); + + balloon_stats.current_pages = min(xen_start_info->nr_pages, max_pfn); +- totalram_pages = balloon_stats.current_pages; + balloon_stats.target_pages = balloon_stats.current_pages; + balloon_stats.balloon_low = 0; + balloon_stats.balloon_high = 0; diff --git a/queue-2.6.32/xen-call-clock-resume-notifier-on-all-cpus.patch b/queue-2.6.32/xen-call-clock-resume-notifier-on-all-cpus.patch new file mode 100644 index 00000000000..70b0f0d2eb4 --- /dev/null +++ b/queue-2.6.32/xen-call-clock-resume-notifier-on-all-cpus.patch @@ -0,0 +1,58 @@ +From f6eafe3665bcc374c66775d58312d1c06c55303f Mon Sep 17 00:00:00 2001 +From: Ian Campbell +Date: Wed, 25 Nov 2009 14:12:08 +0000 +Subject: xen: call clock resume notifier on all CPUs + +From: Ian Campbell + +commit f6eafe3665bcc374c66775d58312d1c06c55303f upstream. + +tick_resume() is never called on secondary processors. Presumably this +is because they are offlined for suspend on native and so this is +normally taken care of in the CPU onlining path. Under Xen we keep all +CPUs online over a suspend. + +This patch papers over the issue for me but I will investigate a more +generic, less hacky, way of doing to the same. + +tick_suspend is also only called on the boot CPU which I presume should +be fixed too. + +Signed-off-by: Ian Campbell +Signed-off-by: Jeremy Fitzhardinge +Cc: Thomas Gleixner +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/xen/suspend.c | 15 ++++++++++++++- + 1 file changed, 14 insertions(+), 1 deletion(-) + +--- a/arch/x86/xen/suspend.c ++++ b/arch/x86/xen/suspend.c +@@ -1,4 +1,5 @@ + #include ++#include + + #include + #include +@@ -46,7 +47,19 @@ void xen_post_suspend(int suspend_cancel + + } + ++static void xen_vcpu_notify_restore(void *data) ++{ ++ unsigned long reason = (unsigned long)data; ++ ++ /* Boot processor notified via generic timekeeping_resume() */ ++ if ( smp_processor_id() == 0) ++ return; ++ ++ clockevents_notify(reason, NULL); ++} ++ + void xen_arch_resume(void) + { +- /* nothing */ ++ smp_call_function(xen_vcpu_notify_restore, ++ (void *)CLOCK_EVT_NOTIFY_RESUME, 1); + } diff --git a/queue-2.6.32/xen-correctly-restore-pfn_to_mfn_list_list-after-resume.patch b/queue-2.6.32/xen-correctly-restore-pfn_to_mfn_list_list-after-resume.patch new file mode 100644 index 00000000000..70906b7561c --- /dev/null +++ b/queue-2.6.32/xen-correctly-restore-pfn_to_mfn_list_list-after-resume.patch @@ -0,0 +1,77 @@ +From fa24ba62ea2869308ffc9f0b286ac9650b4ca6cb Mon Sep 17 00:00:00 2001 +From: Ian Campbell +Date: Sat, 21 Nov 2009 11:32:49 +0000 +Subject: xen: correctly restore pfn_to_mfn_list_list after resume + +From: Ian Campbell + +commit fa24ba62ea2869308ffc9f0b286ac9650b4ca6cb upstream. + +pvops kernels >= 2.6.30 can currently only be saved and restored once. The +second attempt to save results in: + + ERROR Internal error: Frame# in pfn-to-mfn frame list is not in pseudophys + ERROR Internal error: entry 0: p2m_frame_list[0] is 0xf2c2c2c2, max 0x120000 + ERROR Internal error: Failed to map/save the p2m frame list + +I finally narrowed it down to: + + commit cdaead6b4e657f960d6d6f9f380e7dfeedc6a09b + Author: Jeremy Fitzhardinge + Date: Fri Feb 27 15:34:59 2009 -0800 + + xen: split construction of p2m mfn tables from registration + + Build the p2m_mfn_list_list early with the rest of the p2m table, but + register it later when the real shared_info structure is in place. + + Signed-off-by: Jeremy Fitzhardinge + +The unforeseen side-effect of this change was to cause the mfn list list to not +be rebuilt on resume. Prior to this change it would have been rebuilt via +xen_post_suspend() -> xen_setup_shared_info() -> xen_setup_mfn_list_list(). + +Fix by explicitly calling xen_build_mfn_list_list() from xen_post_suspend(). + +Signed-off-by: Ian Campbell +Signed-off-by: Jeremy Fitzhardinge +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/xen/mmu.c | 2 +- + arch/x86/xen/suspend.c | 2 ++ + arch/x86/xen/xen-ops.h | 1 + + 3 files changed, 4 insertions(+), 1 deletion(-) + +--- a/arch/x86/xen/mmu.c ++++ b/arch/x86/xen/mmu.c +@@ -185,7 +185,7 @@ static inline unsigned p2m_index(unsigne + } + + /* Build the parallel p2m_top_mfn structures */ +-static void __init xen_build_mfn_list_list(void) ++void xen_build_mfn_list_list(void) + { + unsigned pfn, idx; + +--- a/arch/x86/xen/suspend.c ++++ b/arch/x86/xen/suspend.c +@@ -27,6 +27,8 @@ void xen_pre_suspend(void) + + void xen_post_suspend(int suspend_cancelled) + { ++ xen_build_mfn_list_list(); ++ + xen_setup_shared_info(); + + if (suspend_cancelled) { +--- a/arch/x86/xen/xen-ops.h ++++ b/arch/x86/xen/xen-ops.h +@@ -25,6 +25,7 @@ extern struct shared_info *HYPERVISOR_sh + + void xen_setup_mfn_list_list(void); + void xen_setup_shared_info(void); ++void xen_build_mfn_list_list(void); + void xen_setup_machphys_mapping(void); + pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn); + void xen_ident_map_ISA(void); diff --git a/queue-2.6.32/xen-don-t-call-dpm_resume_noirq-with-interrupts-disabled.patch b/queue-2.6.32/xen-don-t-call-dpm_resume_noirq-with-interrupts-disabled.patch new file mode 100644 index 00000000000..1c54144194f --- /dev/null +++ b/queue-2.6.32/xen-don-t-call-dpm_resume_noirq-with-interrupts-disabled.patch @@ -0,0 +1,57 @@ +From 922cc38ab71d1360978e65207e4a4f4988987127 Mon Sep 17 00:00:00 2001 +From: Jeremy Fitzhardinge +Date: Tue, 24 Nov 2009 09:58:49 -0800 +Subject: xen: don't call dpm_resume_noirq() with interrupts disabled. + +From: Jeremy Fitzhardinge + +commit 922cc38ab71d1360978e65207e4a4f4988987127 upstream. + +dpm_resume_noirq() takes a mutex, so it can't be called from a no-interrupt +context. Don't call it from within the stop-machine function, but just +afterwards, since we're resuming anyway, regardless of what happened. + +Signed-off-by: Jeremy Fitzhardinge +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/xen/manage.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +--- a/drivers/xen/manage.c ++++ b/drivers/xen/manage.c +@@ -43,7 +43,6 @@ static int xen_suspend(void *data) + if (err) { + printk(KERN_ERR "xen_suspend: sysdev_suspend failed: %d\n", + err); +- dpm_resume_noirq(PMSG_RESUME); + return err; + } + +@@ -69,7 +68,6 @@ static int xen_suspend(void *data) + } + + sysdev_resume(); +- dpm_resume_noirq(PMSG_RESUME); + + return 0; + } +@@ -108,6 +106,9 @@ static void do_suspend(void) + } + + err = stop_machine(xen_suspend, &cancelled, cpumask_of(0)); ++ ++ dpm_resume_noirq(PMSG_RESUME); ++ + if (err) { + printk(KERN_ERR "failed to start xen_suspend: %d\n", err); + goto out; +@@ -119,8 +120,6 @@ static void do_suspend(void) + } else + xs_suspend_cancel(); + +- dpm_resume_noirq(PMSG_RESUME); +- + resume_devices: + dpm_resume_end(PMSG_RESUME); + diff --git a/queue-2.6.32/xen-don-t-leak-irqs-over-suspend-resume.patch b/queue-2.6.32/xen-don-t-leak-irqs-over-suspend-resume.patch new file mode 100644 index 00000000000..88e8cd9a14b --- /dev/null +++ b/queue-2.6.32/xen-don-t-leak-irqs-over-suspend-resume.patch @@ -0,0 +1,44 @@ +From fed5ea87e02aaf902ff38c65b4514233db03dc09 Mon Sep 17 00:00:00 2001 +From: Ian Campbell +Date: Tue, 1 Dec 2009 16:15:30 +0000 +Subject: xen: don't leak IRQs over suspend/resume. + +From: Ian Campbell + +commit fed5ea87e02aaf902ff38c65b4514233db03dc09 upstream. + +On resume irq_info[*].evtchn is reset to 0 since event channel mappings +are not preserved over suspend/resume. The other contents of irq_info +is preserved to allow rebind_evtchn_irq() to function. + +However when a device resumes it will try to unbind from the +previous IRQ (e.g. blkfront goes blkfront_resume() -> blkif_free() -> +unbind_from_irqhandler() -> unbind_from_irq()). This will fail due to the +check for VALID_EVTCHN in unbind_from_irq() and the IRQ is leaked. The +device will then continue to resume and allocate a new IRQ, eventually +leading to find_unbound_irq() panic()ing. + +Fix this by changing unbind_from_irq() to handle teardown of interrupts +which have type!=IRQT_UNBOUND but are not currently bound to a specific +event channel. + +Signed-off-by: Ian Campbell +Signed-off-by: Jeremy Fitzhardinge +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/xen/events.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/xen/events.c ++++ b/drivers/xen/events.c +@@ -474,6 +474,9 @@ static void unbind_from_irq(unsigned int + bind_evtchn_to_cpu(evtchn, 0); + + evtchn_to_irq[evtchn] = -1; ++ } ++ ++ if (irq_info[irq].type != IRQT_UNBOUND) { + irq_info[irq] = mk_unbound_info(); + + dynamic_irq_cleanup(irq); diff --git a/queue-2.6.32/xen-explicitly-create-destroy-stop_machine-workqueues-outside-suspend-resume-region.patch b/queue-2.6.32/xen-explicitly-create-destroy-stop_machine-workqueues-outside-suspend-resume-region.patch new file mode 100644 index 00000000000..c26c42e48bb --- /dev/null +++ b/queue-2.6.32/xen-explicitly-create-destroy-stop_machine-workqueues-outside-suspend-resume-region.patch @@ -0,0 +1,68 @@ +From b4606f2165153833247823e8c04c5e88cb3d298b Mon Sep 17 00:00:00 2001 +From: Ian Campbell +Date: Tue, 1 Dec 2009 11:47:15 +0000 +Subject: xen: explicitly create/destroy stop_machine workqueues outside suspend/resume region. + +From: Ian Campbell + +commit b4606f2165153833247823e8c04c5e88cb3d298b upstream. + +I have observed cases where the implicit stop_machine_destroy() done by +stop_machine() hangs while destroying the workqueues, specifically in +kthread_stop(). This seems to be because timer ticks are not restarted +until after stop_machine() returns. + +Fortunately stop_machine provides a facility to pre-create/post-destroy +the workqueues so use this to ensure that workqueues are only destroyed +after everything is really up and running again. + +I only actually observed this failure with 2.6.30. It seems that newer +kernels are somehow more robust against doing kthread_stop() without timer +interrupts (I tried some backports of some likely looking candidates but +did not track down the commit which added this robustness). However this +change seems like a reasonable belt&braces thing to do. + +Signed-off-by: Ian Campbell +Signed-off-by: Jeremy Fitzhardinge +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/xen/manage.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +--- a/drivers/xen/manage.c ++++ b/drivers/xen/manage.c +@@ -79,6 +79,12 @@ static void do_suspend(void) + + shutting_down = SHUTDOWN_SUSPEND; + ++ err = stop_machine_create(); ++ if (err) { ++ printk(KERN_ERR "xen suspend: failed to setup stop_machine %d\n", err); ++ goto out; ++ } ++ + #ifdef CONFIG_PREEMPT + /* If the kernel is preemptible, we need to freeze all the processes + to prevent them from being in the middle of a pagetable update +@@ -86,7 +92,7 @@ static void do_suspend(void) + err = freeze_processes(); + if (err) { + printk(KERN_ERR "xen suspend: freeze failed %d\n", err); +- goto out; ++ goto out_destroy_sm; + } + #endif + +@@ -129,7 +135,11 @@ out_resume: + out_thaw: + #ifdef CONFIG_PREEMPT + thaw_processes(); ++ ++out_destroy_sm: + #endif ++ stop_machine_destroy(); ++ + out: + shutting_down = SHUTDOWN_INVALID; + } diff --git a/queue-2.6.32/xen-improve-error-handling-in-do_suspend.patch b/queue-2.6.32/xen-improve-error-handling-in-do_suspend.patch new file mode 100644 index 00000000000..308ea1ef8f5 --- /dev/null +++ b/queue-2.6.32/xen-improve-error-handling-in-do_suspend.patch @@ -0,0 +1,91 @@ +From 65f63384b391bf4d384327d8a7c6de9860290b5c Mon Sep 17 00:00:00 2001 +From: Ian Campbell +Date: Tue, 1 Dec 2009 11:47:14 +0000 +Subject: xen: improve error handling in do_suspend. + +From: Ian Campbell + +commit 65f63384b391bf4d384327d8a7c6de9860290b5c upstream. + +The existing error handling has a few issues: +- If freeze_processes() fails it exits with shutting_down = SHUTDOWN_SUSPEND. +- If dpm_suspend_noirq() fails it exits without resuming xenbus. +- If stop_machine() fails it exits without resuming xenbus or calling + dpm_resume_end(). +- xs_suspend()/xs_resume() and dpm_suspend_noirq()/dpm_resume_noirq() were not + nested in the obvious way. + +Fix by ensuring each failure case goto's the correct label. Treat a failure of +stop_machine() as a cancelled suspend in order to follow the correct resume +path. + +Signed-off-by: Ian Campbell +Signed-off-by: Jeremy Fitzhardinge +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/xen/manage.c | 20 +++++++++++--------- + 1 file changed, 11 insertions(+), 9 deletions(-) + +--- a/drivers/xen/manage.c ++++ b/drivers/xen/manage.c +@@ -86,32 +86,32 @@ static void do_suspend(void) + err = freeze_processes(); + if (err) { + printk(KERN_ERR "xen suspend: freeze failed %d\n", err); +- return; ++ goto out; + } + #endif + + err = dpm_suspend_start(PMSG_SUSPEND); + if (err) { + printk(KERN_ERR "xen suspend: dpm_suspend_start %d\n", err); +- goto out; ++ goto out_thaw; + } + +- printk(KERN_DEBUG "suspending xenstore...\n"); +- xs_suspend(); +- + err = dpm_suspend_noirq(PMSG_SUSPEND); + if (err) { + printk(KERN_ERR "dpm_suspend_noirq failed: %d\n", err); +- goto resume_devices; ++ goto out_resume; + } + ++ printk(KERN_DEBUG "suspending xenstore...\n"); ++ xs_suspend(); ++ + err = stop_machine(xen_suspend, &cancelled, cpumask_of(0)); + + dpm_resume_noirq(PMSG_RESUME); + + if (err) { + printk(KERN_ERR "failed to start xen_suspend: %d\n", err); +- goto out; ++ cancelled = 1; + } + + if (!cancelled) { +@@ -120,15 +120,17 @@ static void do_suspend(void) + } else + xs_suspend_cancel(); + +-resume_devices: ++out_resume: + dpm_resume_end(PMSG_RESUME); + + /* Make sure timer events get retriggered on all CPUs */ + clock_was_set(); +-out: ++ ++out_thaw: + #ifdef CONFIG_PREEMPT + thaw_processes(); + #endif ++out: + shutting_down = SHUTDOWN_INVALID; + } + #endif /* CONFIG_PM_SLEEP */ diff --git a/queue-2.6.32/xen-re-register-runstate-area-earlier-on-resume.patch b/queue-2.6.32/xen-re-register-runstate-area-earlier-on-resume.patch new file mode 100644 index 00000000000..c6f478b0fd3 --- /dev/null +++ b/queue-2.6.32/xen-re-register-runstate-area-earlier-on-resume.patch @@ -0,0 +1,76 @@ +From be012920ecba161ad20303a3f6d9e96c58cf97c7 Mon Sep 17 00:00:00 2001 +From: Ian Campbell +Date: Sat, 21 Nov 2009 08:35:55 +0800 +Subject: xen: re-register runstate area earlier on resume. + +From: Ian Campbell + +commit be012920ecba161ad20303a3f6d9e96c58cf97c7 upstream. + +This is necessary to ensure the runstate area is available to +xen_sched_clock before any calls to printk which will require it in +order to provide a timestamp. + +I chose to pull the xen_setup_runstate_info out of xen_time_init into +the caller in order to maintain parity with calling +xen_setup_runstate_info separately from calling xen_time_resume. + +Signed-off-by: Ian Campbell +Signed-off-by: Jeremy Fitzhardinge +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/xen/enlighten.c | 2 ++ + arch/x86/xen/time.c | 5 ++--- + arch/x86/xen/xen-ops.h | 1 + + 3 files changed, 5 insertions(+), 3 deletions(-) + +--- a/arch/x86/xen/enlighten.c ++++ b/arch/x86/xen/enlighten.c +@@ -148,6 +148,8 @@ void xen_vcpu_restore(void) + HYPERVISOR_vcpu_op(VCPUOP_down, cpu, NULL)) + BUG(); + ++ xen_setup_runstate_info(cpu); ++ + xen_vcpu_setup(cpu); + + if (other_cpu && +--- a/arch/x86/xen/time.c ++++ b/arch/x86/xen/time.c +@@ -100,7 +100,7 @@ bool xen_vcpu_stolen(int vcpu) + return per_cpu(runstate, vcpu).state == RUNSTATE_runnable; + } + +-static void setup_runstate_info(int cpu) ++void xen_setup_runstate_info(int cpu) + { + struct vcpu_register_runstate_memory_area area; + +@@ -442,8 +442,6 @@ void xen_setup_timer(int cpu) + + evt->cpumask = cpumask_of(cpu); + evt->irq = irq; +- +- setup_runstate_info(cpu); + } + + void xen_teardown_timer(int cpu) +@@ -494,6 +492,7 @@ __init void xen_time_init(void) + + setup_force_cpu_cap(X86_FEATURE_TSC); + ++ xen_setup_runstate_info(cpu); + xen_setup_timer(cpu); + xen_setup_cpu_clockevents(); + } +--- a/arch/x86/xen/xen-ops.h ++++ b/arch/x86/xen/xen-ops.h +@@ -41,6 +41,7 @@ void __init xen_build_dynamic_phys_to_ma + + void xen_init_irq_ops(void); + void xen_setup_timer(int cpu); ++void xen_setup_runstate_info(int cpu); + void xen_teardown_timer(int cpu); + cycle_t xen_clocksource_read(void); + void xen_setup_cpu_clockevents(void); diff --git a/queue-2.6.32/xen-register-runstate-info-for-boot-cpu-early.patch b/queue-2.6.32/xen-register-runstate-info-for-boot-cpu-early.patch new file mode 100644 index 00000000000..d15412bb514 --- /dev/null +++ b/queue-2.6.32/xen-register-runstate-info-for-boot-cpu-early.patch @@ -0,0 +1,31 @@ +From 499d19b82b586aef18727b9ae1437f8f37b66e91 Mon Sep 17 00:00:00 2001 +From: Jeremy Fitzhardinge +Date: Tue, 24 Nov 2009 09:38:25 -0800 +Subject: xen: register runstate info for boot CPU early + +From: Jeremy Fitzhardinge + +commit 499d19b82b586aef18727b9ae1437f8f37b66e91 upstream. + +printk timestamping uses sched_clock, which in turn relies on runstate +info under Xen. So make sure we set it up before any printks can +be called. + +Signed-off-by: Jeremy Fitzhardinge +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/xen/enlighten.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/arch/x86/xen/enlighten.c ++++ b/arch/x86/xen/enlighten.c +@@ -1181,6 +1181,8 @@ asmlinkage void __init xen_start_kernel( + + xen_raw_console_write("about to get started...\n"); + ++ xen_setup_runstate_info(0); ++ + /* Start the world */ + #ifdef CONFIG_X86_32 + i386_start_kernel(); diff --git a/queue-2.6.32/xen-register-runstate-on-secondary-cpus.patch b/queue-2.6.32/xen-register-runstate-on-secondary-cpus.patch new file mode 100644 index 00000000000..f42aea58961 --- /dev/null +++ b/queue-2.6.32/xen-register-runstate-on-secondary-cpus.patch @@ -0,0 +1,31 @@ +From 028896721ac04f6fa0697f3ecac3f98761746363 Mon Sep 17 00:00:00 2001 +From: Ian Campbell +Date: Tue, 24 Nov 2009 09:32:48 -0800 +Subject: xen: register runstate on secondary CPUs + +From: Ian Campbell + +commit 028896721ac04f6fa0697f3ecac3f98761746363 upstream. + +The commit "xen: re-register runstate area earlier on resume" caused us +to never try and setup the runstate area for secondary CPUs. Ensure that +we do this... + +Signed-off-by: Ian Campbell +Signed-off-by: Jeremy Fitzhardinge +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/xen/smp.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/x86/xen/smp.c ++++ b/arch/x86/xen/smp.c +@@ -295,6 +295,7 @@ static int __cpuinit xen_cpu_up(unsigned + (unsigned long)task_stack_page(idle) - + KERNEL_STACK_OFFSET + THREAD_SIZE; + #endif ++ xen_setup_runstate_info(cpu); + xen_setup_timer(cpu); + xen_init_lock_cpu(cpu); + diff --git a/queue-2.6.32/xen-register-timer-interrupt-with-irqf_timer.patch b/queue-2.6.32/xen-register-timer-interrupt-with-irqf_timer.patch new file mode 100644 index 00000000000..4b31146c8af --- /dev/null +++ b/queue-2.6.32/xen-register-timer-interrupt-with-irqf_timer.patch @@ -0,0 +1,32 @@ +From f350c7922faad3397c98c81a9e5658f5a1ef0214 Mon Sep 17 00:00:00 2001 +From: Ian Campbell +Date: Tue, 24 Nov 2009 10:16:23 +0000 +Subject: xen: register timer interrupt with IRQF_TIMER + +From: Ian Campbell + +commit f350c7922faad3397c98c81a9e5658f5a1ef0214 upstream. + +Otherwise the timer is disabled by dpm_suspend_noirq() which in turn prevents +correct operation of stop_machine on multi-processor systems and breaks +suspend. + +Signed-off-by: Ian Campbell +Signed-off-by: Jeremy Fitzhardinge +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/xen/time.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/xen/time.c ++++ b/arch/x86/xen/time.c +@@ -434,7 +434,7 @@ void xen_setup_timer(int cpu) + name = ""; + + irq = bind_virq_to_irqhandler(VIRQ_TIMER, cpu, xen_timer_interrupt, +- IRQF_DISABLED|IRQF_PERCPU|IRQF_NOBALANCING, ++ IRQF_DISABLED|IRQF_PERCPU|IRQF_NOBALANCING|IRQF_TIMER, + name, NULL); + + evt = &per_cpu(xen_clock_events, cpu); diff --git a/queue-2.6.32/xen-restore-runstate_info-even-if-have_vcpu_info_placement.patch b/queue-2.6.32/xen-restore-runstate_info-even-if-have_vcpu_info_placement.patch new file mode 100644 index 00000000000..b1e74befe36 --- /dev/null +++ b/queue-2.6.32/xen-restore-runstate_info-even-if-have_vcpu_info_placement.patch @@ -0,0 +1,59 @@ +From 3905bb2aa7bb801b31946b37a4635ebac4009051 Mon Sep 17 00:00:00 2001 +From: Jeremy Fitzhardinge +Date: Sat, 21 Nov 2009 08:46:29 +0800 +Subject: xen: restore runstate_info even if !have_vcpu_info_placement + +From: Jeremy Fitzhardinge + +commit 3905bb2aa7bb801b31946b37a4635ebac4009051 upstream. + +Even if have_vcpu_info_placement is not set, we still need to set up +the runstate area on each resumed vcpu. + +Signed-off-by: Jeremy Fitzhardinge +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/xen/enlighten.c | 25 +++++++++++-------------- + 1 file changed, 11 insertions(+), 14 deletions(-) + +--- a/arch/x86/xen/enlighten.c ++++ b/arch/x86/xen/enlighten.c +@@ -138,26 +138,23 @@ static void xen_vcpu_setup(int cpu) + */ + void xen_vcpu_restore(void) + { +- if (have_vcpu_info_placement) { +- int cpu; ++ int cpu; + +- for_each_online_cpu(cpu) { +- bool other_cpu = (cpu != smp_processor_id()); ++ for_each_online_cpu(cpu) { ++ bool other_cpu = (cpu != smp_processor_id()); + +- if (other_cpu && +- HYPERVISOR_vcpu_op(VCPUOP_down, cpu, NULL)) +- BUG(); ++ if (other_cpu && ++ HYPERVISOR_vcpu_op(VCPUOP_down, cpu, NULL)) ++ BUG(); + +- xen_setup_runstate_info(cpu); ++ xen_setup_runstate_info(cpu); + ++ if (have_vcpu_info_placement) + xen_vcpu_setup(cpu); + +- if (other_cpu && +- HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL)) +- BUG(); +- } +- +- BUG_ON(!have_vcpu_info_placement); ++ if (other_cpu && ++ HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL)) ++ BUG(); + } + } + diff --git a/queue-2.6.32/xen-try-harder-to-balloon-up-under-memory-pressure.patch b/queue-2.6.32/xen-try-harder-to-balloon-up-under-memory-pressure.patch new file mode 100644 index 00000000000..8889fac2fca --- /dev/null +++ b/queue-2.6.32/xen-try-harder-to-balloon-up-under-memory-pressure.patch @@ -0,0 +1,135 @@ +From bc2c0303226ec716854d3c208c7f84fe7aa35cd7 Mon Sep 17 00:00:00 2001 +From: Ian Campbell +Date: Fri, 5 Jun 2009 11:58:37 +0100 +Subject: xen: try harder to balloon up under memory pressure. + +From: Ian Campbell + +commit bc2c0303226ec716854d3c208c7f84fe7aa35cd7 upstream. + +Currently if the balloon driver is unable to increase the guest's +reservation it assumes the failure was due to reaching its full +allocation, gives up on the ballooning operation and records the limit +it reached as the "hard limit". The driver will not try again until +the target is set again (even to the same value). + +However it is possible that ballooning has in fact failed due to +memory pressure in the host and therefore it is desirable to keep +attempting to reach the target in case memory becomes available. The +most likely scenario is that some guests are ballooning down while +others are ballooning up and therefore there is temporary memory +pressure while things stabilise. You would not expect a well behaved +toolstack to ask a domain to balloon to more than its allocation nor +would you expect it to deliberately over-commit memory by setting +balloon targets which exceed the total host memory. + +This patch drops the concept of a hard limit and causes the balloon +driver to retry increasing the reservation on a timer in the same +manner as when decreasing the reservation. + +Also if we partially succeed in increasing the reservation +(i.e. receive less pages than we asked for) then we may as well keep +those pages rather than returning them to Xen. + +Signed-off-by: Ian Campbell +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/xen/balloon.c | 31 +++++-------------------------- + 1 file changed, 5 insertions(+), 26 deletions(-) + +--- a/drivers/xen/balloon.c ++++ b/drivers/xen/balloon.c +@@ -66,8 +66,6 @@ struct balloon_stats { + /* We aim for 'current allocation' == 'target allocation'. */ + unsigned long current_pages; + unsigned long target_pages; +- /* We may hit the hard limit in Xen. If we do then we remember it. */ +- unsigned long hard_limit; + /* + * Drivers may alter the memory reservation independently, but they + * must inform the balloon driver so we avoid hitting the hard limit. +@@ -185,7 +183,7 @@ static void balloon_alarm(unsigned long + + static unsigned long current_target(void) + { +- unsigned long target = min(balloon_stats.target_pages, balloon_stats.hard_limit); ++ unsigned long target = balloon_stats.target_pages; + + target = min(target, + balloon_stats.current_pages + +@@ -221,23 +219,10 @@ static int increase_reservation(unsigned + set_xen_guest_handle(reservation.extent_start, frame_list); + reservation.nr_extents = nr_pages; + rc = HYPERVISOR_memory_op(XENMEM_populate_physmap, &reservation); +- if (rc < nr_pages) { +- if (rc > 0) { +- int ret; +- +- /* We hit the Xen hard limit: reprobe. */ +- reservation.nr_extents = rc; +- ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, +- &reservation); +- BUG_ON(ret != rc); +- } +- if (rc >= 0) +- balloon_stats.hard_limit = (balloon_stats.current_pages + rc - +- balloon_stats.driver_pages); ++ if (rc < 0) + goto out; +- } + +- for (i = 0; i < nr_pages; i++) { ++ for (i = 0; i < rc; i++) { + page = balloon_retrieve(); + BUG_ON(page == NULL); + +@@ -263,12 +248,12 @@ static int increase_reservation(unsigned + __free_page(page); + } + +- balloon_stats.current_pages += nr_pages; ++ balloon_stats.current_pages += rc; + + out: + spin_unlock_irqrestore(&balloon_lock, flags); + +- return 0; ++ return rc < 0 ? rc : rc != nr_pages; + } + + static int decrease_reservation(unsigned long nr_pages) +@@ -369,7 +354,6 @@ static void balloon_process(struct work_ + static void balloon_set_new_target(unsigned long target) + { + /* No need for lock. Not read-modify-write updates. */ +- balloon_stats.hard_limit = ~0UL; + balloon_stats.target_pages = target; + schedule_work(&balloon_worker); + } +@@ -428,7 +412,6 @@ static int __init balloon_init(void) + balloon_stats.balloon_low = 0; + balloon_stats.balloon_high = 0; + balloon_stats.driver_pages = 0UL; +- balloon_stats.hard_limit = ~0UL; + + init_timer(&balloon_timer); + balloon_timer.data = 0; +@@ -473,9 +456,6 @@ module_exit(balloon_exit); + BALLOON_SHOW(current_kb, "%lu\n", PAGES2KB(balloon_stats.current_pages)); + BALLOON_SHOW(low_kb, "%lu\n", PAGES2KB(balloon_stats.balloon_low)); + BALLOON_SHOW(high_kb, "%lu\n", PAGES2KB(balloon_stats.balloon_high)); +-BALLOON_SHOW(hard_limit_kb, +- (balloon_stats.hard_limit!=~0UL) ? "%lu\n" : "???\n", +- (balloon_stats.hard_limit!=~0UL) ? PAGES2KB(balloon_stats.hard_limit) : 0); + BALLOON_SHOW(driver_kb, "%lu\n", PAGES2KB(balloon_stats.driver_pages)); + + static ssize_t show_target_kb(struct sys_device *dev, struct sysdev_attribute *attr, +@@ -545,7 +525,6 @@ static struct attribute *balloon_info_at + &attr_current_kb.attr, + &attr_low_kb.attr, + &attr_high_kb.attr, +- &attr_hard_limit_kb.attr, + &attr_driver_kb.attr, + NULL + }; diff --git a/queue-2.6.32/xen-use-iret-for-return-from-64b-kernel-to-32b-usermode.patch b/queue-2.6.32/xen-use-iret-for-return-from-64b-kernel-to-32b-usermode.patch new file mode 100644 index 00000000000..8c48d82623f --- /dev/null +++ b/queue-2.6.32/xen-use-iret-for-return-from-64b-kernel-to-32b-usermode.patch @@ -0,0 +1,46 @@ +From 6aaf5d633bb6cead81b396d861d7bae4b9a0ba7e Mon Sep 17 00:00:00 2001 +From: Jeremy Fitzhardinge +Date: Wed, 25 Nov 2009 13:15:38 -0800 +Subject: xen: use iret for return from 64b kernel to 32b usermode + +From: Jeremy Fitzhardinge + +commit 6aaf5d633bb6cead81b396d861d7bae4b9a0ba7e upstream. + +If Xen wants to return to a 32b usermode with sysret it must use the +right form. When using VCGF_in_syscall to trigger this, it looks at +the code segment and does a 32b sysret if it is FLAT_USER_CS32. +However, this is different from __USER32_CS, so it fails to return +properly if we use the normal Linux segment. + +So avoid the whole mess by dropping VCGF_in_syscall and simply use +plain iret to return to usermode. + +Signed-off-by: Jeremy Fitzhardinge +Acked-by: Jan Beulich +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/xen/xen-asm_64.S | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/x86/xen/xen-asm_64.S ++++ b/arch/x86/xen/xen-asm_64.S +@@ -96,7 +96,7 @@ ENTRY(xen_sysret32) + pushq $__USER32_CS + pushq %rcx + +- pushq $VGCF_in_syscall ++ pushq $0 + 1: jmp hypercall_iret + ENDPATCH(xen_sysret32) + RELOC(xen_sysret32, 1b+1) +@@ -151,7 +151,7 @@ ENTRY(xen_syscall32_target) + ENTRY(xen_sysenter_target) + lea 16(%rsp), %rsp /* strip %rcx, %r11 */ + mov $-ENOSYS, %rax +- pushq $VGCF_in_syscall ++ pushq $0 + jmp hypercall_iret + ENDPROC(xen_syscall32_target) + ENDPROC(xen_sysenter_target) diff --git a/queue-2.6.32/xen-xenbus-make-device_attr-s-static.patch b/queue-2.6.32/xen-xenbus-make-device_attr-s-static.patch new file mode 100644 index 00000000000..bd782b4a29a --- /dev/null +++ b/queue-2.6.32/xen-xenbus-make-device_attr-s-static.patch @@ -0,0 +1,45 @@ +From db05fed0ad72f264e39bcb366795f7367384ec92 Mon Sep 17 00:00:00 2001 +From: Jeremy Fitzhardinge +Date: Tue, 24 Nov 2009 16:41:47 -0800 +Subject: xen/xenbus: make DEVICE_ATTR()s static + +From: Jeremy Fitzhardinge + +commit db05fed0ad72f264e39bcb366795f7367384ec92 upstream. + +They don't need to be global, and may cause linker clashes. + +Signed-off-by: Jeremy Fitzhardinge +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/xen/xenbus/xenbus_probe.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/xen/xenbus/xenbus_probe.c ++++ b/drivers/xen/xenbus/xenbus_probe.c +@@ -454,21 +454,21 @@ static ssize_t xendev_show_nodename(stru + { + return sprintf(buf, "%s\n", to_xenbus_device(dev)->nodename); + } +-DEVICE_ATTR(nodename, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_nodename, NULL); ++static DEVICE_ATTR(nodename, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_nodename, NULL); + + static ssize_t xendev_show_devtype(struct device *dev, + struct device_attribute *attr, char *buf) + { + return sprintf(buf, "%s\n", to_xenbus_device(dev)->devicetype); + } +-DEVICE_ATTR(devtype, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_devtype, NULL); ++static DEVICE_ATTR(devtype, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_devtype, NULL); + + static ssize_t xendev_show_modalias(struct device *dev, + struct device_attribute *attr, char *buf) + { + return sprintf(buf, "xen:%s\n", to_xenbus_device(dev)->devicetype); + } +-DEVICE_ATTR(modalias, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_modalias, NULL); ++static DEVICE_ATTR(modalias, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_modalias, NULL); + + int xenbus_probe_node(struct xen_bus_type *bus, + const char *type,