summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2010-06-28 15:47:04 +0300
committerTony Lindgren <tony@atomide.com>2010-06-28 15:47:04 +0300
commit41bd03ba0758a076671e5de35ed084535984143d (patch)
tree9a669f9f1f52996b38acb077655e4b044bba67c7 /arch
parent090830b4c79cd5ac85430822a9b87c90848bedcf (diff)
parentdc75925d67950889b79df1cc1518c21ec678df6c (diff)
Merge branch 'for_2.6.35rc' of git://git.pwsan.com/linux-2.6 into omap-fixes-for-linus
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/common/sa1111.c9
-rw-r--r--arch/arm/mach-msm/dma.c1
-rw-r--r--arch/arm/mach-nomadik/clock.c11
-rw-r--r--arch/arm/mach-nomadik/clock.h2
-rw-r--r--arch/arm/mach-nomadik/cpu-8815.c8
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c9
-rw-r--r--arch/arm/mach-pxa/palmtc.c4
-rw-r--r--arch/arm/mach-pxa/spitz.c3
-rw-r--r--arch/arm/mach-ux500/Makefile3
-rw-r--r--arch/arm/mach-ux500/clock.c104
-rw-r--r--arch/arm/mach-ux500/clock.h22
-rw-r--r--arch/arm/mach-ux500/cpu.c6
-rw-r--r--arch/arm/mm/copypage-feroceon.c4
-rw-r--r--arch/arm/mm/copypage-v4wb.c4
-rw-r--r--arch/arm/mm/copypage-v4wt.c4
-rw-r--r--arch/arm/mm/copypage-xsc3.c4
-rw-r--r--arch/arm/mm/fault.c3
-rw-r--r--arch/arm/mm/highmem.c11
-rw-r--r--arch/arm/mm/init.c6
-rw-r--r--arch/arm/plat-nomadik/timer.c26
-rw-r--r--arch/arm/vfp/vfphw.S2
-rw-r--r--arch/frv/kernel/gdb-stub.c6
-rw-r--r--arch/ia64/kvm/kvm-ia64.c1
-rw-r--r--arch/microblaze/include/asm/page.h2
-rw-r--r--arch/microblaze/kernel/dma.c1
-rw-r--r--arch/microblaze/pci/pci-common.c1
-rw-r--r--arch/mn10300/unit-asb2305/pci-asb2305.c1
-rw-r--r--arch/powerpc/kernel/pci-common.c1
-rw-r--r--arch/powerpc/kvm/e500.c2
-rw-r--r--arch/powerpc/oprofile/op_model_cell.c2
-rw-r--r--arch/s390/appldata/appldata_os.c2
-rw-r--r--arch/s390/defconfig23
-rw-r--r--arch/s390/kernel/module.c6
-rw-r--r--arch/s390/kvm/kvm-s390.c2
-rw-r--r--arch/s390/kvm/sigp.c2
-rw-r--r--arch/s390/mm/extmem.c19
-rw-r--r--arch/x86/include/asm/msr-index.h1
-rw-r--r--arch/x86/include/asm/suspend_32.h2
-rw-r--r--arch/x86/include/asm/suspend_64.h2
-rw-r--r--arch/x86/kvm/mmu.c5
-rw-r--r--arch/x86/kvm/svm.c96
-rw-r--r--arch/x86/pci/i386.c2
-rw-r--r--arch/x86/power/cpu.c4
43 files changed, 368 insertions, 61 deletions
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index a52a27c1d9b..6f80665f477 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -951,8 +951,6 @@ static int sa1111_resume(struct platform_device *dev)
if (!save)
return 0;
- spin_lock_irqsave(&sachip->lock, flags);
-
/*
* Ensure that the SA1111 is still here.
* FIXME: shouldn't do this here.
@@ -969,6 +967,13 @@ static int sa1111_resume(struct platform_device *dev)
* First of all, wake up the chip.
*/
sa1111_wake(sachip);
+
+ /*
+ * Only lock for write ops. Also, sa1111_wake must be called with
+ * released spinlock!
+ */
+ spin_lock_irqsave(&sachip->lock, flags);
+
sa1111_writel(0, sachip->base + SA1111_INTC + SA1111_INTEN0);
sa1111_writel(0, sachip->base + SA1111_INTC + SA1111_INTEN1);
diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c
index d029d1f5f9e..02cae5e2951 100644
--- a/arch/arm/mach-msm/dma.c
+++ b/arch/arm/mach-msm/dma.c
@@ -17,6 +17,7 @@
#include <linux/err.h>
#include <linux/io.h>
#include <linux/interrupt.h>
+#include <linux/completion.h>
#include <mach/dma.h>
#define MSM_DMOV_CHANNEL_COUNT 16
diff --git a/arch/arm/mach-nomadik/clock.c b/arch/arm/mach-nomadik/clock.c
index 2c471fc451d..f035f418527 100644
--- a/arch/arm/mach-nomadik/clock.c
+++ b/arch/arm/mach-nomadik/clock.c
@@ -32,7 +32,10 @@ void clk_disable(struct clk *clk)
}
EXPORT_SYMBOL(clk_disable);
-/* We have a fixed clock alone, for now */
+static struct clk clk_24 = {
+ .rate = 2400000,
+};
+
static struct clk clk_48 = {
.rate = 48 * 1000 * 1000,
};
@@ -50,6 +53,8 @@ static struct clk clk_default;
}
static struct clk_lookup lookups[] = {
+ CLK(&clk_24, "mtu0"),
+ CLK(&clk_24, "mtu1"),
CLK(&clk_48, "uart0"),
CLK(&clk_48, "uart1"),
CLK(&clk_default, "gpio.0"),
@@ -59,10 +64,8 @@ static struct clk_lookup lookups[] = {
CLK(&clk_default, "rng"),
};
-static int __init clk_init(void)
+int __init clk_init(void)
{
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
return 0;
}
-
-arch_initcall(clk_init);
diff --git a/arch/arm/mach-nomadik/clock.h b/arch/arm/mach-nomadik/clock.h
index 5563985a2cc..78da2e7c398 100644
--- a/arch/arm/mach-nomadik/clock.h
+++ b/arch/arm/mach-nomadik/clock.h
@@ -11,3 +11,5 @@
struct clk {
unsigned long rate;
};
+
+int __init clk_init(void);
diff --git a/arch/arm/mach-nomadik/cpu-8815.c b/arch/arm/mach-nomadik/cpu-8815.c
index 91c3c901b46..ac58e3b03b1 100644
--- a/arch/arm/mach-nomadik/cpu-8815.c
+++ b/arch/arm/mach-nomadik/cpu-8815.c
@@ -31,6 +31,8 @@
#include <asm/cacheflush.h>
#include <asm/hardware/cache-l2x0.h>
+#include "clock.h"
+
#define __MEM_4K_RESOURCE(x) \
.res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM}
@@ -143,6 +145,12 @@ void __init cpu8815_init_irq(void)
/* This modified VIC cell has two register blocks, at 0 and 0x20 */
vic_init(io_p2v(NOMADIK_IC_BASE + 0x00), IRQ_VIC_START + 0, ~0, 0);
vic_init(io_p2v(NOMADIK_IC_BASE + 0x20), IRQ_VIC_START + 32, ~0, 0);
+
+ /*
+ * Init clocks here so that they are available for system timer
+ * initialization.
+ */
+ clk_init();
}
/*
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 95c9a5f774e..b7a4133267d 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -409,10 +409,11 @@ static int _init_main_clk(struct omap_hwmod *oh)
return 0;
oh->_clk = omap_clk_get_by_name(oh->main_clk);
- if (!oh->_clk)
+ if (!oh->_clk) {
pr_warning("omap_hwmod: %s: cannot clk_get main_clk %s\n",
oh->name, oh->main_clk);
return -EINVAL;
+ }
if (!oh->_clk->clkdm)
pr_warning("omap_hwmod: %s: missing clockdomain for %s.\n",
@@ -444,10 +445,11 @@ static int _init_interface_clks(struct omap_hwmod *oh)
continue;
c = omap_clk_get_by_name(os->clk);
- if (!c)
+ if (!c) {
pr_warning("omap_hwmod: %s: cannot clk_get interface_clk %s\n",
oh->name, os->clk);
ret = -EINVAL;
+ }
os->_clk = c;
}
@@ -470,10 +472,11 @@ static int _init_opt_clks(struct omap_hwmod *oh)
for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) {
c = omap_clk_get_by_name(oc->clk);
- if (!c)
+ if (!c) {
pr_warning("omap_hwmod: %s: cannot clk_get opt_clk %s\n",
oh->name, oc->clk);
ret = -EINVAL;
+ }
oc->_clk = c;
}
diff --git a/arch/arm/mach-pxa/palmtc.c b/arch/arm/mach-pxa/palmtc.c
index 033b567e50b..ce1104d1bc1 100644
--- a/arch/arm/mach-pxa/palmtc.c
+++ b/arch/arm/mach-pxa/palmtc.c
@@ -263,11 +263,11 @@ const struct matrix_keymap_data palmtc_keymap_data = {
.keymap_size = ARRAY_SIZE(palmtc_matrix_keys),
};
-const static unsigned int palmtc_keypad_row_gpios[] = {
+static const unsigned int palmtc_keypad_row_gpios[] = {
0, 9, 10, 11
};
-const static unsigned int palmtc_keypad_col_gpios[] = {
+static const unsigned int palmtc_keypad_col_gpios[] = {
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 79, 80
};
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 4d2413ed0ff..c1048a35f18 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -818,6 +818,9 @@ static struct i2c_board_info akita_i2c_board_info[] = {
.type = "max7310",
.addr = 0x18,
.platform_data = &akita_ioexp,
+ }, {
+ .type = "wm8750",
+ .addr = 0x1b,
},
};
diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile
index c7bc4199e3a..4556aea9c3c 100644
--- a/arch/arm/mach-ux500/Makefile
+++ b/arch/arm/mach-ux500/Makefile
@@ -7,4 +7,5 @@ obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o devices-db5500.o
obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o
obj-$(CONFIG_MACH_U8500_MOP) += board-mop500.o
obj-$(CONFIG_MACH_U5500) += board-u5500.o
-obj-$(CONFIG_SMP) += platsmp.o headsmp.o localtimer.o
+obj-$(CONFIG_SMP) += platsmp.o headsmp.o
+obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c
index 6544855af2f..fe84b9021c7 100644
--- a/arch/arm/mach-ux500/clock.c
+++ b/arch/arm/mach-ux500/clock.c
@@ -16,6 +16,7 @@
#include <asm/clkdev.h>
+#include <plat/mtu.h>
#include <mach/hardware.h>
#include "clock.h"
@@ -59,6 +60,9 @@
#define PRCM_DMACLK_MGT 0x074
#define PRCM_B2R2CLK_MGT 0x078
#define PRCM_TVCLK_MGT 0x07C
+#define PRCM_TCR 0x1C8
+#define PRCM_TCR_STOPPED (1 << 16)
+#define PRCM_TCR_DOZE_MODE (1 << 17)
#define PRCM_UNIPROCLK_MGT 0x278
#define PRCM_SSPCLK_MGT 0x280
#define PRCM_RNGCLK_MGT 0x284
@@ -120,10 +124,95 @@ void clk_disable(struct clk *clk)
}
EXPORT_SYMBOL(clk_disable);
+/*
+ * The MTU has a separate, rather complex muxing setup
+ * with alternative parents (peripheral cluster or
+ * ULP or fixed 32768 Hz) depending on settings
+ */
+static unsigned long clk_mtu_get_rate(struct clk *clk)
+{
+ void __iomem *addr = __io_address(U8500_PRCMU_BASE)
+ + PRCM_TCR;
+ u32 tcr = readl(addr);
+ int mtu = (int) clk->data;
+ /*
+ * One of these is selected eventually
+ * TODO: Replace the constant with a reference
+ * to the ULP source once this is modeled.
+ */
+ unsigned long clk32k = 32768;
+ unsigned long mturate;
+ unsigned long retclk;
+
+ /* Get the rate from the parent as a default */
+ if (clk->parent_periph)
+ mturate = clk_get_rate(clk->parent_periph);
+ else if (clk->parent_cluster)
+ mturate = clk_get_rate(clk->parent_cluster);
+ else
+ /* We need to be connected SOMEWHERE */
+ BUG();
+
+ /*
+ * Are we in doze mode?
+ * In this mode the parent peripheral or the fixed 32768 Hz
+ * clock is fed into the block.
+ */
+ if (!(tcr & PRCM_TCR_DOZE_MODE)) {
+ /*
+ * Here we're using the clock input from the APE ULP
+ * clock domain. But first: are the timers stopped?
+ */
+ if (tcr & PRCM_TCR_STOPPED) {
+ clk32k = 0;
+ mturate = 0;
+ } else {
+ /* Else default mode: 0 and 2.4 MHz */
+ clk32k = 0;
+ if (cpu_is_u5500())
+ /* DB5500 divides by 8 */
+ mturate /= 8;
+ else if (cpu_is_u8500ed()) {
+ /*
+ * This clocking setting must not be used
+ * in the ED chip, it is simply not
+ * connected anywhere!
+ */
+ mturate = 0;
+ BUG();
+ } else
+ /*
+ * In this mode the ulp38m4 clock is divided
+ * by a factor 16, on the DB8500 typically
+ * 38400000 / 16 ~ 2.4 MHz.
+ * TODO: Replace the constant with a reference
+ * to the ULP source once this is modeled.
+ */
+ mturate = 38400000 / 16;
+ }
+ }
+
+ /* Return the clock selected for this MTU */
+ if (tcr & (1 << mtu))
+ retclk = clk32k;
+ else
+ retclk = mturate;
+
+ pr_info("MTU%d clock rate: %lu Hz\n", mtu, retclk);
+ return retclk;
+}
+
unsigned long clk_get_rate(struct clk *clk)
{
unsigned long rate;
+ /*
+ * If there is a custom getrate callback for this clock,
+ * it will take precedence.
+ */
+ if (clk->get_rate)
+ return clk->get_rate(clk);
+
if (clk->ops && clk->ops->get_rate)
return clk->ops->get_rate(clk);
@@ -341,8 +430,9 @@ static DEFINE_PRCC_CLK(5, usb_v1, 0, 0, NULL);
/* Peripheral Cluster #6 */
-static DEFINE_PRCC_CLK(6, mtu1_v1, 8, -1, NULL);
-static DEFINE_PRCC_CLK(6, mtu0_v1, 7, -1, NULL);
+/* MTU ID in data */
+static DEFINE_PRCC_CLK_CUSTOM(6, mtu1_v1, 8, -1, NULL, clk_mtu_get_rate, 1);
+static DEFINE_PRCC_CLK_CUSTOM(6, mtu0_v1, 7, -1, NULL, clk_mtu_get_rate, 0);
static DEFINE_PRCC_CLK(6, cfgreg_v1, 6, 6, NULL);
static DEFINE_PRCC_CLK(6, dmc_ed, 6, 6, NULL);
static DEFINE_PRCC_CLK(6, hash1, 5, -1, NULL);
@@ -357,8 +447,9 @@ static DEFINE_PRCC_CLK(6, rng_v1, 0, 0, &clk_rngclk);
/* Peripheral Cluster #7 */
static DEFINE_PRCC_CLK(7, tzpc0_ed, 4, -1, NULL);
-static DEFINE_PRCC_CLK(7, mtu1_ed, 3, -1, NULL);
-static DEFINE_PRCC_CLK(7, mtu0_ed, 2, -1, NULL);
+/* MTU ID in data */
+static DEFINE_PRCC_CLK_CUSTOM(7, mtu1_ed, 3, -1, NULL, clk_mtu_get_rate, 1);
+static DEFINE_PRCC_CLK_CUSTOM(7, mtu0_ed, 2, -1, NULL, clk_mtu_get_rate, 0);
static DEFINE_PRCC_CLK(7, wdg_ed, 1, -1, NULL);
static DEFINE_PRCC_CLK(7, cfgreg_ed, 0, -1, NULL);
@@ -503,15 +594,17 @@ static struct clk_lookup u8500_v1_clks[] = {
CLK(uiccclk, "uicc", NULL),
};
-static int __init clk_init(void)
+int __init clk_init(void)
{
if (cpu_is_u8500ed()) {
clk_prcmu_ops.enable = clk_prcmu_ed_enable;
clk_prcmu_ops.disable = clk_prcmu_ed_disable;
+ clk_per6clk.rate = 100000000;
} else if (cpu_is_u5500()) {
/* Clock tree for U5500 not implemented yet */
clk_prcc_ops.enable = clk_prcc_ops.disable = NULL;
clk_prcmu_ops.enable = clk_prcmu_ops.disable = NULL;
+ clk_per6clk.rate = 26000000;
}
clkdev_add_table(u8500_common_clks, ARRAY_SIZE(u8500_common_clks));
@@ -522,4 +615,3 @@ static int __init clk_init(void)
return 0;
}
-arch_initcall(clk_init);
diff --git a/arch/arm/mach-ux500/clock.h b/arch/arm/mach-ux500/clock.h
index e4f99b65026..a0580250152 100644
--- a/arch/arm/mach-ux500/clock.h
+++ b/arch/arm/mach-ux500/clock.h
@@ -28,6 +28,9 @@ struct clkops {
* @ops: pointer to clkops struct used to control this clock
* @name: name, for debugging
* @enabled: refcount. positive if enabled, zero if disabled
+ * @get_rate: custom callback for getting the clock rate
+ * @data: custom per-clock data for example for the get_rate
+ * callback
* @rate: fixed rate for clocks which don't implement
* ops->getrate
* @prcmu_cg_off: address offset of the combined enable/disable register
@@ -67,6 +70,8 @@ struct clk {
const struct clkops *ops;
const char *name;
unsigned int enabled;
+ unsigned long (*get_rate)(struct clk *);
+ void *data;
unsigned long rate;
struct list_head list;
@@ -117,9 +122,26 @@ struct clk clk_##_name = { \
.parent_periph = _kernclk \
}
+#define DEFINE_PRCC_CLK_CUSTOM(_pclust, _name, _bus_en, _kernel_en, _kernclk, _callback, _data) \
+struct clk clk_##_name = { \
+ .name = #_name, \
+ .ops = &clk_prcc_ops, \
+ .cluster = _pclust, \
+ .prcc_bus = _bus_en, \
+ .prcc_kernel = _kernel_en, \
+ .parent_cluster = &clk_per##_pclust##clk, \
+ .parent_periph = _kernclk, \
+ .get_rate = _callback, \
+ .data = (void *) _data \
+ }
+
+
#define CLK(_clk, _devname, _conname) \
{ \
.clk = &clk_##_clk, \
.dev_id = _devname, \
.con_id = _conname, \
}
+
+int __init clk_db8500_ed_fixup(void);
+int __init clk_init(void);
diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c
index d81ad023963..e0fd747e447 100644
--- a/arch/arm/mach-ux500/cpu.c
+++ b/arch/arm/mach-ux500/cpu.c
@@ -62,6 +62,12 @@ void __init ux500_init_irq(void)
{
gic_dist_init(0, __io_address(UX500_GIC_DIST_BASE), 29);
gic_cpu_init(0, __io_address(UX500_GIC_CPU_BASE));
+
+ /*
+ * Init clocks here so that they are available for system timer
+ * initialization.
+ */
+ clk_init();
}
#ifdef CONFIG_CACHE_L2X0
diff --git a/arch/arm/mm/copypage-feroceon.c b/arch/arm/mm/copypage-feroceon.c
index 5eb4fd93893..ac163de7dc0 100644
--- a/arch/arm/mm/copypage-feroceon.c
+++ b/arch/arm/mm/copypage-feroceon.c
@@ -18,7 +18,7 @@ feroceon_copy_user_page(void *kto, const void *kfrom)
{
asm("\
stmfd sp!, {r4-r9, lr} \n\
- mov ip, %0 \n\
+ mov ip, %2 \n\
1: mov lr, r1 \n\
ldmia r1!, {r2 - r9} \n\
pld [lr, #32] \n\
@@ -64,7 +64,7 @@ feroceon_copy_user_page(void *kto, const void *kfrom)
mcr p15, 0, ip, c7, c10, 4 @ drain WB\n\
ldmfd sp!, {r4-r9, pc}"
:
- : "I" (PAGE_SIZE));
+ : "r" (kto), "r" (kfrom), "I" (PAGE_SIZE));
}
void feroceon_copy_user_highpage(struct page *to, struct page *from,
diff --git a/arch/arm/mm/copypage-v4wb.c b/arch/arm/mm/copypage-v4wb.c
index 7c2eb55cd4a..cb589cbb2b6 100644
--- a/arch/arm/mm/copypage-v4wb.c
+++ b/arch/arm/mm/copypage-v4wb.c
@@ -27,7 +27,7 @@ v4wb_copy_user_page(void *kto, const void *kfrom)
{
asm("\
stmfd sp!, {r4, lr} @ 2\n\
- mov r2, %0 @ 1\n\
+ mov r2, %2 @ 1\n\
ldmia r1!, {r3, r4, ip, lr} @ 4\n\
1: mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line\n\
stmia r0!, {r3, r4, ip, lr} @ 4\n\
@@ -44,7 +44,7 @@ v4wb_copy_user_page(void *kto, const void *kfrom)
mcr p15, 0, r1, c7, c10, 4 @ 1 drain WB\n\
ldmfd sp!, {r4, pc} @ 3"
:
- : "I" (PAGE_SIZE / 64));
+ : "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64));
}
void v4wb_copy_user_highpage(struct page *to, struct page *from,
diff --git a/arch/arm/mm/copypage-v4wt.c b/arch/arm/mm/copypage-v4wt.c
index 172e6a55458..30c7d048a32 100644
--- a/arch/arm/mm/copypage-v4wt.c
+++ b/arch/arm/mm/copypage-v4wt.c
@@ -25,7 +25,7 @@ v4wt_copy_user_page(void *kto, const void *kfrom)
{
asm("\
stmfd sp!, {r4, lr} @ 2\n\
- mov r2, %0 @ 1\n\
+ mov r2, %2 @ 1\n\
ldmia r1!, {r3, r4, ip, lr} @ 4\n\
1: stmia r0!, {r3, r4, ip, lr} @ 4\n\
ldmia r1!, {r3, r4, ip, lr} @ 4+1\n\
@@ -40,7 +40,7 @@ v4wt_copy_user_page(void *kto, const void *kfrom)
mcr p15, 0, r2, c7, c7, 0 @ flush ID cache\n\
ldmfd sp!, {r4, pc} @ 3"
:
- : "I" (PAGE_SIZE / 64));
+ : "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64));
}
void v4wt_copy_user_highpage(struct page *to, struct page *from,
diff --git a/arch/arm/mm/copypage-xsc3.c b/arch/arm/mm/copypage-xsc3.c
index 747ad4140fc..f9cde0702f1 100644
--- a/arch/arm/mm/copypage-xsc3.c
+++ b/arch/arm/mm/copypage-xsc3.c
@@ -34,7 +34,7 @@ xsc3_mc_copy_user_page(void *kto, const void *kfrom)
{
asm("\
stmfd sp!, {r4, r5, lr} \n\
- mov lr, %0 \n\
+ mov lr, %2 \n\
\n\
pld [r1, #0] \n\
pld [r1, #32] \n\
@@ -67,7 +67,7 @@ xsc3_mc_copy_user_page(void *kto, const void *kfrom)
\n\
ldmfd sp!, {r4, r5, pc}"
:
- : "I" (PAGE_SIZE / 64 - 1));
+ : "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64 - 1));
}
void xsc3_mc_copy_user_highpage(struct page *to, struct page *from,
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 92f5801f99c..cbfb2edcf7d 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -393,6 +393,9 @@ do_translation_fault(unsigned long addr, unsigned int fsr,
if (addr < TASK_SIZE)
return do_page_fault(addr, fsr, regs);
+ if (user_mode(regs))
+ goto bad_area;
+
index = pgd_index(addr);
/*
diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
index 77b030f5ec0..086816b205b 100644
--- a/arch/arm/mm/highmem.c
+++ b/arch/arm/mm/highmem.c
@@ -48,7 +48,16 @@ void *kmap_atomic(struct page *page, enum km_type type)
debug_kmap_atomic(type);
- kmap = kmap_high_get(page);
+#ifdef CONFIG_DEBUG_HIGHMEM
+ /*
+ * There is no cache coherency issue when non VIVT, so force the
+ * dedicated kmap usage for better debugging purposes in that case.
+ */
+ if (!cache_is_vivt())
+ kmap = NULL;
+ else
+#endif
+ kmap = kmap_high_get(page);
if (kmap)
return kmap;
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 1ba6cf5a2c0..f6a99946532 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -678,10 +678,10 @@ void __init mem_init(void)
void free_initmem(void)
{
#ifdef CONFIG_HAVE_TCM
- extern char *__tcm_start, *__tcm_end;
+ extern char __tcm_start, __tcm_end;
- totalram_pages += free_area(__phys_to_pfn(__pa(__tcm_start)),
- __phys_to_pfn(__pa(__tcm_end)),
+ totalram_pages += free_area(__phys_to_pfn(__pa(&__tcm_start)),
+ __phys_to_pfn(__pa(&__tcm_end)),
"TCM link");
#endif
diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c
index 0ff3798769a..08aaa4a7f65 100644
--- a/arch/arm/plat-nomadik/timer.c
+++ b/arch/arm/plat-nomadik/timer.c
@@ -13,7 +13,9 @@
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/clockchips.h>
+#include <linux/clk.h>
#include <linux/jiffies.h>
+#include <linux/err.h>
#include <asm/mach/time.h>
#include <plat/mtu.h>
@@ -124,13 +126,25 @@ static struct irqaction nmdk_timer_irq = {
void __init nmdk_timer_init(void)
{
unsigned long rate;
- u32 cr = MTU_CRn_32BITS;;
+ struct clk *clk0;
+ struct clk *clk1;
+ u32 cr;
+
+ clk0 = clk_get_sys("mtu0", NULL);
+ BUG_ON(IS_ERR(clk0));
+
+ clk1 = clk_get_sys("mtu1", NULL);
+ BUG_ON(IS_ERR(clk1));
+
+ clk_enable(clk0);
+ clk_enable(clk1);
/*
* Tick rate is 2.4MHz for Nomadik and 110MHz for ux500:
* use a divide-by-16 counter if it's more than 16MHz
*/
- rate = CLOCK_TICK_RATE;
+ cr = MTU_CRn_32BITS;;
+ rate = clk_get_rate(clk0);
if (rate > 16 << 20) {
rate /= 16;
cr |= MTU_CRn_PRESCALE_16;
@@ -153,6 +167,14 @@ void __init nmdk_timer_init(void)
nmdk_clksrc.name);
/* Timer 1 is used for events, fix according to rate */
+ cr = MTU_CRn_32BITS;
+ rate = clk_get_rate(clk1);
+ if (rate > 16 << 20) {
+ rate /= 16;
+ cr |= MTU_CRn_PRESCALE_16;
+ } else {
+ cr |= MTU_CRn_PRESCALE_1;
+ }
writel(cr | MTU_CRn_ONESHOT, mtu_base + MTU_CR(1)); /* off, currently */
nmdk_clkevt.mult = div_sc(rate, NSEC_PER_SEC, nmdk_clkevt.shift);
nmdk_clkevt.max_delta_ns =
diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S
index 66dc2d03b7f..d66cead97d2 100644
--- a/arch/arm/vfp/vfphw.S
+++ b/arch/arm/vfp/vfphw.S
@@ -277,7 +277,7 @@ ENTRY(vfp_put_double)
#ifdef CONFIG_VFPv3
@ d16 - d31 registers
.irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
-1: mcrr p11, 3, r1, r2, c\dr @ fmdrr r1, r2, d\dr
+1: mcrr p11, 3, r0, r1, c\dr @ fmdrr r0, r1, d\dr
mov pc, lr
.org 1b + 8
.endr
diff --git a/arch/frv/kernel/gdb-stub.c b/arch/frv/kernel/gdb-stub.c
index 84d103c33c9..a4dba6b20bd 100644
--- a/arch/frv/kernel/gdb-stub.c
+++ b/arch/frv/kernel/gdb-stub.c
@@ -1789,6 +1789,12 @@ void gdbstub(int sigval)
flush_cache = 1;
break;
+ /* pNN: Read value of reg N and return it */
+ case 'p':
+ /* return no value, indicating that we don't support
+ * this command and that gdb should use 'g' instead */
+ break;
+
/* PNN,=RRRRRRRR: Write value R to reg N return OK */
case 'P':
ptr = &input_buffer[1];
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index d5f4e916120..21b701374f7 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -144,6 +144,7 @@ int kvm_arch_hardware_enable(void *garbage)
VP_INIT_ENV : VP_INIT_ENV_INITALIZE,
__pa(kvm_vm_buffer), KVM_VM_BUFFER_BASE, &tmp_base);
if (status != 0) {
+ spin_unlock(&vp_lock);
printk(KERN_WARNING"kvm: Failed to Enable VT Support!!!!\n");
return -EINVAL;
}
diff --git a/arch/microblaze/include/asm/page.h b/arch/microblaze/include/asm/page.h
index de493f86d28..464ff32bee3 100644
--- a/arch/microblaze/include/asm/page.h
+++ b/arch/microblaze/include/asm/page.h
@@ -34,6 +34,8 @@
/* MS be sure that SLAB allocates aligned objects */
#define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES
+#define ARCH_SLAB_MINALIGN L1_CACHE_BYTES
+
#define PAGE_UP(addr) (((addr)+((PAGE_SIZE)-1))&(~((PAGE_SIZE)-1)))
#define PAGE_DOWN(addr) ((addr)&(~((PAGE_SIZE)-1)))
diff --git a/arch/microblaze/kernel/dma.c b/arch/microblaze/kernel/dma.c
index 9dcd90b5df5..79c74659f20 100644
--- a/arch/microblaze/kernel/dma.c
+++ b/arch/microblaze/kernel/dma.c
@@ -90,7 +90,6 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
/* FIXME this part of code is untested */
for_each_sg(sgl, sg, nents, i) {
sg->dma_address = sg_phys(sg) + get_dma_direct_offset(dev);
- sg->dma_length = sg->length;
__dma_sync_page(page_to_phys(sg_page(sg)), sg->offset,
sg->length, direction);
}
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index 9cb782b8e03..23be25fec4d 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -1277,6 +1277,7 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus)
printk(KERN_WARNING "PCI: Cannot allocate resource region "
"%d of PCI bridge %d, will remap\n", i, bus->number);
clear_resource:
+ res->start = res->end = 0;
res->flags = 0;
}
diff --git a/arch/mn10300/unit-asb2305/pci-asb2305.c b/arch/mn10300/unit-asb2305/pci-asb2305.c
index d6119b879a9..45b40ac6c46 100644
--- a/arch/mn10300/unit-asb2305/pci-asb2305.c
+++ b/arch/mn10300/unit-asb2305/pci-asb2305.c
@@ -117,6 +117,7 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
* Invalidate the resource to prevent
* child resource allocations in this
* range. */
+ r->start = r->end = 0;
r->flags = 0;
}
}
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 6646005dffb..5b38f6ae2b2 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1309,6 +1309,7 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus)
printk(KERN_WARNING "PCI: Cannot allocate resource region "
"%d of PCI bridge %d, will remap\n", i, bus->number);
clear_resource:
+ res->start = res->end = 0;
res->flags = 0;
}
diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
index bc2b4004eb2..e8a00b0c444 100644
--- a/arch/powerpc/kvm/e500.c
+++ b/arch/powerpc/kvm/e500.c
@@ -164,7 +164,7 @@ static int __init kvmppc_e500_init(void)
return kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), 0, THIS_MODULE);
}
-static void __init kvmppc_e500_exit(void)
+static void __exit kvmppc_e500_exit(void)
{
kvmppc_booke_exit();
}
diff --git a/arch/powerpc/oprofile/op_model_cell.c b/arch/powerpc/oprofile/op_model_cell.c
index 2c9e5226729..7fd90d02d8c 100644
--- a/arch/powerpc/oprofile/op_model_cell.c
+++ b/arch/powerpc/oprofile/op_model_cell.c
@@ -1077,7 +1077,7 @@ static int calculate_lfsr(int n)
index = ENTRIES-1;
/* make sure index is valid */
- if ((index > ENTRIES) || (index < 0))
+ if ((index >= ENTRIES) || (index < 0))
index = ENTRIES-1;
return initial_lfsr[index];
diff --git a/arch/s390/appldata/appldata_os.c b/arch/s390/appldata/appldata_os.c
index 55c80ffd42b..92f1cb745d6 100644
--- a/arch/s390/appldata/appldata_os.c
+++ b/arch/s390/appldata/appldata_os.c
@@ -181,7 +181,7 @@ static int __init appldata_os_init(void)
goto out;
}
- appldata_os_data = kzalloc(max_size, GFP_DMA);
+ appldata_os_data = kzalloc(max_size, GFP_KERNEL | GFP_DMA);
if (appldata_os_data == NULL) {
rc = -ENOMEM;
goto out;
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index bcd6884985a..253f158db66 100644
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.34-rc3
-# Fri Apr 9 09:57:10 2010
+# Linux kernel version: 2.6.35-rc1
+# Fri Jun 4 11:32:40 2010
#
CONFIG_SCHED_MC=y
CONFIG_MMU=y
@@ -35,11 +35,13 @@ CONFIG_CONSTRUCTORS=y
CONFIG_EXPERIMENTAL=y
CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_BZIP2=y
CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
CONFIG_KERNEL_GZIP=y
# CONFIG_KERNEL_BZIP2 is not set
# CONFIG_KERNEL_LZMA is not set
@@ -77,6 +79,7 @@ CONFIG_CGROUP_NS=y
# CONFIG_CGROUP_CPUACCT is not set
# CONFIG_RESOURCE_COUNTERS is not set
# CONFIG_CGROUP_SCHED is not set
+# CONFIG_BLK_CGROUP is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -157,7 +160,6 @@ CONFIG_STOP_MACHINE=y
CONFIG_BLOCK=y
CONFIG_BLK_DEV_BSG=y
# CONFIG_BLK_DEV_INTEGRITY is not set
-# CONFIG_BLK_CGROUP is not set
CONFIG_BLOCK_COMPAT=y
#
@@ -166,7 +168,6 @@ CONFIG_BLOCK_COMPAT=y
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
-# CONFIG_CFQ_GROUP_IOSCHED is not set
CONFIG_DEFAULT_DEADLINE=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
@@ -247,7 +248,6 @@ CONFIG_64BIT=y
CONFIG_SMP=y
CONFIG_NR_CPUS=32
CONFIG_HOTPLUG_CPU=y
-# CONFIG_SCHED_BOOK is not set
CONFIG_COMPAT=y
CONFIG_SYSVIPC_COMPAT=y
CONFIG_AUDIT_ARCH=y
@@ -320,7 +320,6 @@ CONFIG_COMPAT_BINFMT_ELF=y
# CONFIG_HAVE_AOUT is not set
CONFIG_BINFMT_MISC=m
CONFIG_FORCE_MAX_ZONEORDER=9
-# CONFIG_PROCESS_DEBUG is not set
CONFIG_PFAULT=y
# CONFIG_SHARED_KERNEL is not set
# CONFIG_CMM is not set
@@ -457,6 +456,7 @@ CONFIG_NF_CONNTRACK=m
# CONFIG_IP6_NF_IPTABLES is not set
# CONFIG_IP_DCCP is not set
CONFIG_IP_SCTP=m
+# CONFIG_NET_SCTPPROBE is not set
# CONFIG_SCTP_DBG_MSG is not set
# CONFIG_SCTP_DBG_OBJCNT is not set
# CONFIG_SCTP_HMAC_NONE is not set
@@ -465,6 +465,7 @@ CONFIG_SCTP_HMAC_MD5=y
# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
# CONFIG_BRIDGE is not set
# CONFIG_VLAN_8021Q is not set
# CONFIG_DECNET is not set
@@ -525,6 +526,7 @@ CONFIG_NET_ACT_NAT=m
# CONFIG_NET_CLS_IND is not set
CONFIG_NET_SCH_FIFO=y
# CONFIG_DCB is not set
+CONFIG_RPS=y
#
# Network testing
@@ -546,6 +548,7 @@ CONFIG_CAN_VCAN=m
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
# CONFIG_PCMCIA is not set
CONFIG_CCW=y
@@ -728,6 +731,7 @@ CONFIG_VIRTIO_NET=m
# Character devices
#
CONFIG_DEVKMEM=y
+# CONFIG_N_GSM is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
CONFIG_LEGACY_PTYS=y
@@ -775,6 +779,7 @@ CONFIG_S390_TAPE_34XX=m
# CONFIG_MONREADER is not set
CONFIG_MONWRITER=m
CONFIG_S390_VMUR=m
+# CONFIG_RAMOOPS is not set
#
# PPS support
@@ -788,10 +793,6 @@ CONFIG_S390_VMUR=m
# CONFIG_NEW_LEDS is not set
CONFIG_ACCESSIBILITY=y
# CONFIG_AUXDISPLAY is not set
-
-#
-# TI VLYNQ
-#
# CONFIG_STAGING is not set
#
@@ -976,6 +977,7 @@ CONFIG_DEBUG_MEMORY_INIT=y
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
# CONFIG_LKDTM is not set
+# CONFIG_CPU_NOTIFIER_ERROR_INJECT is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -1010,6 +1012,7 @@ CONFIG_BRANCH_PROFILE_NONE=y
CONFIG_KPROBE_EVENT=y
# CONFIG_RING_BUFFER_BENCHMARK is not set
# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
CONFIG_SAMPLES=y
# CONFIG_SAMPLE_TRACEPOINTS is not set
# CONFIG_SAMPLE_TRACE_EVENTS is not set
diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c
index 639380a0c45..22cfd634c35 100644
--- a/arch/s390/kernel/module.c
+++ b/arch/s390/kernel/module.c
@@ -55,8 +55,10 @@ void *module_alloc(unsigned long size)
/* Free memory returned from module_alloc */
void module_free(struct module *mod, void *module_region)
{
- vfree(mod->arch.syminfo);
- mod->arch.syminfo = NULL;
+ if (mod) {
+ vfree(mod->arch.syminfo);
+ mod->arch.syminfo = NULL;
+ }
vfree(module_region);
}
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 8093e6f47f4..ae370581687 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -761,7 +761,7 @@ static int __init kvm_s390_init(void)
* to hold the maximum amount of facilites. On the other hand, we
* only set facilities that are known to work in KVM.
*/
- facilities = (unsigned long long *) get_zeroed_page(GFP_DMA);
+ facilities = (unsigned long long *) get_zeroed_page(GFP_KERNEL|GFP_DMA);
if (!facilities) {
kvm_exit();
return -ENOMEM;
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c
index eff3c5989b4..702276f5e2f 100644
--- a/arch/s390/kvm/sigp.c
+++ b/arch/s390/kvm/sigp.c
@@ -113,7 +113,7 @@ static int __inject_sigp_stop(struct kvm_s390_local_interrupt *li, int action)
{
struct kvm_s390_interrupt_info *inti;
- inti = kzalloc(sizeof(*inti), GFP_KERNEL);
+ inti = kzalloc(sizeof(*inti), GFP_ATOMIC);
if (!inti)
return -ENOMEM;
inti->type = KVM_S390_SIGP_STOP;
diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c
index 6409fd57eb0..3cc95dd0a3a 100644
--- a/arch/s390/mm/extmem.c
+++ b/arch/s390/mm/extmem.c
@@ -105,7 +105,7 @@ static int
dcss_set_subcodes(void)
{
#ifdef CONFIG_64BIT
- char *name = kmalloc(8 * sizeof(char), GFP_DMA);
+ char *name = kmalloc(8 * sizeof(char), GFP_KERNEL | GFP_DMA);
unsigned long rx, ry;
int rc;
@@ -252,12 +252,13 @@ dcss_diag_translate_rc (int vm_rc) {
static int
query_segment_type (struct dcss_segment *seg)
{
- struct qin64 *qin = kmalloc (sizeof(struct qin64), GFP_DMA);
- struct qout64 *qout = kmalloc (sizeof(struct qout64), GFP_DMA);
-
- int diag_cc, rc, i;
unsigned long dummy, vmrc;
+ int diag_cc, rc, i;
+ struct qout64 *qout;
+ struct qin64 *qin;
+ qin = kmalloc(sizeof(*qin), GFP_KERNEL | GFP_DMA);
+ qout = kmalloc(sizeof(*qout), GFP_KERNEL | GFP_DMA);
if ((qin == NULL) || (qout == NULL)) {
rc = -ENOMEM;
goto out_free;
@@ -286,7 +287,7 @@ query_segment_type (struct dcss_segment *seg)
copy data for the new format. */
if (segext_scode == DCSS_SEGEXT) {
struct qout64_old *qout_old;
- qout_old = kzalloc(sizeof(struct qout64_old), GFP_DMA);
+ qout_old = kzalloc(sizeof(*qout_old), GFP_KERNEL | GFP_DMA);
if (qout_old == NULL) {
rc = -ENOMEM;
goto out_free;
@@ -407,11 +408,11 @@ segment_overlaps_others (struct dcss_segment *seg)
static int
__segment_load (char *name, int do_nonshared, unsigned long *addr, unsigned long *end)
{
- struct dcss_segment *seg = kmalloc(sizeof(struct dcss_segment),
- GFP_DMA);
- int rc, diag_cc;
unsigned long start_addr, end_addr, dummy;
+ struct dcss_segment *seg;
+ int rc, diag_cc;
+ seg = kmalloc(sizeof(*seg), GFP_KERNEL | GFP_DMA);
if (seg == NULL) {
rc = -ENOMEM;
goto out;
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index b49d8ca228f..8c7ae431862 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -110,6 +110,7 @@
#define MSR_AMD64_PATCH_LOADER 0xc0010020
#define MSR_AMD64_OSVW_ID_LENGTH 0xc0010140
#define MSR_AMD64_OSVW_STATUS 0xc0010141
+#define MSR_AMD64_DC_CFG 0xc0011022
#define MSR_AMD64_IBSFETCHCTL 0xc0011030
#define MSR_AMD64_IBSFETCHLINAD 0xc0011031
#define MSR_AMD64_IBSFETCHPHYSAD 0xc0011032
diff --git a/arch/x86/include/asm/suspend_32.h b/arch/x86/include/asm/suspend_32.h
index 48dcfa62ea0..fd921c3a684 100644
--- a/arch/x86/include/asm/suspend_32.h
+++ b/arch/x86/include/asm/suspend_32.h
@@ -15,6 +15,8 @@ static inline int arch_prepare_suspend(void) { return 0; }
struct saved_context {
u16 es, fs, gs, ss;
unsigned long cr0, cr2, cr3, cr4;
+ u64 misc_enable;
+ bool misc_enable_saved;
struct desc_ptr gdt;
struct desc_ptr idt;
u16 ldt;
diff --git a/arch/x86/include/asm/suspend_64.h b/arch/x86/include/asm/suspend_64.h
index 06284f42b75..8d942afae68 100644
--- a/arch/x86/include/asm/suspend_64.h
+++ b/arch/x86/include/asm/suspend_64.h
@@ -27,6 +27,8 @@ struct saved_context {
u16 ds, es, fs, gs, ss;
unsigned long gs_base, gs_kernel_base, fs_base;
unsigned long cr0, cr2, cr3, cr4, cr8;
+ u64 misc_enable;
+ bool misc_enable_saved;
unsigned long efer;
u16 gdt_pad;
u16 gdt_limit;
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 81563e76e28..a6f695d7692 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -1815,6 +1815,9 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
spte |= PT_WRITABLE_MASK;
+ if (!tdp_enabled && !(pte_access & ACC_WRITE_MASK))
+ spte &= ~PT_USER_MASK;
+
/*
* Optimization: for pte sync, if spte was writable the hash
* lookup is unnecessary (and expensive). Write protection
@@ -1870,6 +1873,8 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
child = page_header(pte & PT64_BASE_ADDR_MASK);
mmu_page_remove_parent_pte(child, sptep);
+ __set_spte(sptep, shadow_trap_nonpresent_pte);
+ kvm_flush_remote_tlbs(vcpu->kvm);
} else if (pfn != spte_to_pfn(*sptep)) {
pgprintk("hfn old %lx new %lx\n",
spte_to_pfn(*sptep), pfn);
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 96dc232bfc5..ce438e0fdd2 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -28,6 +28,7 @@
#include <linux/ftrace_event.h>
#include <linux/slab.h>
+#include <asm/tlbflush.h>
#include <asm/desc.h>
#include <asm/virtext.h>
@@ -56,6 +57,8 @@ MODULE_LICENSE("GPL");
#define DEBUGCTL_RESERVED_BITS (~(0x3fULL))
+static bool erratum_383_found __read_mostly;
+
static const u32 host_save_user_msrs[] = {
#ifdef CONFIG_X86_64
MSR_STAR, MSR_LSTAR, MSR_CSTAR, MSR_SYSCALL_MASK, MSR_KERNEL_GS_BASE,
@@ -374,6 +377,31 @@ static void svm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
svm->vmcb->control.event_inj_err = error_code;
}
+static void svm_init_erratum_383(void)
+{
+ u32 low, high;
+ int err;
+ u64 val;
+
+ /* Only Fam10h is affected */
+ if (boot_cpu_data.x86 != 0x10)
+ return;
+
+ /* Use _safe variants to not break nested virtualization */
+ val = native_read_msr_safe(MSR_AMD64_DC_CFG, &err);
+ if (err)
+ return;
+
+ val |= (1ULL << 47);
+
+ low = lower_32_bits(val);
+ high = upper_32_bits(val);
+
+ native_write_msr_safe(MSR_AMD64_DC_CFG, low, high);
+
+ erratum_383_found = true;
+}
+
static int has_svm(void)
{
const char *msg;
@@ -429,6 +457,8 @@ static int svm_hardware_enable(void *garbage)
wrmsrl(MSR_VM_HSAVE_PA, page_to_pfn(sd->save_area) << PAGE_SHIFT);
+ svm_init_erratum_383();
+
return 0;
}
@@ -1410,8 +1440,59 @@ static int nm_interception(struct vcpu_svm *svm)
return 1;
}
-static int mc_interception(struct vcpu_svm *svm)
+static bool is_erratum_383(void)
{
+ int err, i;
+ u64 value;
+
+ if (!erratum_383_found)
+ return false;
+
+ value = native_read_msr_safe(MSR_IA32_MC0_STATUS, &err);
+ if (err)
+ return false;
+
+ /* Bit 62 may or may not be set for this mce */
+ value &= ~(1ULL << 62);
+
+ if (value != 0xb600000000010015ULL)
+ return false;
+
+ /* Clear MCi_STATUS registers */
+ for (i = 0; i < 6; ++i)
+ native_write_msr_safe(MSR_IA32_MCx_STATUS(i), 0, 0);
+
+ value = native_read_msr_safe(MSR_IA32_MCG_STATUS, &err);
+ if (!err) {
+ u32 low, high;
+
+ value &= ~(1ULL << 2);
+ low = lower_32_bits(value);
+ high = upper_32_bits(value);
+
+ native_write_msr_safe(MSR_IA32_MCG_STATUS, low, high);
+ }
+
+ /* Flush tlb to evict multi-match entries */
+ __flush_tlb_all();
+
+ return true;
+}
+
+static void svm_handle_mce(struct vcpu_svm *svm)
+{
+ if (is_erratum_383()) {
+ /*
+ * Erratum 383 triggered. Guest state is corrupt so kill the
+ * guest.
+ */
+ pr_err("KVM: Guest triggered AMD Erratum 383\n");
+
+ set_bit(KVM_REQ_TRIPLE_FAULT, &svm->vcpu.requests);
+
+ return;
+ }
+
/*
* On an #MC intercept the MCE handler is not called automatically in
* the host. So do it by hand here.
@@ -1420,6 +1501,11 @@ static int mc_interception(struct vcpu_svm *svm)
"int $0x12\n");
/* not sure if we ever come back to this point */
+ return;
+}
+
+static int mc_interception(struct vcpu_svm *svm)
+{
return 1;
}
@@ -3088,6 +3174,14 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
vcpu->arch.regs_avail &= ~(1 << VCPU_EXREG_PDPTR);
vcpu->arch.regs_dirty &= ~(1 << VCPU_EXREG_PDPTR);
}
+
+ /*
+ * We need to handle MC intercepts here before the vcpu has a chance to
+ * change the physical cpu
+ */
+ if (unlikely(svm->vmcb->control.exit_code ==
+ SVM_EXIT_EXCP_BASE + MC_VECTOR))
+ svm_handle_mce(svm);
}
#undef R
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index 97da2ba9344..6fdb3ec30c3 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -96,6 +96,7 @@ EXPORT_SYMBOL(pcibios_align_resource);
* the fact the PCI specs explicitly allow address decoders to be
* shared between expansion ROMs and other resource regions, it's
* at least dangerous)
+ * - bad resource sizes or overlaps with other regions
*
* Our solution:
* (1) Allocate resources for all buses behind PCI-to-PCI bridges.
@@ -136,6 +137,7 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
* child resource allocations in this
* range.
*/
+ r->start = r->end = 0;
r->flags = 0;
}
}
diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
index 0a979f3e5b8..1290ba54b35 100644
--- a/arch/x86/power/cpu.c
+++ b/arch/x86/power/cpu.c
@@ -105,6 +105,8 @@ static void __save_processor_state(struct saved_context *ctxt)
ctxt->cr4 = read_cr4();
ctxt->cr8 = read_cr8();
#endif
+ ctxt->misc_enable_saved = !rdmsrl_safe(MSR_IA32_MISC_ENABLE,
+ &ctxt->misc_enable);
}
/* Needed by apm.c */
@@ -152,6 +154,8 @@ static void fix_processor_context(void)
*/
static void __restore_processor_state(struct saved_context *ctxt)
{
+ if (ctxt->misc_enable_saved)
+ wrmsrl(MSR_IA32_MISC_ENABLE, ctxt->misc_enable);
/*
* control registers
*/