Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Linux 2.6.25.3

3 views
Skip to first unread message

Greg Kroah-Hartman

unread,
May 10, 2008, 1:13:44 AM5/10/08
to linux-...@vger.kernel.org, Andrew Morton, torv...@linux-foundation.org, sta...@kernel.org
We (the -stable team) are announcing the release of the 2.6.25.3 kernel.

Yes, its a few hours earlier than originally expected, but there are two
security bugs fixed in here that just recently were made public, so we
figured we would err on the safe side. All users of the 2.6.25 series
are strongly encouraged to upgrade, and anyone running 2.6.24 should
also move up to 2.6.25 at this time if possible.

I'll also be replying to this message with a copy of the patch between
2.6.25.2 and 2.6.25.3

The updated 2.6.25.y git tree can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-2.6.25.y.git
and can be browsed at the normal kernel.org git web browser:
http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.25.y.git;a=summary

thanks,

greg k-h

--------

Makefile | 2 -
arch/arm/kernel/kprobes-decode.c | 2 -
arch/arm/kernel/kprobes.c | 2 -
arch/sparc/kernel/sys_sparc.c | 3 -
arch/sparc64/kernel/sys_sparc.c | 4 +-
arch/x86/pci/common.c | 7 ++--
arch/x86/pci/init.c | 2 +
arch/x86/pci/pci.h | 2 +
crypto/authenc.c | 5 +-
crypto/cryptd.c | 4 +-
crypto/eseqiv.c | 3 +
drivers/acpi/processor_idle.c | 4 ++
drivers/md/md.c | 2 -
drivers/net/wireless/b43/b43.h | 4 ++
drivers/net/wireless/b43/main.c | 40 ++++++++++++++++++-----
drivers/serial/mpc52xx_uart.c | 2 -
fs/reiserfs/ioctl.c | 4 --
fs/reiserfs/super.c | 17 +++++++---
fs/utimes.c | 17 ++++++++--
include/crypto/scatterwalk.h | 4 ++
include/linux/reiserfs_fs.h | 1
kernel/sched.c | 66 ++++++++++++++++++++++++++++++++++++++-
mm/page_alloc.c | 14 +++++++-
net/ipv6/sit.c | 2 -
24 files changed, 175 insertions(+), 38 deletions(-)


Dan Williams (1):
md: fix use after free when removing rdev via sysfs

David S. Miller (2):
sparc: Fix mmap VA span checking.
sit: Add missing kfree_skb() on pskb_may_pull() failure.

Grant Likely (1):
POWERPC: mpc5200: Fix unterminated of_device_id table

Greg Kroah-Hartman (1):
Linux 2.6.25.3

Herbert Xu (2):
CRYPTO: api: Fix scatterwalk_sg_chain
CRYPTO: eseqiv: Fix off-by-one encryption

Jan Kara (1):
reiserfs: Unpack tails on quota files

Julia Lawall (1):
CRYPTO: cryptd: Correct kzalloc error test

KAMEZAWA Hiroyuki (1):
mm: fix usemap initialization

Lennert Buytenhek (1):
kprobes/arm: fix decoding of arithmetic immediate instructions

Michael Buesch (2):
b43: Fix dual-PHY devices
b43: Fix some TX/RX locking issues

Miklos Szeredi (1):
vfs: fix permission checking in sys_utimensat

Nicolas Pitre (1):
kprobes/arm: fix cache flush address for instruction stub

Patrick McHardy (1):
CRYPTO: authenc: Fix async crypto crash in crypto_authenc_genicv()

Peter Zijlstra (1):
sched: fix hrtick_start_fair and CPU-Hotplug

Venkatesh Pallipadi (1):
2.6.25 regression: powertop says 120K wakeups/sec

Yinghai Lu (1):
x86 PCI: call dmi_check_pciprobe()

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majo...@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

Greg Kroah-Hartman

unread,
May 10, 2008, 1:16:33 AM5/10/08
to linux-...@vger.kernel.org, Andrew Morton, torv...@linux-foundation.org, sta...@kernel.org
diff --git a/Makefile b/Makefile
index 621f7b3..1ae3a39 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 25
-EXTRAVERSION = .2
+EXTRAVERSION = .3
NAME = Funky Weasel is Jiggy wit it

# *DOCUMENTATION*
diff --git a/arch/arm/kernel/kprobes-decode.c b/arch/arm/kernel/kprobes-decode.c
index d51bc8b..b4565bb 100644
--- a/arch/arm/kernel/kprobes-decode.c
+++ b/arch/arm/kernel/kprobes-decode.c
@@ -1176,7 +1176,7 @@ space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
* *S (bit 20) updates condition codes
* ADC/SBC/RSC reads the C flag
*/
- insn &= 0xfff00ff0; /* Rn = r0, Rd = r0 */
+ insn &= 0xfff00fff; /* Rn = r0, Rd = r0 */
asi->insn[0] = insn;
asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */
emulate_alu_imm_rwflags : emulate_alu_imm_rflags;
diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c
index 13e371a..5593dd2 100644
--- a/arch/arm/kernel/kprobes.c
+++ b/arch/arm/kernel/kprobes.c
@@ -66,7 +66,7 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
return -ENOMEM;
for (is = 0; is < MAX_INSN_SIZE; ++is)
p->ainsn.insn[is] = tmp_insn[is];
- flush_insns(&p->ainsn.insn, MAX_INSN_SIZE);
+ flush_insns(p->ainsn.insn, MAX_INSN_SIZE);
break;

case INSN_GOOD_NO_SLOT: /* instruction doesn't need insn slot */
diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c
index 42bf09d..9f8c8e1 100644
--- a/arch/sparc/kernel/sys_sparc.c
+++ b/arch/sparc/kernel/sys_sparc.c
@@ -224,8 +224,7 @@ int sparc_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
{
if (ARCH_SUN4C_SUN4 &&
(len > 0x20000000 ||
- ((flags & MAP_FIXED) &&
- addr < 0xe0000000 && addr + len > 0x20000000)))
+ (addr < 0xe0000000 && addr + len > 0x20000000)))
return -EINVAL;

/* See asm-sparc/uaccess.h */
diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c
index f952745..cc37936 100644
--- a/arch/sparc64/kernel/sys_sparc.c
+++ b/arch/sparc64/kernel/sys_sparc.c
@@ -549,13 +549,13 @@ int sparc64_mmap_check(unsigned long addr, unsigned long len,
if (len >= STACK_TOP32)
return -EINVAL;

- if ((flags & MAP_FIXED) && addr > STACK_TOP32 - len)
+ if (addr > STACK_TOP32 - len)
return -EINVAL;
} else {
if (len >= VA_EXCLUDE_START)
return -EINVAL;

- if ((flags & MAP_FIXED) && invalid_64bit_range(addr, len))
+ if (invalid_64bit_range(addr, len))
return -EINVAL;
}

diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 7b6e3bb..05356ce 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -372,13 +372,16 @@ static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = {
{}
};

+void __init dmi_check_pciprobe(void)
+{
+ dmi_check_system(pciprobe_dmi_table);
+}
+
struct pci_bus * __devinit pcibios_scan_root(int busnum)
{
struct pci_bus *bus = NULL;
struct pci_sysdata *sd;

- dmi_check_system(pciprobe_dmi_table);
-
while ((bus = pci_find_next_bus(bus)) != NULL) {
if (bus->number == busnum) {
/* Already scanned */
diff --git a/arch/x86/pci/init.c b/arch/x86/pci/init.c
index 3de9f9b..f1bf4e5 100644
--- a/arch/x86/pci/init.c
+++ b/arch/x86/pci/init.c
@@ -32,6 +32,8 @@ static __init int pci_access_init(void)
printk(KERN_ERR
"PCI: Fatal: No config space access function found\n");

+ dmi_check_pciprobe();
+
return 0;
}
arch_initcall(pci_access_init);
diff --git a/arch/x86/pci/pci.h b/arch/x86/pci/pci.h
index 3431518..95e5675 100644
--- a/arch/x86/pci/pci.h
+++ b/arch/x86/pci/pci.h
@@ -39,6 +39,8 @@ enum pci_bf_sort_state {
pci_dmi_bf,
};

+extern void __init dmi_check_pciprobe(void);
+
/* pci-i386.c */

extern unsigned int pcibios_max_latency;
diff --git a/crypto/authenc.c b/crypto/authenc.c
index ed8ac5a..4b22676 100644
--- a/crypto/authenc.c
+++ b/crypto/authenc.c
@@ -217,9 +217,10 @@ static void crypto_authenc_givencrypt_done(struct crypto_async_request *req,
int err)
{
if (!err) {
- struct aead_givcrypt_request *greq = req->data;
+ struct aead_request *areq = req->data;
+ struct skcipher_givcrypt_request *greq = aead_request_ctx(areq);

- err = crypto_authenc_genicv(&greq->areq, greq->giv, 0);
+ err = crypto_authenc_genicv(areq, greq->giv, 0);
}

aead_request_complete(req->data, err);
diff --git a/crypto/cryptd.c b/crypto/cryptd.c
index 2504252..b150de5 100644
--- a/crypto/cryptd.c
+++ b/crypto/cryptd.c
@@ -190,8 +190,10 @@ static struct crypto_instance *cryptd_alloc_instance(struct crypto_alg *alg,
int err;

inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
- if (IS_ERR(inst))
+ if (!inst) {
+ inst = ERR_PTR(-ENOMEM);
goto out;
+ }

err = -ENAMETOOLONG;
if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME,
diff --git a/crypto/eseqiv.c b/crypto/eseqiv.c
index b14f14e..881d309 100644
--- a/crypto/eseqiv.c
+++ b/crypto/eseqiv.c
@@ -136,7 +136,8 @@ static int eseqiv_givencrypt(struct skcipher_givcrypt_request *req)
}

ablkcipher_request_set_crypt(subreq, reqctx->src, dst,
- req->creq.nbytes, req->creq.info);
+ req->creq.nbytes + ivsize,
+ req->creq.info);

memcpy(req->creq.info, ctx->salt, ivsize);

diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 788da97..836362b 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -848,6 +848,7 @@ static int acpi_processor_get_power_info_default(struct acpi_processor *pr)
/* all processors need to support C1 */
pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1;
pr->power.states[ACPI_STATE_C1].valid = 1;
+ pr->power.states[ACPI_STATE_C1].entry_method = ACPI_CSTATE_HALT;
}
/* the C0 state only exists as a filler in our array */
pr->power.states[ACPI_STATE_C0].valid = 1;
@@ -960,6 +961,9 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
cx.address);
}

+ if (cx.type == ACPI_STATE_C1) {
+ cx.valid = 1;
+ }

obj = &(element->package.elements[2]);
if (obj->type != ACPI_TYPE_INTEGER)
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 61ccbd2..9f6d228 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -2096,7 +2096,7 @@ rdev_attr_store(struct kobject *kobj, struct attribute *attr,
rv = -EBUSY;
else
rv = entry->store(rdev, page, length);
- mddev_unlock(rdev->mddev);
+ mddev_unlock(mddev);
}
return rv;
}
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index f13346b..44ebdea 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -628,6 +628,10 @@ struct b43_wl {

struct mutex mutex;
spinlock_t irq_lock;
+ /* R/W lock for data transmission.
+ * Transmissions on 2+ queues can run concurrently, but somebody else
+ * might sync with TX by write_lock_irqsave()'ing. */
+ rwlock_t tx_lock;
/* Lock for LEDs access. */
spinlock_t leds_lock;
/* Lock for SHM access. */
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index f23317e..e0055d0 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -622,6 +622,7 @@ static void b43_synchronize_irq(struct b43_wldev *dev)
*/
void b43_dummy_transmission(struct b43_wldev *dev)
{
+ struct b43_wl *wl = dev->wl;
struct b43_phy *phy = &dev->phy;
unsigned int i, max_loop;
u16 value;
@@ -648,6 +649,9 @@ void b43_dummy_transmission(struct b43_wldev *dev)
return;
}

+ spin_lock_irq(&wl->irq_lock);
+ write_lock(&wl->tx_lock);
+
for (i = 0; i < 5; i++)
b43_ram_write(dev, i * 4, buffer[i]);

@@ -688,6 +692,9 @@ void b43_dummy_transmission(struct b43_wldev *dev)
}
if (phy->radio_ver == 0x2050 && phy->radio_rev <= 0x5)
b43_radio_write16(dev, 0x0051, 0x0037);
+
+ write_unlock(&wl->tx_lock);
+ spin_unlock_irq(&wl->irq_lock);
}

static void key_write(struct b43_wldev *dev,
@@ -2592,15 +2599,21 @@ static int b43_op_tx(struct ieee80211_hw *hw,
{
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev = wl->current_dev;
- int err = -ENODEV;
+ unsigned long flags;
+ int err;

if (unlikely(!dev))
- goto out;
- if (unlikely(b43_status(dev) < B43_STAT_STARTED))
- goto out;
- /* DMA-TX is done without a global lock. */
- err = b43_dma_tx(dev, skb, ctl);
-out:
+ return NETDEV_TX_BUSY;
+
+ /* Transmissions on seperate queues can run concurrently. */
+ read_lock_irqsave(&wl->tx_lock, flags);
+
+ err = -ENODEV;
+ if (likely(b43_status(dev) >= B43_STAT_STARTED))
+ err = b43_dma_tx(dev, skb, ctl);
+
+ read_unlock_irqrestore(&wl->tx_lock, flags);
+
if (unlikely(err))
return NETDEV_TX_BUSY;
return NETDEV_TX_OK;
@@ -3109,7 +3122,9 @@ static void b43_wireless_core_stop(struct b43_wldev *dev)
spin_unlock_irqrestore(&wl->irq_lock, flags);
b43_synchronize_irq(dev);

+ write_lock_irqsave(&wl->tx_lock, flags);
b43_set_status(dev, B43_STAT_INITIALIZED);
+ write_unlock_irqrestore(&wl->tx_lock, flags);

mutex_unlock(&wl->mutex);
/* Must unlock as it would otherwise deadlock. No races here.
@@ -3117,8 +3132,6 @@ static void b43_wireless_core_stop(struct b43_wldev *dev)
cancel_delayed_work_sync(&dev->periodic_work);
mutex_lock(&wl->mutex);

- ieee80211_stop_queues(wl->hw); //FIXME this could cause a deadlock, as mac80211 seems buggy.
-
b43_mac_suspend(dev);
free_irq(dev->dev->irq, dev);
b43dbg(wl, "Wireless interface stopped\n");
@@ -3912,6 +3925,14 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
err = -EOPNOTSUPP;
goto err_powerdown;
}
+ if (1 /* disable A-PHY */) {
+ /* FIXME: For now we disable the A-PHY on multi-PHY devices. */
+ if (dev->phy.type != B43_PHYTYPE_N) {
+ have_2ghz_phy = 1;
+ have_5ghz_phy = 0;
+ }
+ }
+
dev->phy.gmode = have_2ghz_phy;
tmp = dev->phy.gmode ? B43_TMSLOW_GMODE : 0;
b43_wireless_core_reset(dev, tmp);
@@ -4076,6 +4097,7 @@ static int b43_wireless_init(struct ssb_device *dev)
memset(wl, 0, sizeof(*wl));
wl->hw = hw;
spin_lock_init(&wl->irq_lock);
+ rwlock_init(&wl->tx_lock);
spin_lock_init(&wl->leds_lock);
spin_lock_init(&wl->shm_lock);
mutex_init(&wl->mutex);
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index d93b357..7a3625f 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -1221,8 +1221,8 @@ static struct of_device_id mpc52xx_uart_of_match[] = {
#endif
#ifdef CONFIG_PPC_MPC512x
{ .compatible = "fsl,mpc5121-psc-uart", .data = &mpc512x_psc_ops, },
- {},
#endif
+ {},
};

static int __devinit
diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c
index e0f0f09..9f877ab 100644
--- a/fs/reiserfs/ioctl.c
+++ b/fs/reiserfs/ioctl.c
@@ -11,8 +11,6 @@
#include <linux/smp_lock.h>
#include <linux/compat.h>

-static int reiserfs_unpack(struct inode *inode, struct file *filp);
-
/*
** reiserfs_ioctl - handler for ioctl for inode
** supported commands:
@@ -140,7 +138,7 @@ int reiserfs_prepare_write(struct file *f, struct page *page,
** Function try to convert tail from direct item into indirect.
** It set up nopack attribute in the REISERFS_I(inode)->nopack
*/
-static int reiserfs_unpack(struct inode *inode, struct file *filp)
+int reiserfs_unpack(struct inode *inode, struct file *filp)
{
int retval = 0;
int index;
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 393cc22..3302259 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -2019,6 +2019,7 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
{
int err;
struct nameidata nd;
+ struct inode *inode;

if (!(REISERFS_SB(sb)->s_mount_opt & (1 << REISERFS_QUOTA)))
return -EINVAL;
@@ -2030,12 +2031,18 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
path_put(&nd.path);
return -EXDEV;
}
+ inode = nd.path.dentry->d_inode;
/* We must not pack tails for quota files on reiserfs for quota IO to work */
- if (!(REISERFS_I(nd.path.dentry->d_inode)->i_flags & i_nopack_mask)) {
- reiserfs_warning(sb,
- "reiserfs: Quota file must have tail packing disabled.");
- path_put(&nd.path);
- return -EINVAL;
+ if (!(REISERFS_I(inode)->i_flags & i_nopack_mask)) {
+ err = reiserfs_unpack(inode, NULL);
+ if (err) {
+ reiserfs_warning(sb,
+ "reiserfs: Unpacking tail of quota file failed"
+ " (%d). Cannot turn on quotas.", err);
+ path_put(&nd.path);
+ return -EINVAL;
+ }
+ mark_inode_dirty(inode);
}
/* Not journalling quota? No more tests needed... */
if (!REISERFS_SB(sb)->s_qf_names[USRQUOTA] &&
diff --git a/fs/utimes.c b/fs/utimes.c
index b18da9c..80a481e 100644
--- a/fs/utimes.c
+++ b/fs/utimes.c
@@ -39,9 +39,14 @@ asmlinkage long sys_utime(char __user *filename, struct utimbuf __user *times)

#endif

+static bool nsec_special(long nsec)
+{
+ return nsec == UTIME_OMIT || nsec == UTIME_NOW;
+}
+
static bool nsec_valid(long nsec)
{
- if (nsec == UTIME_OMIT || nsec == UTIME_NOW)
+ if (nsec_special(nsec))
return true;

return nsec >= 0 && nsec <= 999999999;
@@ -115,7 +120,15 @@ long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags
newattrs.ia_mtime.tv_nsec = times[1].tv_nsec;
newattrs.ia_valid |= ATTR_MTIME_SET;
}
- } else {
+ }
+
+ /*
+ * If times is NULL or both times are either UTIME_OMIT or
+ * UTIME_NOW, then need to check permissions, because
+ * inode_change_ok() won't do it.
+ */
+ if (!times || (nsec_special(times[0].tv_nsec) &&
+ nsec_special(times[1].tv_nsec))) {
error = -EACCES;
if (IS_IMMUTABLE(inode))
goto dput_and_out;
diff --git a/include/crypto/scatterwalk.h b/include/crypto/scatterwalk.h
index 224658b..833d208 100644
--- a/include/crypto/scatterwalk.h
+++ b/include/crypto/scatterwalk.h
@@ -57,10 +57,14 @@ static inline void scatterwalk_sg_chain(struct scatterlist *sg1, int num,
struct scatterlist *sg2)
{
sg_set_page(&sg1[num - 1], (void *)sg2, 0, 0);
+ sg1[num - 1].page_link &= ~0x02;
}

static inline struct scatterlist *scatterwalk_sg_next(struct scatterlist *sg)
{
+ if (sg_is_last(sg))
+ return NULL;
+
return (++sg)->length ? sg : (void *)sg_page(sg);
}

diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
index 8e7eff2..4aacaee 100644
--- a/include/linux/reiserfs_fs.h
+++ b/include/linux/reiserfs_fs.h
@@ -2176,6 +2176,7 @@ int reiserfs_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
long reiserfs_compat_ioctl(struct file *filp,
unsigned int cmd, unsigned long arg);
+int reiserfs_unpack(struct inode *inode, struct file *filp);

/* ioctl's command */
#define REISERFS_IOC_UNPACK _IOW(0xCD,1,long)
diff --git a/kernel/sched.c b/kernel/sched.c
index 8dcdec6..1e4596c 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -876,6 +876,7 @@ static inline void resched_rq(struct rq *rq)
enum {
HRTICK_SET, /* re-programm hrtick_timer */
HRTICK_RESET, /* not a new slice */
+ HRTICK_BLOCK, /* stop hrtick operations */
};

/*
@@ -887,6 +888,8 @@ static inline int hrtick_enabled(struct rq *rq)
{
if (!sched_feat(HRTICK))
return 0;
+ if (unlikely(test_bit(HRTICK_BLOCK, &rq->hrtick_flags)))
+ return 0;
return hrtimer_is_hres_active(&rq->hrtick_timer);
}

@@ -969,7 +972,63 @@ static enum hrtimer_restart hrtick(struct hrtimer *timer)
return HRTIMER_NORESTART;
}

-static inline void init_rq_hrtick(struct rq *rq)
+static void hotplug_hrtick_disable(int cpu)
+{
+ struct rq *rq = cpu_rq(cpu);
+ unsigned long flags;
+
+ spin_lock_irqsave(&rq->lock, flags);
+ rq->hrtick_flags = 0;
+ __set_bit(HRTICK_BLOCK, &rq->hrtick_flags);
+ spin_unlock_irqrestore(&rq->lock, flags);
+
+ hrtick_clear(rq);
+}
+
+static void hotplug_hrtick_enable(int cpu)
+{
+ struct rq *rq = cpu_rq(cpu);
+ unsigned long flags;
+
+ spin_lock_irqsave(&rq->lock, flags);
+ __clear_bit(HRTICK_BLOCK, &rq->hrtick_flags);
+ spin_unlock_irqrestore(&rq->lock, flags);
+}
+
+static int
+hotplug_hrtick(struct notifier_block *nfb, unsigned long action, void *hcpu)
+{
+ int cpu = (int)(long)hcpu;
+
+ switch (action) {
+ case CPU_UP_CANCELED:
+ case CPU_UP_CANCELED_FROZEN:
+ case CPU_DOWN_PREPARE:
+ case CPU_DOWN_PREPARE_FROZEN:
+ case CPU_DEAD:
+ case CPU_DEAD_FROZEN:
+ hotplug_hrtick_disable(cpu);
+ return NOTIFY_OK;
+
+ case CPU_UP_PREPARE:
+ case CPU_UP_PREPARE_FROZEN:
+ case CPU_DOWN_FAILED:
+ case CPU_DOWN_FAILED_FROZEN:
+ case CPU_ONLINE:
+ case CPU_ONLINE_FROZEN:
+ hotplug_hrtick_enable(cpu);
+ return NOTIFY_OK;
+ }
+
+ return NOTIFY_DONE;
+}
+
+static void init_hrtick(void)
+{
+ hotcpu_notifier(hotplug_hrtick, 0);
+}
+
+static void init_rq_hrtick(struct rq *rq)
{
rq->hrtick_flags = 0;
hrtimer_init(&rq->hrtick_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
@@ -1006,6 +1065,10 @@ static inline void init_rq_hrtick(struct rq *rq)
void hrtick_resched(void)
{
}
+
+static inline void init_hrtick(void)
+{
+}
#endif

/*
@@ -7094,6 +7157,7 @@ void __init sched_init_smp(void)
put_online_cpus();
/* XXX: Theoretical race here - CPU may be hotplugged now */
hotcpu_notifier(update_sched_domains, 0);
+ init_hrtick();

/* Move init over to a non-isolated CPU */
if (set_cpus_allowed(current, non_isolated_cpus) < 0)
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 402a504..55443c2 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2518,7 +2518,9 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone,
struct page *page;
unsigned long end_pfn = start_pfn + size;
unsigned long pfn;
+ struct zone *z;

+ z = &NODE_DATA(nid)->node_zones[zone];
for (pfn = start_pfn; pfn < end_pfn; pfn++) {
/*
* There can be holes in boot-time mem_map[]s
@@ -2536,7 +2538,6 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone,
init_page_count(page);
reset_page_mapcount(page);
SetPageReserved(page);
-
/*
* Mark the block movable so that blocks are reserved for
* movable at startup. This will force kernel allocations
@@ -2545,8 +2546,15 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone,
* kernel allocations are made. Later some blocks near
* the start are marked MIGRATE_RESERVE by
* setup_zone_migrate_reserve()
+ *
+ * bitmap is created for zone's valid pfn range. but memmap
+ * can be created for invalid pages (for alignment)
+ * check here not to call set_pageblock_migratetype() against
+ * pfn out of zone.
*/
- if ((pfn & (pageblock_nr_pages-1)))
+ if ((z->zone_start_pfn <= pfn)
+ && (pfn < z->zone_start_pfn + z->spanned_pages)
+ && !(pfn & (pageblock_nr_pages - 1)))
set_pageblock_migratetype(page, MIGRATE_MOVABLE);

INIT_LIST_HEAD(&page->lru);
@@ -4460,6 +4468,8 @@ void set_pageblock_flags_group(struct page *page, unsigned long flags,
pfn = page_to_pfn(page);
bitmap = get_pageblock_bitmap(zone, pfn);
bitidx = pfn_to_bitidx(zone, pfn);
+ VM_BUG_ON(pfn < zone->zone_start_pfn);
+ VM_BUG_ON(pfn >= zone->zone_start_pfn + zone->spanned_pages);

for (; start_bitidx <= end_bitidx; start_bitidx++, value <<= 1)
if (flags & value)
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 1656c00..4de86c4 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -446,9 +446,9 @@ static int ipip6_rcv(struct sk_buff *skb)
}

icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
- kfree_skb(skb);
read_unlock(&ipip6_lock);
out:
+ kfree_skb(skb);
return 0;
0 new messages