diff options
Diffstat (limited to 'arch')
325 files changed, 8357 insertions, 2237 deletions
diff --git a/arch/alpha/include/asm/mman.h b/arch/alpha/include/asm/mman.h index 99c56d47879d..72db984f8781 100644 --- a/arch/alpha/include/asm/mman.h +++ b/arch/alpha/include/asm/mman.h | |||
@@ -53,6 +53,9 @@ | |||
53 | #define MADV_MERGEABLE 12 /* KSM may merge identical pages */ | 53 | #define MADV_MERGEABLE 12 /* KSM may merge identical pages */ |
54 | #define MADV_UNMERGEABLE 13 /* KSM may not merge identical pages */ | 54 | #define MADV_UNMERGEABLE 13 /* KSM may not merge identical pages */ |
55 | 55 | ||
56 | #define MADV_HUGEPAGE 14 /* Worth backing with hugepages */ | ||
57 | #define MADV_NOHUGEPAGE 15 /* Not worth backing with hugepages */ | ||
58 | |||
56 | /* compatibility flags */ | 59 | /* compatibility flags */ |
57 | #define MAP_FILE 0 | 60 | #define MAP_FILE 0 |
58 | 61 | ||
diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c index 0f1d8493cfca..c1f3e7cb82a4 100644 --- a/arch/alpha/kernel/time.c +++ b/arch/alpha/kernel/time.c | |||
@@ -506,7 +506,7 @@ set_rtc_mmss(unsigned long nowtime) | |||
506 | CMOS_WRITE(real_seconds,RTC_SECONDS); | 506 | CMOS_WRITE(real_seconds,RTC_SECONDS); |
507 | CMOS_WRITE(real_minutes,RTC_MINUTES); | 507 | CMOS_WRITE(real_minutes,RTC_MINUTES); |
508 | } else { | 508 | } else { |
509 | printk(KERN_WARNING | 509 | printk_once(KERN_NOTICE |
510 | "set_rtc_mmss: can't update from %d to %d\n", | 510 | "set_rtc_mmss: can't update from %d to %d\n", |
511 | cmos_minutes, real_minutes); | 511 | cmos_minutes, real_minutes); |
512 | retval = -1; | 512 | retval = -1; |
diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c index 42ff90b46dfb..665ebf7e62a6 100644 --- a/arch/arm/common/it8152.c +++ b/arch/arm/common/it8152.c | |||
@@ -236,7 +236,7 @@ static struct resource it8152_mem = { | |||
236 | 236 | ||
237 | /* | 237 | /* |
238 | * The following functions are needed for DMA bouncing. | 238 | * The following functions are needed for DMA bouncing. |
239 | * ITE8152 chip can addrees up to 64MByte, so all the devices | 239 | * ITE8152 chip can address up to 64MByte, so all the devices |
240 | * connected to ITE8152 (PCI and USB) should have limited DMA window | 240 | * connected to ITE8152 (PCI and USB) should have limited DMA window |
241 | */ | 241 | */ |
242 | 242 | ||
diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c index ba65f6eedca6..cb660bc54d7a 100644 --- a/arch/arm/common/vic.c +++ b/arch/arm/common/vic.c | |||
@@ -70,7 +70,7 @@ static inline struct vic_device *to_vic(struct sys_device *sys) | |||
70 | * vic_init2 - common initialisation code | 70 | * vic_init2 - common initialisation code |
71 | * @base: Base of the VIC. | 71 | * @base: Base of the VIC. |
72 | * | 72 | * |
73 | * Common initialisation code for registeration | 73 | * Common initialisation code for registration |
74 | * and resume. | 74 | * and resume. |
75 | */ | 75 | */ |
76 | static void vic_init2(void __iomem *base) | 76 | static void vic_init2(void __iomem *base) |
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index 0c1bb68ff4a8..2cfe8161b478 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c | |||
@@ -38,17 +38,9 @@ | |||
38 | #ifdef CONFIG_MMU | 38 | #ifdef CONFIG_MMU |
39 | void *module_alloc(unsigned long size) | 39 | void *module_alloc(unsigned long size) |
40 | { | 40 | { |
41 | struct vm_struct *area; | 41 | return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END, |
42 | 42 | GFP_KERNEL, PAGE_KERNEL_EXEC, -1, | |
43 | size = PAGE_ALIGN(size); | 43 | __builtin_return_address(0)); |
44 | if (!size) | ||
45 | return NULL; | ||
46 | |||
47 | area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END); | ||
48 | if (!area) | ||
49 | return NULL; | ||
50 | |||
51 | return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC); | ||
52 | } | 44 | } |
53 | #else /* CONFIG_MMU */ | 45 | #else /* CONFIG_MMU */ |
54 | void *module_alloc(unsigned long size) | 46 | void *module_alloc(unsigned long size) |
diff --git a/arch/arm/mach-at91/board-ecbat91.c b/arch/arm/mach-at91/board-ecbat91.c index 7b58c948a957..de2fd04e7c8a 100644 --- a/arch/arm/mach-at91/board-ecbat91.c +++ b/arch/arm/mach-at91/board-ecbat91.c | |||
@@ -128,17 +128,17 @@ static struct spi_board_info __initdata ecb_at91spi_devices[] = { | |||
128 | .platform_data = &my_flash0_platform, | 128 | .platform_data = &my_flash0_platform, |
129 | #endif | 129 | #endif |
130 | }, | 130 | }, |
131 | { /* User accessable spi - cs1 (250KHz) */ | 131 | { /* User accessible spi - cs1 (250KHz) */ |
132 | .modalias = "spi-cs1", | 132 | .modalias = "spi-cs1", |
133 | .chip_select = 1, | 133 | .chip_select = 1, |
134 | .max_speed_hz = 250 * 1000, | 134 | .max_speed_hz = 250 * 1000, |
135 | }, | 135 | }, |
136 | { /* User accessable spi - cs2 (1MHz) */ | 136 | { /* User accessible spi - cs2 (1MHz) */ |
137 | .modalias = "spi-cs2", | 137 | .modalias = "spi-cs2", |
138 | .chip_select = 2, | 138 | .chip_select = 2, |
139 | .max_speed_hz = 1 * 1000 * 1000, | 139 | .max_speed_hz = 1 * 1000 * 1000, |
140 | }, | 140 | }, |
141 | { /* User accessable spi - cs3 (10MHz) */ | 141 | { /* User accessible spi - cs3 (10MHz) */ |
142 | .modalias = "spi-cs3", | 142 | .modalias = "spi-cs3", |
143 | .chip_select = 3, | 143 | .chip_select = 3, |
144 | .max_speed_hz = 10 * 1000 * 1000, | 144 | .max_speed_hz = 10 * 1000 * 1000, |
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index dafbacc25eb1..ea53f4d9b283 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c | |||
@@ -301,7 +301,7 @@ static void at91_pm_end(void) | |||
301 | } | 301 | } |
302 | 302 | ||
303 | 303 | ||
304 | static struct platform_suspend_ops at91_pm_ops ={ | 304 | static const struct platform_suspend_ops at91_pm_ops = { |
305 | .valid = at91_pm_valid_state, | 305 | .valid = at91_pm_valid_state, |
306 | .begin = at91_pm_begin, | 306 | .begin = at91_pm_begin, |
307 | .enter = at91_pm_enter, | 307 | .enter = at91_pm_enter, |
diff --git a/arch/arm/mach-bcmring/csp/chipc/chipcHw.c b/arch/arm/mach-bcmring/csp/chipc/chipcHw.c index b3a61d860c65..96273ff34956 100644 --- a/arch/arm/mach-bcmring/csp/chipc/chipcHw.c +++ b/arch/arm/mach-bcmring/csp/chipc/chipcHw.c | |||
@@ -757,7 +757,7 @@ static int chipcHw_divide(int num, int denom) | |||
757 | t = t << 1; | 757 | t = t << 1; |
758 | } | 758 | } |
759 | 759 | ||
760 | /* Intialize the result */ | 760 | /* Initialize the result */ |
761 | r = 0; | 761 | r = 0; |
762 | 762 | ||
763 | do { | 763 | do { |
diff --git a/arch/arm/mach-bcmring/csp/dmac/dmacHw.c b/arch/arm/mach-bcmring/csp/dmac/dmacHw.c index 7b9bac2d79a5..6b9be2e98e51 100644 --- a/arch/arm/mach-bcmring/csp/dmac/dmacHw.c +++ b/arch/arm/mach-bcmring/csp/dmac/dmacHw.c | |||
@@ -893,7 +893,7 @@ int dmacHw_setDataDescriptor(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration | |||
893 | */ | 893 | */ |
894 | /****************************************************************************/ | 894 | /****************************************************************************/ |
895 | uint32_t dmacHw_getDmaControllerAttribute(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */ | 895 | uint32_t dmacHw_getDmaControllerAttribute(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */ |
896 | dmacHw_CONTROLLER_ATTRIB_e attr /* [ IN ] DMA Controler attribute of type dmacHw_CONTROLLER_ATTRIB_e */ | 896 | dmacHw_CONTROLLER_ATTRIB_e attr /* [ IN ] DMA Controller attribute of type dmacHw_CONTROLLER_ATTRIB_e */ |
897 | ) { | 897 | ) { |
898 | dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle); | 898 | dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle); |
899 | 899 | ||
diff --git a/arch/arm/mach-bcmring/csp/dmac/dmacHw_extra.c b/arch/arm/mach-bcmring/csp/dmac/dmacHw_extra.c index ff7b436d0935..77f84b40dda9 100644 --- a/arch/arm/mach-bcmring/csp/dmac/dmacHw_extra.c +++ b/arch/arm/mach-bcmring/csp/dmac/dmacHw_extra.c | |||
@@ -316,7 +316,7 @@ static void DisplayDescRing(void *pDescriptor, /* [ IN ] Descriptor buffer */ | |||
316 | /** | 316 | /** |
317 | * @brief Check if DMA channel is the flow controller | 317 | * @brief Check if DMA channel is the flow controller |
318 | * | 318 | * |
319 | * @return 1 : If DMA is a flow controler | 319 | * @return 1 : If DMA is a flow controller |
320 | * 0 : Peripheral is the flow controller | 320 | * 0 : Peripheral is the flow controller |
321 | * | 321 | * |
322 | * @note | 322 | * @note |
diff --git a/arch/arm/mach-bcmring/csp/tmr/tmrHw.c b/arch/arm/mach-bcmring/csp/tmr/tmrHw.c index 5c1c9a0e5ed2..16225e43f3c3 100644 --- a/arch/arm/mach-bcmring/csp/tmr/tmrHw.c +++ b/arch/arm/mach-bcmring/csp/tmr/tmrHw.c | |||
@@ -558,7 +558,7 @@ static int tmrHw_divide(int num, int denom) | |||
558 | t = t << 1; | 558 | t = t << 1; |
559 | } | 559 | } |
560 | 560 | ||
561 | /* Intialize the result */ | 561 | /* Initialize the result */ |
562 | r = 0; | 562 | r = 0; |
563 | 563 | ||
564 | do { | 564 | do { |
diff --git a/arch/arm/mach-bcmring/dma.c b/arch/arm/mach-bcmring/dma.c index 77eb35c89cd0..8d1baf3f4683 100644 --- a/arch/arm/mach-bcmring/dma.c +++ b/arch/arm/mach-bcmring/dma.c | |||
@@ -671,7 +671,7 @@ static int ConfigChannel(DMA_Handle_t handle) | |||
671 | 671 | ||
672 | /****************************************************************************/ | 672 | /****************************************************************************/ |
673 | /** | 673 | /** |
674 | * Intializes all of the data structures associated with the DMA. | 674 | * Initializes all of the data structures associated with the DMA. |
675 | * @return | 675 | * @return |
676 | * >= 0 - Initialization was successfull. | 676 | * >= 0 - Initialization was successfull. |
677 | * | 677 | * |
diff --git a/arch/arm/mach-bcmring/include/csp/dmacHw.h b/arch/arm/mach-bcmring/include/csp/dmacHw.h index 5d510130a25f..6c8da2b9fc1f 100644 --- a/arch/arm/mach-bcmring/include/csp/dmacHw.h +++ b/arch/arm/mach-bcmring/include/csp/dmacHw.h | |||
@@ -590,7 +590,7 @@ void dmacHw_printDebugInfo(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle | |||
590 | */ | 590 | */ |
591 | /****************************************************************************/ | 591 | /****************************************************************************/ |
592 | uint32_t dmacHw_getDmaControllerAttribute(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */ | 592 | uint32_t dmacHw_getDmaControllerAttribute(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */ |
593 | dmacHw_CONTROLLER_ATTRIB_e attr /* [ IN ] DMA Controler attribute of type dmacHw_CONTROLLER_ATTRIB_e */ | 593 | dmacHw_CONTROLLER_ATTRIB_e attr /* [ IN ] DMA Controller attribute of type dmacHw_CONTROLLER_ATTRIB_e */ |
594 | ); | 594 | ); |
595 | 595 | ||
596 | #endif /* _DMACHW_H */ | 596 | #endif /* _DMACHW_H */ |
diff --git a/arch/arm/mach-bcmring/include/csp/tmrHw.h b/arch/arm/mach-bcmring/include/csp/tmrHw.h index f1236d00cb97..2cbb530db8ea 100644 --- a/arch/arm/mach-bcmring/include/csp/tmrHw.h +++ b/arch/arm/mach-bcmring/include/csp/tmrHw.h | |||
@@ -76,7 +76,7 @@ tmrHw_RATE_t tmrHw_setPeriodicTimerRate(tmrHw_ID_t timerId, /* [ IN ] Timer Id | |||
76 | * certain time interval | 76 | * certain time interval |
77 | * | 77 | * |
78 | * This function initializes a periodic timer to generate timer interrupt | 78 | * This function initializes a periodic timer to generate timer interrupt |
79 | * after every time interval in milisecond | 79 | * after every time interval in millisecond |
80 | * | 80 | * |
81 | * @return On success: Effective interval set in mili-second | 81 | * @return On success: Effective interval set in mili-second |
82 | * On failure: 0 | 82 | * On failure: 0 |
@@ -93,7 +93,7 @@ tmrHw_INTERVAL_t tmrHw_setPeriodicTimerInterval(tmrHw_ID_t timerId, /* [ IN ] T | |||
93 | * after certain time interval | 93 | * after certain time interval |
94 | * | 94 | * |
95 | * This function initializes a periodic timer to generate a single ticks after | 95 | * This function initializes a periodic timer to generate a single ticks after |
96 | * certain time interval in milisecond | 96 | * certain time interval in millisecond |
97 | * | 97 | * |
98 | * @return On success: Effective interval set in mili-second | 98 | * @return On success: Effective interval set in mili-second |
99 | * On failure: 0 | 99 | * On failure: 0 |
diff --git a/arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h b/arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h index cbf334d1c761..d67e2f8c22de 100644 --- a/arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h +++ b/arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h | |||
@@ -28,7 +28,7 @@ | |||
28 | 28 | ||
29 | /* Data type for DMA Link List Item */ | 29 | /* Data type for DMA Link List Item */ |
30 | typedef struct { | 30 | typedef struct { |
31 | uint32_t sar; /* Source Adress Register. | 31 | uint32_t sar; /* Source Address Register. |
32 | Address must be aligned to CTLx.SRC_TR_WIDTH. */ | 32 | Address must be aligned to CTLx.SRC_TR_WIDTH. */ |
33 | uint32_t dar; /* Destination Address Register. | 33 | uint32_t dar; /* Destination Address Register. |
34 | Address must be aligned to CTLx.DST_TR_WIDTH. */ | 34 | Address must be aligned to CTLx.DST_TR_WIDTH. */ |
diff --git a/arch/arm/mach-bcmring/include/mach/csp/dmacHw_reg.h b/arch/arm/mach-bcmring/include/mach/csp/dmacHw_reg.h index 891cea87e333..f1ecf96f2da5 100644 --- a/arch/arm/mach-bcmring/include/mach/csp/dmacHw_reg.h +++ b/arch/arm/mach-bcmring/include/mach/csp/dmacHw_reg.h | |||
@@ -35,7 +35,7 @@ typedef struct { | |||
35 | 35 | ||
36 | /* Data type representing DMA channel registers */ | 36 | /* Data type representing DMA channel registers */ |
37 | typedef struct { | 37 | typedef struct { |
38 | dmacHw_REG64_t ChannelSar; /* Source Adress Register. 64 bits (upper 32 bits are reserved) | 38 | dmacHw_REG64_t ChannelSar; /* Source Address Register. 64 bits (upper 32 bits are reserved) |
39 | Address must be aligned to CTLx.SRC_TR_WIDTH. | 39 | Address must be aligned to CTLx.SRC_TR_WIDTH. |
40 | */ | 40 | */ |
41 | dmacHw_REG64_t ChannelDar; /* Destination Address Register.64 bits (upper 32 bits are reserved) | 41 | dmacHw_REG64_t ChannelDar; /* Destination Address Register.64 bits (upper 32 bits are reserved) |
diff --git a/arch/arm/mach-davinci/pm.c b/arch/arm/mach-davinci/pm.c index fab953b43dea..1bd73a04be20 100644 --- a/arch/arm/mach-davinci/pm.c +++ b/arch/arm/mach-davinci/pm.c | |||
@@ -110,7 +110,7 @@ static int davinci_pm_enter(suspend_state_t state) | |||
110 | return ret; | 110 | return ret; |
111 | } | 111 | } |
112 | 112 | ||
113 | static struct platform_suspend_ops davinci_pm_ops = { | 113 | static const struct platform_suspend_ops davinci_pm_ops = { |
114 | .enter = davinci_pm_enter, | 114 | .enter = davinci_pm_enter, |
115 | .valid = suspend_valid_only_mem, | 115 | .valid = suspend_valid_only_mem, |
116 | }; | 116 | }; |
diff --git a/arch/arm/mach-gemini/include/mach/hardware.h b/arch/arm/mach-gemini/include/mach/hardware.h index 213a4fcfeb1c..8c950e1d06be 100644 --- a/arch/arm/mach-gemini/include/mach/hardware.h +++ b/arch/arm/mach-gemini/include/mach/hardware.h | |||
@@ -33,7 +33,7 @@ | |||
33 | #define GEMINI_LPC_HOST_BASE 0x47000000 | 33 | #define GEMINI_LPC_HOST_BASE 0x47000000 |
34 | #define GEMINI_LPC_IO_BASE 0x47800000 | 34 | #define GEMINI_LPC_IO_BASE 0x47800000 |
35 | #define GEMINI_INTERRUPT_BASE 0x48000000 | 35 | #define GEMINI_INTERRUPT_BASE 0x48000000 |
36 | /* TODO: Different interrupt controlers when SMP | 36 | /* TODO: Different interrupt controllers when SMP |
37 | * #define GEMINI_INTERRUPT0_BASE 0x48000000 | 37 | * #define GEMINI_INTERRUPT0_BASE 0x48000000 |
38 | * #define GEMINI_INTERRUPT1_BASE 0x49000000 | 38 | * #define GEMINI_INTERRUPT1_BASE 0x49000000 |
39 | */ | 39 | */ |
diff --git a/arch/arm/mach-imx/mach-pcm038.c b/arch/arm/mach-imx/mach-pcm038.c index f667a262dfc1..505614803bc6 100644 --- a/arch/arm/mach-imx/mach-pcm038.c +++ b/arch/arm/mach-imx/mach-pcm038.c | |||
@@ -254,10 +254,10 @@ static struct regulator_init_data cam_data = { | |||
254 | 254 | ||
255 | static struct mc13783_regulator_init_data pcm038_regulators[] = { | 255 | static struct mc13783_regulator_init_data pcm038_regulators[] = { |
256 | { | 256 | { |
257 | .id = MC13783_REGU_VCAM, | 257 | .id = MC13783_REG_VCAM, |
258 | .init_data = &cam_data, | 258 | .init_data = &cam_data, |
259 | }, { | 259 | }, { |
260 | .id = MC13783_REGU_VMMC1, | 260 | .id = MC13783_REG_VMMC1, |
261 | .init_data = &sdhc1_data, | 261 | .init_data = &sdhc1_data, |
262 | }, | 262 | }, |
263 | }; | 263 | }; |
diff --git a/arch/arm/mach-imx/pm-imx27.c b/arch/arm/mach-imx/pm-imx27.c index 6bf81ceea137..acf17691d2cc 100644 --- a/arch/arm/mach-imx/pm-imx27.c +++ b/arch/arm/mach-imx/pm-imx27.c | |||
@@ -32,7 +32,7 @@ static int mx27_suspend_enter(suspend_state_t state) | |||
32 | return 0; | 32 | return 0; |
33 | } | 33 | } |
34 | 34 | ||
35 | static struct platform_suspend_ops mx27_suspend_ops = { | 35 | static const struct platform_suspend_ops mx27_suspend_ops = { |
36 | .enter = mx27_suspend_enter, | 36 | .enter = mx27_suspend_enter, |
37 | .valid = suspend_valid_only_mem, | 37 | .valid = suspend_valid_only_mem, |
38 | }; | 38 | }; |
diff --git a/arch/arm/mach-kirkwood/openrd-setup.c b/arch/arm/mach-kirkwood/openrd-setup.c index c9d77fad10ab..cfcca4174e25 100644 --- a/arch/arm/mach-kirkwood/openrd-setup.c +++ b/arch/arm/mach-kirkwood/openrd-setup.c | |||
@@ -171,7 +171,7 @@ static void __init openrd_init(void) | |||
171 | 171 | ||
172 | kirkwood_i2c_init(); | 172 | kirkwood_i2c_init(); |
173 | 173 | ||
174 | if (machine_is_openrd_client()) { | 174 | if (machine_is_openrd_client() || machine_is_openrd_ultimate()) { |
175 | i2c_register_board_info(0, i2c_board_info, | 175 | i2c_register_board_info(0, i2c_board_info, |
176 | ARRAY_SIZE(i2c_board_info)); | 176 | ARRAY_SIZE(i2c_board_info)); |
177 | kirkwood_audio_init(); | 177 | kirkwood_audio_init(); |
diff --git a/arch/arm/mach-lpc32xx/pm.c b/arch/arm/mach-lpc32xx/pm.c index a6e2aed9a49f..e76d41bb7056 100644 --- a/arch/arm/mach-lpc32xx/pm.c +++ b/arch/arm/mach-lpc32xx/pm.c | |||
@@ -123,7 +123,7 @@ static int lpc32xx_pm_enter(suspend_state_t state) | |||
123 | return 0; | 123 | return 0; |
124 | } | 124 | } |
125 | 125 | ||
126 | static struct platform_suspend_ops lpc32xx_pm_ops = { | 126 | static const struct platform_suspend_ops lpc32xx_pm_ops = { |
127 | .valid = suspend_valid_only_mem, | 127 | .valid = suspend_valid_only_mem, |
128 | .enter = lpc32xx_pm_enter, | 128 | .enter = lpc32xx_pm_enter, |
129 | }; | 129 | }; |
diff --git a/arch/arm/mach-msm/include/mach/entry-macro-qgic.S b/arch/arm/mach-msm/include/mach/entry-macro-qgic.S index 4dc99aa65d07..12467157afb9 100644 --- a/arch/arm/mach-msm/include/mach/entry-macro-qgic.S +++ b/arch/arm/mach-msm/include/mach/entry-macro-qgic.S | |||
@@ -26,7 +26,7 @@ | |||
26 | * The interrupt numbering scheme is defined in the | 26 | * The interrupt numbering scheme is defined in the |
27 | * interrupt controller spec. To wit: | 27 | * interrupt controller spec. To wit: |
28 | * | 28 | * |
29 | * Migrated the code from ARM MP port to be more consistant | 29 | * Migrated the code from ARM MP port to be more consistent |
30 | * with interrupt processing , the following still holds true | 30 | * with interrupt processing , the following still holds true |
31 | * however, all interrupts are treated the same regardless of | 31 | * however, all interrupts are treated the same regardless of |
32 | * if they are local IPI or PPI | 32 | * if they are local IPI or PPI |
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c index 800f327a7ecc..1260007a9dd1 100644 --- a/arch/arm/mach-msm/io.c +++ b/arch/arm/mach-msm/io.c | |||
@@ -154,7 +154,7 @@ __msm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype) | |||
154 | { | 154 | { |
155 | if (mtype == MT_DEVICE) { | 155 | if (mtype == MT_DEVICE) { |
156 | /* The peripherals in the 88000000 - D0000000 range | 156 | /* The peripherals in the 88000000 - D0000000 range |
157 | * are only accessable by type MT_DEVICE_NONSHARED. | 157 | * are only accessible by type MT_DEVICE_NONSHARED. |
158 | * Adjust mtype as necessary to make this "just work." | 158 | * Adjust mtype as necessary to make this "just work." |
159 | */ | 159 | */ |
160 | if ((phys_addr >= 0x88000000) && (phys_addr < 0xD0000000)) | 160 | if ((phys_addr >= 0x88000000) && (phys_addr < 0xD0000000)) |
diff --git a/arch/arm/mach-mx3/mach-mx31_3ds.c b/arch/arm/mach-mx3/mach-mx31_3ds.c index 4e516b49a901..899a969e92fa 100644 --- a/arch/arm/mach-mx3/mach-mx31_3ds.c +++ b/arch/arm/mach-mx3/mach-mx31_3ds.c | |||
@@ -140,10 +140,10 @@ static struct regulator_init_data gpo_init = { | |||
140 | 140 | ||
141 | static struct mc13783_regulator_init_data mx31_3ds_regulators[] = { | 141 | static struct mc13783_regulator_init_data mx31_3ds_regulators[] = { |
142 | { | 142 | { |
143 | .id = MC13783_REGU_PWGT1SPI, /* Power Gate for ARM core. */ | 143 | .id = MC13783_REG_PWGT1SPI, /* Power Gate for ARM core. */ |
144 | .init_data = &pwgtx_init, | 144 | .init_data = &pwgtx_init, |
145 | }, { | 145 | }, { |
146 | .id = MC13783_REGU_PWGT2SPI, /* Power Gate for L2 Cache. */ | 146 | .id = MC13783_REG_PWGT2SPI, /* Power Gate for L2 Cache. */ |
147 | .init_data = &pwgtx_init, | 147 | .init_data = &pwgtx_init, |
148 | }, { | 148 | }, { |
149 | 149 | ||
diff --git a/arch/arm/mach-mx3/mach-mx31moboard.c b/arch/arm/mach-mx3/mach-mx31moboard.c index 203d21a510aa..1aa8d65fccbb 100644 --- a/arch/arm/mach-mx3/mach-mx31moboard.c +++ b/arch/arm/mach-mx3/mach-mx31moboard.c | |||
@@ -216,11 +216,11 @@ static struct regulator_init_data cam_vreg_data = { | |||
216 | 216 | ||
217 | static struct mc13783_regulator_init_data moboard_regulators[] = { | 217 | static struct mc13783_regulator_init_data moboard_regulators[] = { |
218 | { | 218 | { |
219 | .id = MC13783_REGU_VMMC1, | 219 | .id = MC13783_REG_VMMC1, |
220 | .init_data = &sdhc_vreg_data, | 220 | .init_data = &sdhc_vreg_data, |
221 | }, | 221 | }, |
222 | { | 222 | { |
223 | .id = MC13783_REGU_VCAM, | 223 | .id = MC13783_REG_VCAM, |
224 | .init_data = &cam_vreg_data, | 224 | .init_data = &cam_vreg_data, |
225 | }, | 225 | }, |
226 | }; | 226 | }; |
diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c index 0cca23a85175..98ba9784aa15 100644 --- a/arch/arm/mach-omap1/pm.c +++ b/arch/arm/mach-omap1/pm.c | |||
@@ -647,7 +647,7 @@ static struct irqaction omap_wakeup_irq = { | |||
647 | 647 | ||
648 | 648 | ||
649 | 649 | ||
650 | static struct platform_suspend_ops omap_pm_ops ={ | 650 | static const struct platform_suspend_ops omap_pm_ops = { |
651 | .prepare = omap_pm_prepare, | 651 | .prepare = omap_pm_prepare, |
652 | .enter = omap_pm_enter, | 652 | .enter = omap_pm_enter, |
653 | .finish = omap_pm_finish, | 653 | .finish = omap_pm_finish, |
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index cd7332f50b2d..1c0c2b02d870 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile | |||
@@ -187,16 +187,19 @@ obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o \ | |||
187 | hsmmc.o | 187 | hsmmc.o |
188 | obj-$(CONFIG_MACH_OMAP_ZOOM2) += board-zoom.o \ | 188 | obj-$(CONFIG_MACH_OMAP_ZOOM2) += board-zoom.o \ |
189 | board-zoom-peripherals.o \ | 189 | board-zoom-peripherals.o \ |
190 | board-zoom-display.o \ | ||
190 | board-flash.o \ | 191 | board-flash.o \ |
191 | hsmmc.o \ | 192 | hsmmc.o \ |
192 | board-zoom-debugboard.o | 193 | board-zoom-debugboard.o |
193 | obj-$(CONFIG_MACH_OMAP_ZOOM3) += board-zoom.o \ | 194 | obj-$(CONFIG_MACH_OMAP_ZOOM3) += board-zoom.o \ |
194 | board-zoom-peripherals.o \ | 195 | board-zoom-peripherals.o \ |
196 | board-zoom-display.o \ | ||
195 | board-flash.o \ | 197 | board-flash.o \ |
196 | hsmmc.o \ | 198 | hsmmc.o \ |
197 | board-zoom-debugboard.o | 199 | board-zoom-debugboard.o |
198 | obj-$(CONFIG_MACH_OMAP_3630SDP) += board-3630sdp.o \ | 200 | obj-$(CONFIG_MACH_OMAP_3630SDP) += board-3630sdp.o \ |
199 | board-zoom-peripherals.o \ | 201 | board-zoom-peripherals.o \ |
202 | board-zoom-display.o \ | ||
200 | board-flash.o \ | 203 | board-flash.o \ |
201 | hsmmc.o | 204 | hsmmc.o |
202 | obj-$(CONFIG_MACH_CM_T35) += board-cm-t35.o \ | 205 | obj-$(CONFIG_MACH_CM_T35) += board-cm-t35.o \ |
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index 3b39ef1a680a..d4e41ef86aa5 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <plat/dma.h> | 38 | #include <plat/dma.h> |
39 | #include <plat/gpmc.h> | 39 | #include <plat/gpmc.h> |
40 | #include <plat/display.h> | 40 | #include <plat/display.h> |
41 | #include <plat/panel-generic-dpi.h> | ||
41 | 42 | ||
42 | #include <plat/gpmc-smc91x.h> | 43 | #include <plat/gpmc-smc91x.h> |
43 | 44 | ||
@@ -270,13 +271,18 @@ static struct omap_dss_device sdp3430_lcd_device = { | |||
270 | .platform_disable = sdp3430_panel_disable_lcd, | 271 | .platform_disable = sdp3430_panel_disable_lcd, |
271 | }; | 272 | }; |
272 | 273 | ||
274 | static struct panel_generic_dpi_data dvi_panel = { | ||
275 | .name = "generic", | ||
276 | .platform_enable = sdp3430_panel_enable_dvi, | ||
277 | .platform_disable = sdp3430_panel_disable_dvi, | ||
278 | }; | ||
279 | |||
273 | static struct omap_dss_device sdp3430_dvi_device = { | 280 | static struct omap_dss_device sdp3430_dvi_device = { |
274 | .name = "dvi", | 281 | .name = "dvi", |
275 | .driver_name = "generic_panel", | ||
276 | .type = OMAP_DISPLAY_TYPE_DPI, | 282 | .type = OMAP_DISPLAY_TYPE_DPI, |
283 | .driver_name = "generic_dpi_panel", | ||
284 | .data = &dvi_panel, | ||
277 | .phy.dpi.data_lines = 24, | 285 | .phy.dpi.data_lines = 24, |
278 | .platform_enable = sdp3430_panel_enable_dvi, | ||
279 | .platform_disable = sdp3430_panel_disable_dvi, | ||
280 | }; | 286 | }; |
281 | 287 | ||
282 | static struct omap_dss_device sdp3430_tv_device = { | 288 | static struct omap_dss_device sdp3430_tv_device = { |
diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c index 5d41dbe059a3..62645640f5e4 100644 --- a/arch/arm/mach-omap2/board-3630sdp.c +++ b/arch/arm/mach-omap2/board-3630sdp.c | |||
@@ -207,6 +207,7 @@ static void __init omap_sdp_init(void) | |||
207 | { | 207 | { |
208 | omap3_mux_init(board_mux, OMAP_PACKAGE_CBP); | 208 | omap3_mux_init(board_mux, OMAP_PACKAGE_CBP); |
209 | zoom_peripherals_init(); | 209 | zoom_peripherals_init(); |
210 | zoom_display_init(); | ||
210 | board_smc91x_init(); | 211 | board_smc91x_init(); |
211 | board_flash_init(sdp_flash_partitions, chip_sel_sdp); | 212 | board_flash_init(sdp_flash_partitions, chip_sel_sdp); |
212 | enable_board_wakeup_source(); | 213 | enable_board_wakeup_source(); |
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c index bc1562648020..10d60b7743cf 100644 --- a/arch/arm/mach-omap2/board-am3517evm.c +++ b/arch/arm/mach-omap2/board-am3517evm.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <plat/common.h> | 35 | #include <plat/common.h> |
36 | #include <plat/usb.h> | 36 | #include <plat/usb.h> |
37 | #include <plat/display.h> | 37 | #include <plat/display.h> |
38 | #include <plat/panel-generic-dpi.h> | ||
38 | 39 | ||
39 | #include "mux.h" | 40 | #include "mux.h" |
40 | #include "control.h" | 41 | #include "control.h" |
@@ -303,13 +304,18 @@ static void am3517_evm_panel_disable_lcd(struct omap_dss_device *dssdev) | |||
303 | lcd_enabled = 0; | 304 | lcd_enabled = 0; |
304 | } | 305 | } |
305 | 306 | ||
307 | static struct panel_generic_dpi_data lcd_panel = { | ||
308 | .name = "sharp_lq", | ||
309 | .platform_enable = am3517_evm_panel_enable_lcd, | ||
310 | .platform_disable = am3517_evm_panel_disable_lcd, | ||
311 | }; | ||
312 | |||
306 | static struct omap_dss_device am3517_evm_lcd_device = { | 313 | static struct omap_dss_device am3517_evm_lcd_device = { |
307 | .type = OMAP_DISPLAY_TYPE_DPI, | 314 | .type = OMAP_DISPLAY_TYPE_DPI, |
308 | .name = "lcd", | 315 | .name = "lcd", |
309 | .driver_name = "sharp_lq_panel", | 316 | .driver_name = "generic_dpi_panel", |
317 | .data = &lcd_panel, | ||
310 | .phy.dpi.data_lines = 16, | 318 | .phy.dpi.data_lines = 16, |
311 | .platform_enable = am3517_evm_panel_enable_lcd, | ||
312 | .platform_disable = am3517_evm_panel_disable_lcd, | ||
313 | }; | 319 | }; |
314 | 320 | ||
315 | static int am3517_evm_panel_enable_tv(struct omap_dss_device *dssdev) | 321 | static int am3517_evm_panel_enable_tv(struct omap_dss_device *dssdev) |
@@ -346,13 +352,18 @@ static void am3517_evm_panel_disable_dvi(struct omap_dss_device *dssdev) | |||
346 | dvi_enabled = 0; | 352 | dvi_enabled = 0; |
347 | } | 353 | } |
348 | 354 | ||
355 | static struct panel_generic_dpi_data dvi_panel = { | ||
356 | .name = "generic", | ||
357 | .platform_enable = am3517_evm_panel_enable_dvi, | ||
358 | .platform_disable = am3517_evm_panel_disable_dvi, | ||
359 | }; | ||
360 | |||
349 | static struct omap_dss_device am3517_evm_dvi_device = { | 361 | static struct omap_dss_device am3517_evm_dvi_device = { |
350 | .type = OMAP_DISPLAY_TYPE_DPI, | 362 | .type = OMAP_DISPLAY_TYPE_DPI, |
351 | .name = "dvi", | 363 | .name = "dvi", |
352 | .driver_name = "generic_panel", | 364 | .driver_name = "generic_dpi_panel", |
365 | .data = &dvi_panel, | ||
353 | .phy.dpi.data_lines = 24, | 366 | .phy.dpi.data_lines = 24, |
354 | .platform_enable = am3517_evm_panel_enable_dvi, | ||
355 | .platform_disable = am3517_evm_panel_disable_dvi, | ||
356 | }; | 367 | }; |
357 | 368 | ||
358 | static struct omap_dss_device *am3517_evm_dss_devices[] = { | 369 | static struct omap_dss_device *am3517_evm_dss_devices[] = { |
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index 486a3de5f401..dac141610666 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <plat/gpmc.h> | 46 | #include <plat/gpmc.h> |
47 | #include <plat/usb.h> | 47 | #include <plat/usb.h> |
48 | #include <plat/display.h> | 48 | #include <plat/display.h> |
49 | #include <plat/panel-generic-dpi.h> | ||
49 | #include <plat/mcspi.h> | 50 | #include <plat/mcspi.h> |
50 | 51 | ||
51 | #include <mach/hardware.h> | 52 | #include <mach/hardware.h> |
@@ -351,22 +352,32 @@ static void cm_t35_panel_disable_tv(struct omap_dss_device *dssdev) | |||
351 | { | 352 | { |
352 | } | 353 | } |
353 | 354 | ||
355 | static struct panel_generic_dpi_data lcd_panel = { | ||
356 | .name = "toppoly_tdo35s", | ||
357 | .platform_enable = cm_t35_panel_enable_lcd, | ||
358 | .platform_disable = cm_t35_panel_disable_lcd, | ||
359 | }; | ||
360 | |||
354 | static struct omap_dss_device cm_t35_lcd_device = { | 361 | static struct omap_dss_device cm_t35_lcd_device = { |
355 | .name = "lcd", | 362 | .name = "lcd", |
356 | .driver_name = "toppoly_tdo35s_panel", | ||
357 | .type = OMAP_DISPLAY_TYPE_DPI, | 363 | .type = OMAP_DISPLAY_TYPE_DPI, |
364 | .driver_name = "generic_dpi_panel", | ||
365 | .data = &lcd_panel, | ||
358 | .phy.dpi.data_lines = 18, | 366 | .phy.dpi.data_lines = 18, |
359 | .platform_enable = cm_t35_panel_enable_lcd, | 367 | }; |
360 | .platform_disable = cm_t35_panel_disable_lcd, | 368 | |
369 | static struct panel_generic_dpi_data dvi_panel = { | ||
370 | .name = "generic", | ||
371 | .platform_enable = cm_t35_panel_enable_dvi, | ||
372 | .platform_disable = cm_t35_panel_disable_dvi, | ||
361 | }; | 373 | }; |
362 | 374 | ||
363 | static struct omap_dss_device cm_t35_dvi_device = { | 375 | static struct omap_dss_device cm_t35_dvi_device = { |
364 | .name = "dvi", | 376 | .name = "dvi", |
365 | .driver_name = "generic_panel", | ||
366 | .type = OMAP_DISPLAY_TYPE_DPI, | 377 | .type = OMAP_DISPLAY_TYPE_DPI, |
378 | .driver_name = "generic_dpi_panel", | ||
379 | .data = &dvi_panel, | ||
367 | .phy.dpi.data_lines = 24, | 380 | .phy.dpi.data_lines = 24, |
368 | .platform_enable = cm_t35_panel_enable_dvi, | ||
369 | .platform_disable = cm_t35_panel_disable_dvi, | ||
370 | }; | 381 | }; |
371 | 382 | ||
372 | static struct omap_dss_device cm_t35_tv_device = { | 383 | static struct omap_dss_device cm_t35_tv_device = { |
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c index 451e7ff08b18..00bb1fc5e017 100644 --- a/arch/arm/mach-omap2/board-devkit8000.c +++ b/arch/arm/mach-omap2/board-devkit8000.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <plat/nand.h> | 46 | #include <plat/nand.h> |
47 | #include <plat/usb.h> | 47 | #include <plat/usb.h> |
48 | #include <plat/display.h> | 48 | #include <plat/display.h> |
49 | #include <plat/panel-generic-dpi.h> | ||
49 | 50 | ||
50 | #include <plat/mcspi.h> | 51 | #include <plat/mcspi.h> |
51 | #include <linux/input/matrix_keypad.h> | 52 | #include <linux/input/matrix_keypad.h> |
@@ -149,23 +150,32 @@ static struct regulator_consumer_supply devkit8000_vmmc1_supply = | |||
149 | static struct regulator_consumer_supply devkit8000_vio_supply = | 150 | static struct regulator_consumer_supply devkit8000_vio_supply = |
150 | REGULATOR_SUPPLY("vcc", "spi2.0"); | 151 | REGULATOR_SUPPLY("vcc", "spi2.0"); |
151 | 152 | ||
153 | static struct panel_generic_dpi_data lcd_panel = { | ||
154 | .name = "generic", | ||
155 | .platform_enable = devkit8000_panel_enable_lcd, | ||
156 | .platform_disable = devkit8000_panel_disable_lcd, | ||
157 | }; | ||
158 | |||
152 | static struct omap_dss_device devkit8000_lcd_device = { | 159 | static struct omap_dss_device devkit8000_lcd_device = { |
153 | .name = "lcd", | 160 | .name = "lcd", |
154 | .driver_name = "generic_panel", | ||
155 | .type = OMAP_DISPLAY_TYPE_DPI, | 161 | .type = OMAP_DISPLAY_TYPE_DPI, |
162 | .driver_name = "generic_dpi_panel", | ||
163 | .data = &lcd_panel, | ||
156 | .phy.dpi.data_lines = 24, | 164 | .phy.dpi.data_lines = 24, |
157 | .reset_gpio = -EINVAL, /* will be replaced */ | ||
158 | .platform_enable = devkit8000_panel_enable_lcd, | ||
159 | .platform_disable = devkit8000_panel_disable_lcd, | ||
160 | }; | 165 | }; |
166 | |||
167 | static struct panel_generic_dpi_data dvi_panel = { | ||
168 | .name = "generic", | ||
169 | .platform_enable = devkit8000_panel_enable_dvi, | ||
170 | .platform_disable = devkit8000_panel_disable_dvi, | ||
171 | }; | ||
172 | |||
161 | static struct omap_dss_device devkit8000_dvi_device = { | 173 | static struct omap_dss_device devkit8000_dvi_device = { |
162 | .name = "dvi", | 174 | .name = "dvi", |
163 | .driver_name = "generic_panel", | ||
164 | .type = OMAP_DISPLAY_TYPE_DPI, | 175 | .type = OMAP_DISPLAY_TYPE_DPI, |
176 | .driver_name = "generic_dpi_panel", | ||
177 | .data = &dvi_panel, | ||
165 | .phy.dpi.data_lines = 24, | 178 | .phy.dpi.data_lines = 24, |
166 | .reset_gpio = -EINVAL, /* will be replaced */ | ||
167 | .platform_enable = devkit8000_panel_enable_dvi, | ||
168 | .platform_disable = devkit8000_panel_disable_dvi, | ||
169 | }; | 179 | }; |
170 | 180 | ||
171 | static struct omap_dss_device devkit8000_tv_device = { | 181 | static struct omap_dss_device devkit8000_tv_device = { |
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c index 0afa3011db0f..ebaa230e67ed 100644 --- a/arch/arm/mach-omap2/board-igep0020.c +++ b/arch/arm/mach-omap2/board-igep0020.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <plat/gpmc.h> | 31 | #include <plat/gpmc.h> |
32 | #include <plat/usb.h> | 32 | #include <plat/usb.h> |
33 | #include <plat/display.h> | 33 | #include <plat/display.h> |
34 | #include <plat/panel-generic-dpi.h> | ||
34 | #include <plat/onenand.h> | 35 | #include <plat/onenand.h> |
35 | 36 | ||
36 | #include "mux.h" | 37 | #include "mux.h" |
@@ -459,13 +460,18 @@ static void igep2_disable_dvi(struct omap_dss_device *dssdev) | |||
459 | gpio_direction_output(IGEP2_GPIO_DVI_PUP, 0); | 460 | gpio_direction_output(IGEP2_GPIO_DVI_PUP, 0); |
460 | } | 461 | } |
461 | 462 | ||
463 | static struct panel_generic_dpi_data dvi_panel = { | ||
464 | .name = "generic", | ||
465 | .platform_enable = igep2_enable_dvi, | ||
466 | .platform_disable = igep2_disable_dvi, | ||
467 | }; | ||
468 | |||
462 | static struct omap_dss_device igep2_dvi_device = { | 469 | static struct omap_dss_device igep2_dvi_device = { |
463 | .type = OMAP_DISPLAY_TYPE_DPI, | 470 | .type = OMAP_DISPLAY_TYPE_DPI, |
464 | .name = "dvi", | 471 | .name = "dvi", |
465 | .driver_name = "generic_panel", | 472 | .driver_name = "generic_dpi_panel", |
473 | .data = &dvi_panel, | ||
466 | .phy.dpi.data_lines = 24, | 474 | .phy.dpi.data_lines = 24, |
467 | .platform_enable = igep2_enable_dvi, | ||
468 | .platform_disable = igep2_disable_dvi, | ||
469 | }; | 475 | }; |
470 | 476 | ||
471 | static struct omap_dss_device *igep2_dss_devices[] = { | 477 | static struct omap_dss_device *igep2_dss_devices[] = { |
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index 6c127605942f..a4fe8e1ee1bd 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <plat/board.h> | 41 | #include <plat/board.h> |
42 | #include <plat/common.h> | 42 | #include <plat/common.h> |
43 | #include <plat/display.h> | 43 | #include <plat/display.h> |
44 | #include <plat/panel-generic-dpi.h> | ||
44 | #include <plat/gpmc.h> | 45 | #include <plat/gpmc.h> |
45 | #include <plat/nand.h> | 46 | #include <plat/nand.h> |
46 | #include <plat/usb.h> | 47 | #include <plat/usb.h> |
@@ -194,14 +195,19 @@ static void beagle_disable_dvi(struct omap_dss_device *dssdev) | |||
194 | gpio_set_value(dssdev->reset_gpio, 0); | 195 | gpio_set_value(dssdev->reset_gpio, 0); |
195 | } | 196 | } |
196 | 197 | ||
198 | static struct panel_generic_dpi_data dvi_panel = { | ||
199 | .name = "generic", | ||
200 | .platform_enable = beagle_enable_dvi, | ||
201 | .platform_disable = beagle_disable_dvi, | ||
202 | }; | ||
203 | |||
197 | static struct omap_dss_device beagle_dvi_device = { | 204 | static struct omap_dss_device beagle_dvi_device = { |
198 | .type = OMAP_DISPLAY_TYPE_DPI, | 205 | .type = OMAP_DISPLAY_TYPE_DPI, |
199 | .name = "dvi", | 206 | .name = "dvi", |
200 | .driver_name = "generic_panel", | 207 | .driver_name = "generic_dpi_panel", |
208 | .data = &dvi_panel, | ||
201 | .phy.dpi.data_lines = 24, | 209 | .phy.dpi.data_lines = 24, |
202 | .reset_gpio = 170, | 210 | .reset_gpio = 170, |
203 | .platform_enable = beagle_enable_dvi, | ||
204 | .platform_disable = beagle_disable_dvi, | ||
205 | }; | 211 | }; |
206 | 212 | ||
207 | static struct omap_dss_device beagle_tv_device = { | 213 | static struct omap_dss_device beagle_tv_device = { |
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c index 3de8d9b8ec76..323c3809ce39 100644 --- a/arch/arm/mach-omap2/board-omap3evm.c +++ b/arch/arm/mach-omap2/board-omap3evm.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <plat/common.h> | 43 | #include <plat/common.h> |
44 | #include <plat/mcspi.h> | 44 | #include <plat/mcspi.h> |
45 | #include <plat/display.h> | 45 | #include <plat/display.h> |
46 | #include <plat/panel-generic-dpi.h> | ||
46 | 47 | ||
47 | #include "mux.h" | 48 | #include "mux.h" |
48 | #include "sdram-micron-mt46h32m32lf-6.h" | 49 | #include "sdram-micron-mt46h32m32lf-6.h" |
@@ -301,13 +302,18 @@ static void omap3_evm_disable_dvi(struct omap_dss_device *dssdev) | |||
301 | dvi_enabled = 0; | 302 | dvi_enabled = 0; |
302 | } | 303 | } |
303 | 304 | ||
305 | static struct panel_generic_dpi_data dvi_panel = { | ||
306 | .name = "generic", | ||
307 | .platform_enable = omap3_evm_enable_dvi, | ||
308 | .platform_disable = omap3_evm_disable_dvi, | ||
309 | }; | ||
310 | |||
304 | static struct omap_dss_device omap3_evm_dvi_device = { | 311 | static struct omap_dss_device omap3_evm_dvi_device = { |
305 | .name = "dvi", | 312 | .name = "dvi", |
306 | .driver_name = "generic_panel", | ||
307 | .type = OMAP_DISPLAY_TYPE_DPI, | 313 | .type = OMAP_DISPLAY_TYPE_DPI, |
314 | .driver_name = "generic_dpi_panel", | ||
315 | .data = &dvi_panel, | ||
308 | .phy.dpi.data_lines = 24, | 316 | .phy.dpi.data_lines = 24, |
309 | .platform_enable = omap3_evm_enable_dvi, | ||
310 | .platform_disable = omap3_evm_disable_dvi, | ||
311 | }; | 317 | }; |
312 | 318 | ||
313 | static struct omap_dss_device *omap3_evm_dss_devices[] = { | 319 | static struct omap_dss_device *omap3_evm_dss_devices[] = { |
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c index 9df9d9367608..2a2dad447e86 100644 --- a/arch/arm/mach-omap2/board-omap3stalker.c +++ b/arch/arm/mach-omap2/board-omap3stalker.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <plat/nand.h> | 40 | #include <plat/nand.h> |
41 | #include <plat/usb.h> | 41 | #include <plat/usb.h> |
42 | #include <plat/display.h> | 42 | #include <plat/display.h> |
43 | #include <plat/panel-generic-dpi.h> | ||
43 | 44 | ||
44 | #include <plat/mcspi.h> | 45 | #include <plat/mcspi.h> |
45 | #include <linux/input/matrix_keypad.h> | 46 | #include <linux/input/matrix_keypad.h> |
@@ -160,13 +161,18 @@ static void omap3_stalker_disable_lcd(struct omap_dss_device *dssdev) | |||
160 | lcd_enabled = 0; | 161 | lcd_enabled = 0; |
161 | } | 162 | } |
162 | 163 | ||
164 | static struct panel_generic_dpi_data lcd_panel = { | ||
165 | .name = "generic", | ||
166 | .platform_enable = omap3_stalker_enable_lcd, | ||
167 | .platform_disable = omap3_stalker_disable_lcd, | ||
168 | }; | ||
169 | |||
163 | static struct omap_dss_device omap3_stalker_lcd_device = { | 170 | static struct omap_dss_device omap3_stalker_lcd_device = { |
164 | .name = "lcd", | 171 | .name = "lcd", |
165 | .driver_name = "generic_panel", | 172 | .driver_name = "generic_dpi_panel", |
173 | .data = &lcd_panel, | ||
166 | .phy.dpi.data_lines = 24, | 174 | .phy.dpi.data_lines = 24, |
167 | .type = OMAP_DISPLAY_TYPE_DPI, | 175 | .type = OMAP_DISPLAY_TYPE_DPI, |
168 | .platform_enable = omap3_stalker_enable_lcd, | ||
169 | .platform_disable = omap3_stalker_disable_lcd, | ||
170 | }; | 176 | }; |
171 | 177 | ||
172 | static int omap3_stalker_enable_tv(struct omap_dss_device *dssdev) | 178 | static int omap3_stalker_enable_tv(struct omap_dss_device *dssdev) |
@@ -208,13 +214,18 @@ static void omap3_stalker_disable_dvi(struct omap_dss_device *dssdev) | |||
208 | dvi_enabled = 0; | 214 | dvi_enabled = 0; |
209 | } | 215 | } |
210 | 216 | ||
217 | static struct panel_generic_dpi_data dvi_panel = { | ||
218 | .name = "generic", | ||
219 | .platform_enable = omap3_stalker_enable_dvi, | ||
220 | .platform_disable = omap3_stalker_disable_dvi, | ||
221 | }; | ||
222 | |||
211 | static struct omap_dss_device omap3_stalker_dvi_device = { | 223 | static struct omap_dss_device omap3_stalker_dvi_device = { |
212 | .name = "dvi", | 224 | .name = "dvi", |
213 | .driver_name = "generic_panel", | ||
214 | .type = OMAP_DISPLAY_TYPE_DPI, | 225 | .type = OMAP_DISPLAY_TYPE_DPI, |
226 | .driver_name = "generic_dpi_panel", | ||
227 | .data = &dvi_panel, | ||
215 | .phy.dpi.data_lines = 24, | 228 | .phy.dpi.data_lines = 24, |
216 | .platform_enable = omap3_stalker_enable_dvi, | ||
217 | .platform_disable = omap3_stalker_disable_dvi, | ||
218 | }; | 229 | }; |
219 | 230 | ||
220 | static struct omap_dss_device *omap3_stalker_dss_devices[] = { | 231 | static struct omap_dss_device *omap3_stalker_dss_devices[] = { |
diff --git a/arch/arm/mach-omap2/board-zoom-display.c b/arch/arm/mach-omap2/board-zoom-display.c new file mode 100644 index 000000000000..6bcd43657aed --- /dev/null +++ b/arch/arm/mach-omap2/board-zoom-display.c | |||
@@ -0,0 +1,168 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 Texas Instruments Inc. | ||
3 | * | ||
4 | * Modified from mach-omap2/board-zoom-peripherals.c | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/gpio.h> | ||
15 | #include <linux/i2c/twl.h> | ||
16 | #include <linux/spi/spi.h> | ||
17 | #include <plat/mcspi.h> | ||
18 | #include <plat/display.h> | ||
19 | |||
20 | #define LCD_PANEL_RESET_GPIO_PROD 96 | ||
21 | #define LCD_PANEL_RESET_GPIO_PILOT 55 | ||
22 | #define LCD_PANEL_QVGA_GPIO 56 | ||
23 | |||
24 | static void zoom_lcd_panel_init(void) | ||
25 | { | ||
26 | int ret; | ||
27 | unsigned char lcd_panel_reset_gpio; | ||
28 | |||
29 | lcd_panel_reset_gpio = (omap_rev() > OMAP3430_REV_ES3_0) ? | ||
30 | LCD_PANEL_RESET_GPIO_PROD : | ||
31 | LCD_PANEL_RESET_GPIO_PILOT; | ||
32 | |||
33 | ret = gpio_request(lcd_panel_reset_gpio, "lcd reset"); | ||
34 | if (ret) { | ||
35 | pr_err("Failed to get LCD reset GPIO (gpio%d).\n", | ||
36 | lcd_panel_reset_gpio); | ||
37 | return; | ||
38 | } | ||
39 | gpio_direction_output(lcd_panel_reset_gpio, 1); | ||
40 | |||
41 | ret = gpio_request(LCD_PANEL_QVGA_GPIO, "lcd qvga"); | ||
42 | if (ret) { | ||
43 | pr_err("Failed to get LCD_PANEL_QVGA_GPIO (gpio%d).\n", | ||
44 | LCD_PANEL_QVGA_GPIO); | ||
45 | goto err0; | ||
46 | } | ||
47 | gpio_direction_output(LCD_PANEL_QVGA_GPIO, 1); | ||
48 | |||
49 | return; | ||
50 | err0: | ||
51 | gpio_free(lcd_panel_reset_gpio); | ||
52 | } | ||
53 | |||
54 | static int zoom_panel_enable_lcd(struct omap_dss_device *dssdev) | ||
55 | { | ||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | static void zoom_panel_disable_lcd(struct omap_dss_device *dssdev) | ||
60 | { | ||
61 | } | ||
62 | |||
63 | /* | ||
64 | * PWMA/B register offsets (TWL4030_MODULE_PWMA) | ||
65 | */ | ||
66 | #define TWL_INTBR_PMBR1 0xD | ||
67 | #define TWL_INTBR_GPBR1 0xC | ||
68 | #define TWL_LED_PWMON 0x0 | ||
69 | #define TWL_LED_PWMOFF 0x1 | ||
70 | |||
71 | static int zoom_set_bl_intensity(struct omap_dss_device *dssdev, int level) | ||
72 | { | ||
73 | unsigned char c; | ||
74 | u8 mux_pwm, enb_pwm; | ||
75 | |||
76 | if (level > 100) | ||
77 | return -1; | ||
78 | |||
79 | twl_i2c_read_u8(TWL4030_MODULE_INTBR, &mux_pwm, TWL_INTBR_PMBR1); | ||
80 | twl_i2c_read_u8(TWL4030_MODULE_INTBR, &enb_pwm, TWL_INTBR_GPBR1); | ||
81 | |||
82 | if (level == 0) { | ||
83 | /* disable pwm1 output and clock */ | ||
84 | enb_pwm = enb_pwm & 0xF5; | ||
85 | /* change pwm1 pin to gpio pin */ | ||
86 | mux_pwm = mux_pwm & 0xCF; | ||
87 | twl_i2c_write_u8(TWL4030_MODULE_INTBR, | ||
88 | enb_pwm, TWL_INTBR_GPBR1); | ||
89 | twl_i2c_write_u8(TWL4030_MODULE_INTBR, | ||
90 | mux_pwm, TWL_INTBR_PMBR1); | ||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | if (!((enb_pwm & 0xA) && (mux_pwm & 0x30))) { | ||
95 | /* change gpio pin to pwm1 pin */ | ||
96 | mux_pwm = mux_pwm | 0x30; | ||
97 | /* enable pwm1 output and clock*/ | ||
98 | enb_pwm = enb_pwm | 0x0A; | ||
99 | twl_i2c_write_u8(TWL4030_MODULE_INTBR, | ||
100 | mux_pwm, TWL_INTBR_PMBR1); | ||
101 | twl_i2c_write_u8(TWL4030_MODULE_INTBR, | ||
102 | enb_pwm, TWL_INTBR_GPBR1); | ||
103 | } | ||
104 | |||
105 | c = ((50 * (100 - level)) / 100) + 1; | ||
106 | twl_i2c_write_u8(TWL4030_MODULE_PWM1, 0x7F, TWL_LED_PWMOFF); | ||
107 | twl_i2c_write_u8(TWL4030_MODULE_PWM1, c, TWL_LED_PWMON); | ||
108 | |||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | static struct omap_dss_device zoom_lcd_device = { | ||
113 | .name = "lcd", | ||
114 | .driver_name = "NEC_8048_panel", | ||
115 | .type = OMAP_DISPLAY_TYPE_DPI, | ||
116 | .phy.dpi.data_lines = 24, | ||
117 | .platform_enable = zoom_panel_enable_lcd, | ||
118 | .platform_disable = zoom_panel_disable_lcd, | ||
119 | .max_backlight_level = 100, | ||
120 | .set_backlight = zoom_set_bl_intensity, | ||
121 | }; | ||
122 | |||
123 | static struct omap_dss_device *zoom_dss_devices[] = { | ||
124 | &zoom_lcd_device, | ||
125 | }; | ||
126 | |||
127 | static struct omap_dss_board_info zoom_dss_data = { | ||
128 | .num_devices = ARRAY_SIZE(zoom_dss_devices), | ||
129 | .devices = zoom_dss_devices, | ||
130 | .default_device = &zoom_lcd_device, | ||
131 | }; | ||
132 | |||
133 | static struct platform_device zoom_dss_device = { | ||
134 | .name = "omapdss", | ||
135 | .id = -1, | ||
136 | .dev = { | ||
137 | .platform_data = &zoom_dss_data, | ||
138 | }, | ||
139 | }; | ||
140 | |||
141 | static struct omap2_mcspi_device_config dss_lcd_mcspi_config = { | ||
142 | .turbo_mode = 1, | ||
143 | .single_channel = 1, /* 0: slave, 1: master */ | ||
144 | }; | ||
145 | |||
146 | static struct spi_board_info nec_8048_spi_board_info[] __initdata = { | ||
147 | [0] = { | ||
148 | .modalias = "nec_8048_spi", | ||
149 | .bus_num = 1, | ||
150 | .chip_select = 2, | ||
151 | .max_speed_hz = 375000, | ||
152 | .controller_data = &dss_lcd_mcspi_config, | ||
153 | }, | ||
154 | }; | ||
155 | |||
156 | static struct platform_device *zoom_display_devices[] __initdata = { | ||
157 | &zoom_dss_device, | ||
158 | }; | ||
159 | |||
160 | void __init zoom_display_init(void) | ||
161 | { | ||
162 | platform_add_devices(zoom_display_devices, | ||
163 | ARRAY_SIZE(zoom_display_devices)); | ||
164 | spi_register_board_info(nec_8048_spi_board_info, | ||
165 | ARRAY_SIZE(nec_8048_spi_board_info)); | ||
166 | zoom_lcd_panel_init(); | ||
167 | } | ||
168 | |||
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c index 3fbd0edd712e..14d95afa3f0d 100644 --- a/arch/arm/mach-omap2/board-zoom-peripherals.c +++ b/arch/arm/mach-omap2/board-zoom-peripherals.c | |||
@@ -35,6 +35,8 @@ | |||
35 | #define OMAP_ZOOM_WLAN_PMENA_GPIO (101) | 35 | #define OMAP_ZOOM_WLAN_PMENA_GPIO (101) |
36 | #define OMAP_ZOOM_WLAN_IRQ_GPIO (162) | 36 | #define OMAP_ZOOM_WLAN_IRQ_GPIO (162) |
37 | 37 | ||
38 | #define LCD_PANEL_ENABLE_GPIO (7 + OMAP_MAX_GPIO_LINES) | ||
39 | |||
38 | /* Zoom2 has Qwerty keyboard*/ | 40 | /* Zoom2 has Qwerty keyboard*/ |
39 | static uint32_t board_keymap[] = { | 41 | static uint32_t board_keymap[] = { |
40 | KEY(0, 0, KEY_E), | 42 | KEY(0, 0, KEY_E), |
@@ -224,9 +226,43 @@ static struct omap2_hsmmc_info mmc[] = { | |||
224 | {} /* Terminator */ | 226 | {} /* Terminator */ |
225 | }; | 227 | }; |
226 | 228 | ||
229 | static struct regulator_consumer_supply zoom_vpll2_supply = | ||
230 | REGULATOR_SUPPLY("vdds_dsi", "omapdss"); | ||
231 | |||
232 | static struct regulator_consumer_supply zoom_vdda_dac_supply = | ||
233 | REGULATOR_SUPPLY("vdda_dac", "omapdss"); | ||
234 | |||
235 | static struct regulator_init_data zoom_vpll2 = { | ||
236 | .constraints = { | ||
237 | .min_uV = 1800000, | ||
238 | .max_uV = 1800000, | ||
239 | .valid_modes_mask = REGULATOR_MODE_NORMAL | ||
240 | | REGULATOR_MODE_STANDBY, | ||
241 | .valid_ops_mask = REGULATOR_CHANGE_MODE | ||
242 | | REGULATOR_CHANGE_STATUS, | ||
243 | }, | ||
244 | .num_consumer_supplies = 1, | ||
245 | .consumer_supplies = &zoom_vpll2_supply, | ||
246 | }; | ||
247 | |||
248 | static struct regulator_init_data zoom_vdac = { | ||
249 | .constraints = { | ||
250 | .min_uV = 1800000, | ||
251 | .max_uV = 1800000, | ||
252 | .valid_modes_mask = REGULATOR_MODE_NORMAL | ||
253 | | REGULATOR_MODE_STANDBY, | ||
254 | .valid_ops_mask = REGULATOR_CHANGE_MODE | ||
255 | | REGULATOR_CHANGE_STATUS, | ||
256 | }, | ||
257 | .num_consumer_supplies = 1, | ||
258 | .consumer_supplies = &zoom_vdda_dac_supply, | ||
259 | }; | ||
260 | |||
227 | static int zoom_twl_gpio_setup(struct device *dev, | 261 | static int zoom_twl_gpio_setup(struct device *dev, |
228 | unsigned gpio, unsigned ngpio) | 262 | unsigned gpio, unsigned ngpio) |
229 | { | 263 | { |
264 | int ret; | ||
265 | |||
230 | /* gpio + 0 is "mmc0_cd" (input/IRQ) */ | 266 | /* gpio + 0 is "mmc0_cd" (input/IRQ) */ |
231 | mmc[0].gpio_cd = gpio + 0; | 267 | mmc[0].gpio_cd = gpio + 0; |
232 | omap2_hsmmc_init(mmc); | 268 | omap2_hsmmc_init(mmc); |
@@ -238,7 +274,15 @@ static int zoom_twl_gpio_setup(struct device *dev, | |||
238 | zoom_vsim_supply.dev = mmc[0].dev; | 274 | zoom_vsim_supply.dev = mmc[0].dev; |
239 | zoom_vmmc2_supply.dev = mmc[1].dev; | 275 | zoom_vmmc2_supply.dev = mmc[1].dev; |
240 | 276 | ||
241 | return 0; | 277 | ret = gpio_request(LCD_PANEL_ENABLE_GPIO, "lcd enable"); |
278 | if (ret) { | ||
279 | pr_err("Failed to get LCD_PANEL_ENABLE_GPIO (gpio%d).\n", | ||
280 | LCD_PANEL_ENABLE_GPIO); | ||
281 | return ret; | ||
282 | } | ||
283 | gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 0); | ||
284 | |||
285 | return ret; | ||
242 | } | 286 | } |
243 | 287 | ||
244 | /* EXTMUTE callback function */ | 288 | /* EXTMUTE callback function */ |
@@ -301,7 +345,8 @@ static struct twl4030_platform_data zoom_twldata = { | |||
301 | .vmmc1 = &zoom_vmmc1, | 345 | .vmmc1 = &zoom_vmmc1, |
302 | .vmmc2 = &zoom_vmmc2, | 346 | .vmmc2 = &zoom_vmmc2, |
303 | .vsim = &zoom_vsim, | 347 | .vsim = &zoom_vsim, |
304 | 348 | .vpll2 = &zoom_vpll2, | |
349 | .vdac = &zoom_vdac, | ||
305 | }; | 350 | }; |
306 | 351 | ||
307 | static struct i2c_board_info __initdata zoom_i2c_boardinfo[] = { | 352 | static struct i2c_board_info __initdata zoom_i2c_boardinfo[] = { |
diff --git a/arch/arm/mach-omap2/board-zoom.c b/arch/arm/mach-omap2/board-zoom.c index e041c537ea37..e26754c24ee8 100644 --- a/arch/arm/mach-omap2/board-zoom.c +++ b/arch/arm/mach-omap2/board-zoom.c | |||
@@ -130,6 +130,7 @@ static void __init omap_zoom_init(void) | |||
130 | ARRAY_SIZE(zoom_nand_partitions), ZOOM_NAND_CS); | 130 | ARRAY_SIZE(zoom_nand_partitions), ZOOM_NAND_CS); |
131 | zoom_debugboard_init(); | 131 | zoom_debugboard_init(); |
132 | zoom_peripherals_init(); | 132 | zoom_peripherals_init(); |
133 | zoom_display_init(); | ||
133 | } | 134 | } |
134 | 135 | ||
135 | MACHINE_START(OMAP_ZOOM2, "OMAP Zoom2 board") | 136 | MACHINE_START(OMAP_ZOOM2, "OMAP Zoom2 board") |
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index f3e043fe5eb8..f7b22a16f385 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c | |||
@@ -47,6 +47,8 @@ | |||
47 | 47 | ||
48 | #define OMAP3_STATE_MAX OMAP3_STATE_C7 | 48 | #define OMAP3_STATE_MAX OMAP3_STATE_C7 |
49 | 49 | ||
50 | #define CPUIDLE_FLAG_CHECK_BM 0x10000 /* use omap3_enter_idle_bm() */ | ||
51 | |||
50 | struct omap3_processor_cx { | 52 | struct omap3_processor_cx { |
51 | u8 valid; | 53 | u8 valid; |
52 | u8 type; | 54 | u8 type; |
@@ -252,7 +254,7 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev, | |||
252 | * FIXME: we currently manage device-specific idle states | 254 | * FIXME: we currently manage device-specific idle states |
253 | * for PER and CORE in combination with CPU-specific | 255 | * for PER and CORE in combination with CPU-specific |
254 | * idle states. This is wrong, and device-specific | 256 | * idle states. This is wrong, and device-specific |
255 | * idle managment needs to be separated out into | 257 | * idle management needs to be separated out into |
256 | * its own code. | 258 | * its own code. |
257 | */ | 259 | */ |
258 | 260 | ||
diff --git a/arch/arm/mach-omap2/include/mach/board-zoom.h b/arch/arm/mach-omap2/include/mach/board-zoom.h index f93ca3928c3b..d20bd9c1a106 100644 --- a/arch/arm/mach-omap2/include/mach/board-zoom.h +++ b/arch/arm/mach-omap2/include/mach/board-zoom.h | |||
@@ -1,9 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * Defines for zoom boards | 2 | * Defines for zoom boards |
3 | */ | 3 | */ |
4 | #include <plat/display.h> | ||
5 | |||
4 | #define ZOOM_NAND_CS 0 | 6 | #define ZOOM_NAND_CS 0 |
5 | 7 | ||
6 | extern int __init zoom_debugboard_init(void); | 8 | extern int __init zoom_debugboard_init(void); |
7 | extern void __init zoom_peripherals_init(void); | 9 | extern void __init zoom_peripherals_init(void); |
10 | extern void __init zoom_display_init(void); | ||
8 | 11 | ||
9 | #define ZOOM2_HEADSET_EXTMUTE_GPIO 153 | 12 | #define ZOOM2_HEADSET_EXTMUTE_GPIO 153 |
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index dac2d1d9987d..9e5dc8ed51e9 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c | |||
@@ -350,7 +350,7 @@ static void omap2_pm_end(void) | |||
350 | enable_hlt(); | 350 | enable_hlt(); |
351 | } | 351 | } |
352 | 352 | ||
353 | static struct platform_suspend_ops omap_pm_ops = { | 353 | static const struct platform_suspend_ops omap_pm_ops = { |
354 | .begin = omap2_pm_begin, | 354 | .begin = omap2_pm_begin, |
355 | .enter = omap2_pm_enter, | 355 | .enter = omap2_pm_enter, |
356 | .end = omap2_pm_end, | 356 | .end = omap2_pm_end, |
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 5b323f28da2d..8cbbeade4b8a 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c | |||
@@ -605,7 +605,7 @@ static void omap3_pm_end(void) | |||
605 | return; | 605 | return; |
606 | } | 606 | } |
607 | 607 | ||
608 | static struct platform_suspend_ops omap_pm_ops = { | 608 | static const struct platform_suspend_ops omap_pm_ops = { |
609 | .begin = omap3_pm_begin, | 609 | .begin = omap3_pm_begin, |
610 | .end = omap3_pm_end, | 610 | .end = omap3_pm_end, |
611 | .enter = omap3_pm_enter, | 611 | .enter = omap3_pm_enter, |
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index e9f4862c4de4..76cfff2db514 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c | |||
@@ -65,7 +65,7 @@ static void omap4_pm_end(void) | |||
65 | return; | 65 | return; |
66 | } | 66 | } |
67 | 67 | ||
68 | static struct platform_suspend_ops omap_pm_ops = { | 68 | static const struct platform_suspend_ops omap_pm_ops = { |
69 | .begin = omap4_pm_begin, | 69 | .begin = omap4_pm_begin, |
70 | .end = omap4_pm_end, | 70 | .end = omap4_pm_end, |
71 | .enter = omap4_pm_enter, | 71 | .enter = omap4_pm_enter, |
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index c64578853a8d..302da7403a10 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c | |||
@@ -852,7 +852,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) | |||
852 | } | 852 | } |
853 | 853 | ||
854 | /** | 854 | /** |
855 | * omap_serial_init() - intialize all supported serial ports | 855 | * omap_serial_init() - initialize all supported serial ports |
856 | * | 856 | * |
857 | * Initializes all available UARTs as serial ports. Platforms | 857 | * Initializes all available UARTs as serial ports. Platforms |
858 | * can call this function when they want to have default behaviour | 858 | * can call this function when they want to have default behaviour |
diff --git a/arch/arm/mach-pnx4008/pm.c b/arch/arm/mach-pnx4008/pm.c index ee3c29c57ae3..f3e60a049f98 100644 --- a/arch/arm/mach-pnx4008/pm.c +++ b/arch/arm/mach-pnx4008/pm.c | |||
@@ -119,7 +119,7 @@ static int pnx4008_pm_valid(suspend_state_t state) | |||
119 | (state == PM_SUSPEND_MEM); | 119 | (state == PM_SUSPEND_MEM); |
120 | } | 120 | } |
121 | 121 | ||
122 | static struct platform_suspend_ops pnx4008_pm_ops = { | 122 | static const struct platform_suspend_ops pnx4008_pm_ops = { |
123 | .enter = pnx4008_pm_enter, | 123 | .enter = pnx4008_pm_enter, |
124 | .valid = pnx4008_pm_valid, | 124 | .valid = pnx4008_pm_valid, |
125 | }; | 125 | }; |
diff --git a/arch/arm/mach-pxa/mxm8x10.c b/arch/arm/mach-pxa/mxm8x10.c index 462167ac05f9..cdf7f41e2bb3 100644 --- a/arch/arm/mach-pxa/mxm8x10.c +++ b/arch/arm/mach-pxa/mxm8x10.c | |||
@@ -337,7 +337,7 @@ void __init mxm_8x10_mmc_init(void) | |||
337 | } | 337 | } |
338 | #endif | 338 | #endif |
339 | 339 | ||
340 | /* USB Open Host Controler Interface */ | 340 | /* USB Open Host Controller Interface */ |
341 | static struct pxaohci_platform_data mxm_8x10_ohci_platform_data = { | 341 | static struct pxaohci_platform_data mxm_8x10_ohci_platform_data = { |
342 | .port_mode = PMM_NPS_MODE, | 342 | .port_mode = PMM_NPS_MODE, |
343 | .flags = ENABLE_PORT_ALL | 343 | .flags = ENABLE_PORT_ALL |
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c index 166c15f62916..978e1b289544 100644 --- a/arch/arm/mach-pxa/pm.c +++ b/arch/arm/mach-pxa/pm.c | |||
@@ -96,7 +96,7 @@ void pxa_pm_finish(void) | |||
96 | pxa_cpu_pm_fns->finish(); | 96 | pxa_cpu_pm_fns->finish(); |
97 | } | 97 | } |
98 | 98 | ||
99 | static struct platform_suspend_ops pxa_pm_ops = { | 99 | static const struct platform_suspend_ops pxa_pm_ops = { |
100 | .valid = pxa_pm_valid, | 100 | .valid = pxa_pm_valid, |
101 | .enter = pxa_pm_enter, | 101 | .enter = pxa_pm_enter, |
102 | .prepare = pxa_pm_prepare, | 102 | .prepare = pxa_pm_prepare, |
diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c index e68d46d415f3..785880f67b60 100644 --- a/arch/arm/mach-pxa/sharpsl_pm.c +++ b/arch/arm/mach-pxa/sharpsl_pm.c | |||
@@ -869,7 +869,7 @@ static void sharpsl_apm_get_power_status(struct apm_power_info *info) | |||
869 | } | 869 | } |
870 | 870 | ||
871 | #ifdef CONFIG_PM | 871 | #ifdef CONFIG_PM |
872 | static struct platform_suspend_ops sharpsl_pm_ops = { | 872 | static const struct platform_suspend_ops sharpsl_pm_ops = { |
873 | .prepare = pxa_pm_prepare, | 873 | .prepare = pxa_pm_prepare, |
874 | .finish = pxa_pm_finish, | 874 | .finish = pxa_pm_finish, |
875 | .enter = corgi_pxa_pm_enter, | 875 | .enter = corgi_pxa_pm_enter, |
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c index d7ada8c7e41f..1a81fe12ccd7 100644 --- a/arch/arm/mach-s3c2410/mach-h1940.c +++ b/arch/arm/mach-s3c2410/mach-h1940.c | |||
@@ -387,7 +387,7 @@ static struct platform_device *h1940_devices[] __initdata = { | |||
387 | &s3c_device_wdt, | 387 | &s3c_device_wdt, |
388 | &s3c_device_i2c0, | 388 | &s3c_device_i2c0, |
389 | &s3c_device_iis, | 389 | &s3c_device_iis, |
390 | &s3c_device_pcm, | 390 | &samsung_asoc_dma, |
391 | &s3c_device_usbgadget, | 391 | &s3c_device_usbgadget, |
392 | &h1940_device_leds, | 392 | &h1940_device_leds, |
393 | &h1940_device_bluetooth, | 393 | &h1940_device_bluetooth, |
diff --git a/arch/arm/mach-s3c2440/mach-rx1950.c b/arch/arm/mach-s3c2440/mach-rx1950.c index e0622bbb6dfa..eab6ae50683c 100644 --- a/arch/arm/mach-s3c2440/mach-rx1950.c +++ b/arch/arm/mach-s3c2440/mach-rx1950.c | |||
@@ -692,7 +692,7 @@ static struct platform_device *rx1950_devices[] __initdata = { | |||
692 | &s3c_device_wdt, | 692 | &s3c_device_wdt, |
693 | &s3c_device_i2c0, | 693 | &s3c_device_i2c0, |
694 | &s3c_device_iis, | 694 | &s3c_device_iis, |
695 | &s3c_device_pcm, | 695 | &samsung_asoc_dma, |
696 | &s3c_device_usbgadget, | 696 | &s3c_device_usbgadget, |
697 | &s3c_device_rtc, | 697 | &s3c_device_rtc, |
698 | &s3c_device_nand, | 698 | &s3c_device_nand, |
diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c index 7e03f0ae2fc8..1c98d2ff2ed6 100644 --- a/arch/arm/mach-s3c64xx/clock.c +++ b/arch/arm/mach-s3c64xx/clock.c | |||
@@ -695,7 +695,7 @@ static struct clksrc_clk clksrcs[] = { | |||
695 | }, { | 695 | }, { |
696 | .clk = { | 696 | .clk = { |
697 | .name = "audio-bus", | 697 | .name = "audio-bus", |
698 | .id = -1, /* There's only one IISv4 port */ | 698 | .id = 2, |
699 | .ctrlbit = S3C6410_CLKCON_SCLK_AUDIO2, | 699 | .ctrlbit = S3C6410_CLKCON_SCLK_AUDIO2, |
700 | .enable = s3c64xx_sclk_ctrl, | 700 | .enable = s3c64xx_sclk_ctrl, |
701 | }, | 701 | }, |
diff --git a/arch/arm/mach-s3c64xx/dev-audio.c b/arch/arm/mach-s3c64xx/dev-audio.c index 76426a32c013..cad67022fa25 100644 --- a/arch/arm/mach-s3c64xx/dev-audio.c +++ b/arch/arm/mach-s3c64xx/dev-audio.c | |||
@@ -22,7 +22,12 @@ | |||
22 | #include <plat/audio.h> | 22 | #include <plat/audio.h> |
23 | #include <plat/gpio-cfg.h> | 23 | #include <plat/gpio-cfg.h> |
24 | 24 | ||
25 | static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev) | 25 | static const char *rclksrc[] = { |
26 | [0] = "iis", | ||
27 | [1] = "audio-bus", | ||
28 | }; | ||
29 | |||
30 | static int s3c64xx_i2s_cfg_gpio(struct platform_device *pdev) | ||
26 | { | 31 | { |
27 | unsigned int base; | 32 | unsigned int base; |
28 | 33 | ||
@@ -33,6 +38,12 @@ static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev) | |||
33 | case 1: | 38 | case 1: |
34 | base = S3C64XX_GPE(0); | 39 | base = S3C64XX_GPE(0); |
35 | break; | 40 | break; |
41 | case 2: | ||
42 | s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C_GPIO_SFN(5)); | ||
43 | s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C_GPIO_SFN(5)); | ||
44 | s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C_GPIO_SFN(5)); | ||
45 | s3c_gpio_cfgpin_range(S3C64XX_GPH(6), 4, S3C_GPIO_SFN(5)); | ||
46 | return 0; | ||
36 | default: | 47 | default: |
37 | printk(KERN_DEBUG "Invalid I2S Controller number: %d\n", | 48 | printk(KERN_DEBUG "Invalid I2S Controller number: %d\n", |
38 | pdev->id); | 49 | pdev->id); |
@@ -44,16 +55,6 @@ static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev) | |||
44 | return 0; | 55 | return 0; |
45 | } | 56 | } |
46 | 57 | ||
47 | static int s3c64xx_i2sv4_cfg_gpio(struct platform_device *pdev) | ||
48 | { | ||
49 | s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C_GPIO_SFN(5)); | ||
50 | s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C_GPIO_SFN(5)); | ||
51 | s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C_GPIO_SFN(5)); | ||
52 | s3c_gpio_cfgpin_range(S3C64XX_GPH(6), 4, S3C_GPIO_SFN(5)); | ||
53 | |||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | static struct resource s3c64xx_iis0_resource[] = { | 58 | static struct resource s3c64xx_iis0_resource[] = { |
58 | [0] = { | 59 | [0] = { |
59 | .start = S3C64XX_PA_IIS0, | 60 | .start = S3C64XX_PA_IIS0, |
@@ -72,17 +73,22 @@ static struct resource s3c64xx_iis0_resource[] = { | |||
72 | }, | 73 | }, |
73 | }; | 74 | }; |
74 | 75 | ||
75 | static struct s3c_audio_pdata s3c_i2s0_pdata = { | 76 | static struct s3c_audio_pdata i2sv3_pdata = { |
76 | .cfg_gpio = s3c64xx_i2sv3_cfg_gpio, | 77 | .cfg_gpio = s3c64xx_i2s_cfg_gpio, |
78 | .type = { | ||
79 | .i2s = { | ||
80 | .src_clk = rclksrc, | ||
81 | }, | ||
82 | }, | ||
77 | }; | 83 | }; |
78 | 84 | ||
79 | struct platform_device s3c64xx_device_iis0 = { | 85 | struct platform_device s3c64xx_device_iis0 = { |
80 | .name = "s3c64xx-iis", | 86 | .name = "samsung-i2s", |
81 | .id = 0, | 87 | .id = 0, |
82 | .num_resources = ARRAY_SIZE(s3c64xx_iis0_resource), | 88 | .num_resources = ARRAY_SIZE(s3c64xx_iis0_resource), |
83 | .resource = s3c64xx_iis0_resource, | 89 | .resource = s3c64xx_iis0_resource, |
84 | .dev = { | 90 | .dev = { |
85 | .platform_data = &s3c_i2s0_pdata, | 91 | .platform_data = &i2sv3_pdata, |
86 | }, | 92 | }, |
87 | }; | 93 | }; |
88 | EXPORT_SYMBOL(s3c64xx_device_iis0); | 94 | EXPORT_SYMBOL(s3c64xx_device_iis0); |
@@ -105,17 +111,13 @@ static struct resource s3c64xx_iis1_resource[] = { | |||
105 | }, | 111 | }, |
106 | }; | 112 | }; |
107 | 113 | ||
108 | static struct s3c_audio_pdata s3c_i2s1_pdata = { | ||
109 | .cfg_gpio = s3c64xx_i2sv3_cfg_gpio, | ||
110 | }; | ||
111 | |||
112 | struct platform_device s3c64xx_device_iis1 = { | 114 | struct platform_device s3c64xx_device_iis1 = { |
113 | .name = "s3c64xx-iis", | 115 | .name = "samsung-i2s", |
114 | .id = 1, | 116 | .id = 1, |
115 | .num_resources = ARRAY_SIZE(s3c64xx_iis1_resource), | 117 | .num_resources = ARRAY_SIZE(s3c64xx_iis1_resource), |
116 | .resource = s3c64xx_iis1_resource, | 118 | .resource = s3c64xx_iis1_resource, |
117 | .dev = { | 119 | .dev = { |
118 | .platform_data = &s3c_i2s1_pdata, | 120 | .platform_data = &i2sv3_pdata, |
119 | }, | 121 | }, |
120 | }; | 122 | }; |
121 | EXPORT_SYMBOL(s3c64xx_device_iis1); | 123 | EXPORT_SYMBOL(s3c64xx_device_iis1); |
@@ -138,17 +140,23 @@ static struct resource s3c64xx_iisv4_resource[] = { | |||
138 | }, | 140 | }, |
139 | }; | 141 | }; |
140 | 142 | ||
141 | static struct s3c_audio_pdata s3c_i2sv4_pdata = { | 143 | static struct s3c_audio_pdata i2sv4_pdata = { |
142 | .cfg_gpio = s3c64xx_i2sv4_cfg_gpio, | 144 | .cfg_gpio = s3c64xx_i2s_cfg_gpio, |
145 | .type = { | ||
146 | .i2s = { | ||
147 | .quirks = QUIRK_PRI_6CHAN, | ||
148 | .src_clk = rclksrc, | ||
149 | }, | ||
150 | }, | ||
143 | }; | 151 | }; |
144 | 152 | ||
145 | struct platform_device s3c64xx_device_iisv4 = { | 153 | struct platform_device s3c64xx_device_iisv4 = { |
146 | .name = "s3c64xx-iis-v4", | 154 | .name = "samsung-i2s", |
147 | .id = -1, | 155 | .id = 2, |
148 | .num_resources = ARRAY_SIZE(s3c64xx_iisv4_resource), | 156 | .num_resources = ARRAY_SIZE(s3c64xx_iisv4_resource), |
149 | .resource = s3c64xx_iisv4_resource, | 157 | .resource = s3c64xx_iisv4_resource, |
150 | .dev = { | 158 | .dev = { |
151 | .platform_data = &s3c_i2sv4_pdata, | 159 | .platform_data = &i2sv4_pdata, |
152 | }, | 160 | }, |
153 | }; | 161 | }; |
154 | EXPORT_SYMBOL(s3c64xx_device_iisv4); | 162 | EXPORT_SYMBOL(s3c64xx_device_iisv4); |
@@ -288,7 +296,7 @@ static struct s3c_audio_pdata s3c_ac97_pdata; | |||
288 | static u64 s3c64xx_ac97_dmamask = DMA_BIT_MASK(32); | 296 | static u64 s3c64xx_ac97_dmamask = DMA_BIT_MASK(32); |
289 | 297 | ||
290 | struct platform_device s3c64xx_device_ac97 = { | 298 | struct platform_device s3c64xx_device_ac97 = { |
291 | .name = "s3c-ac97", | 299 | .name = "samsung-ac97", |
292 | .id = -1, | 300 | .id = -1, |
293 | .num_resources = ARRAY_SIZE(s3c64xx_ac97_resource), | 301 | .num_resources = ARRAY_SIZE(s3c64xx_ac97_resource), |
294 | .resource = s3c64xx_ac97_resource, | 302 | .resource = s3c64xx_ac97_resource, |
@@ -307,16 +315,3 @@ void __init s3c64xx_ac97_setup_gpio(int num) | |||
307 | else | 315 | else |
308 | s3c_ac97_pdata.cfg_gpio = s3c64xx_ac97_cfg_gpe; | 316 | s3c_ac97_pdata.cfg_gpio = s3c64xx_ac97_cfg_gpe; |
309 | } | 317 | } |
310 | |||
311 | static u64 s3c_device_audio_dmamask = 0xffffffffUL; | ||
312 | |||
313 | struct platform_device s3c_device_pcm = { | ||
314 | .name = "s3c24xx-pcm-audio", | ||
315 | .id = -1, | ||
316 | .dev = { | ||
317 | .dma_mask = &s3c_device_audio_dmamask, | ||
318 | .coherent_dma_mask = 0xffffffffUL | ||
319 | } | ||
320 | }; | ||
321 | EXPORT_SYMBOL(s3c_device_pcm); | ||
322 | |||
diff --git a/arch/arm/mach-s3c64xx/dma.c b/arch/arm/mach-s3c64xx/dma.c index e7d03ab41d80..372ea6855454 100644 --- a/arch/arm/mach-s3c64xx/dma.c +++ b/arch/arm/mach-s3c64xx/dma.c | |||
@@ -740,7 +740,7 @@ static int __init s3c64xx_dma_init(void) | |||
740 | /* Set all DMA configuration to be DMA, not SDMA */ | 740 | /* Set all DMA configuration to be DMA, not SDMA */ |
741 | writel(0xffffff, S3C_SYSREG(0x110)); | 741 | writel(0xffffff, S3C_SYSREG(0x110)); |
742 | 742 | ||
743 | /* Register standard DMA controlers */ | 743 | /* Register standard DMA controllers */ |
744 | s3c64xx_dma_init1(0, DMACH_UART0, IRQ_DMA0, 0x75000000); | 744 | s3c64xx_dma_init1(0, DMACH_UART0, IRQ_DMA0, 0x75000000); |
745 | s3c64xx_dma_init1(8, DMACH_PCM1_TX, IRQ_DMA1, 0x75100000); | 745 | s3c64xx_dma_init1(8, DMACH_PCM1_TX, IRQ_DMA1, 0x75100000); |
746 | 746 | ||
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c index 77488facfe4c..e85192a86fbe 100644 --- a/arch/arm/mach-s3c64xx/mach-smdk6410.c +++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c | |||
@@ -283,7 +283,7 @@ static struct platform_device *smdk6410_devices[] __initdata = { | |||
283 | &s3c_device_fb, | 283 | &s3c_device_fb, |
284 | &s3c_device_ohci, | 284 | &s3c_device_ohci, |
285 | &s3c_device_usb_hsotg, | 285 | &s3c_device_usb_hsotg, |
286 | &s3c_device_pcm, | 286 | &samsung_asoc_dma, |
287 | &s3c64xx_device_iisv4, | 287 | &s3c64xx_device_iisv4, |
288 | &samsung_device_keypad, | 288 | &samsung_device_keypad, |
289 | 289 | ||
diff --git a/arch/arm/mach-s5p6442/dev-audio.c b/arch/arm/mach-s5p6442/dev-audio.c index 3462197ff352..8719dc41fe32 100644 --- a/arch/arm/mach-s5p6442/dev-audio.c +++ b/arch/arm/mach-s5p6442/dev-audio.c | |||
@@ -29,7 +29,7 @@ static int s5p6442_cfg_i2s(struct platform_device *pdev) | |||
29 | base = S5P6442_GPC1(0); | 29 | base = S5P6442_GPC1(0); |
30 | break; | 30 | break; |
31 | 31 | ||
32 | case -1: | 32 | case 0: |
33 | base = S5P6442_GPC0(0); | 33 | base = S5P6442_GPC0(0); |
34 | break; | 34 | break; |
35 | 35 | ||
@@ -42,8 +42,19 @@ static int s5p6442_cfg_i2s(struct platform_device *pdev) | |||
42 | return 0; | 42 | return 0; |
43 | } | 43 | } |
44 | 44 | ||
45 | static struct s3c_audio_pdata s3c_i2s_pdata = { | 45 | static const char *rclksrc_v35[] = { |
46 | [0] = "busclk", | ||
47 | [1] = "i2sclk", | ||
48 | }; | ||
49 | |||
50 | static struct s3c_audio_pdata i2sv35_pdata = { | ||
46 | .cfg_gpio = s5p6442_cfg_i2s, | 51 | .cfg_gpio = s5p6442_cfg_i2s, |
52 | .type = { | ||
53 | .i2s = { | ||
54 | .quirks = QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR, | ||
55 | .src_clk = rclksrc_v35, | ||
56 | }, | ||
57 | }, | ||
47 | }; | 58 | }; |
48 | 59 | ||
49 | static struct resource s5p6442_iis0_resource[] = { | 60 | static struct resource s5p6442_iis0_resource[] = { |
@@ -62,15 +73,34 @@ static struct resource s5p6442_iis0_resource[] = { | |||
62 | .end = DMACH_I2S0_RX, | 73 | .end = DMACH_I2S0_RX, |
63 | .flags = IORESOURCE_DMA, | 74 | .flags = IORESOURCE_DMA, |
64 | }, | 75 | }, |
76 | [3] = { | ||
77 | .start = DMACH_I2S0S_TX, | ||
78 | .end = DMACH_I2S0S_TX, | ||
79 | .flags = IORESOURCE_DMA, | ||
80 | }, | ||
65 | }; | 81 | }; |
66 | 82 | ||
67 | struct platform_device s5p6442_device_iis0 = { | 83 | struct platform_device s5p6442_device_iis0 = { |
68 | .name = "s3c64xx-iis-v4", | 84 | .name = "samsung-i2s", |
69 | .id = -1, | 85 | .id = 0, |
70 | .num_resources = ARRAY_SIZE(s5p6442_iis0_resource), | 86 | .num_resources = ARRAY_SIZE(s5p6442_iis0_resource), |
71 | .resource = s5p6442_iis0_resource, | 87 | .resource = s5p6442_iis0_resource, |
72 | .dev = { | 88 | .dev = { |
73 | .platform_data = &s3c_i2s_pdata, | 89 | .platform_data = &i2sv35_pdata, |
90 | }, | ||
91 | }; | ||
92 | |||
93 | static const char *rclksrc_v3[] = { | ||
94 | [0] = "iis", | ||
95 | [1] = "sclk_audio", | ||
96 | }; | ||
97 | |||
98 | static struct s3c_audio_pdata i2sv3_pdata = { | ||
99 | .cfg_gpio = s5p6442_cfg_i2s, | ||
100 | .type = { | ||
101 | .i2s = { | ||
102 | .src_clk = rclksrc_v3, | ||
103 | }, | ||
74 | }, | 104 | }, |
75 | }; | 105 | }; |
76 | 106 | ||
@@ -93,12 +123,12 @@ static struct resource s5p6442_iis1_resource[] = { | |||
93 | }; | 123 | }; |
94 | 124 | ||
95 | struct platform_device s5p6442_device_iis1 = { | 125 | struct platform_device s5p6442_device_iis1 = { |
96 | .name = "s3c64xx-iis", | 126 | .name = "samsung-i2s", |
97 | .id = 1, | 127 | .id = 1, |
98 | .num_resources = ARRAY_SIZE(s5p6442_iis1_resource), | 128 | .num_resources = ARRAY_SIZE(s5p6442_iis1_resource), |
99 | .resource = s5p6442_iis1_resource, | 129 | .resource = s5p6442_iis1_resource, |
100 | .dev = { | 130 | .dev = { |
101 | .platform_data = &s3c_i2s_pdata, | 131 | .platform_data = &i2sv3_pdata, |
102 | }, | 132 | }, |
103 | }; | 133 | }; |
104 | 134 | ||
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c index e4883dc1c8d7..409c5fc3670d 100644 --- a/arch/arm/mach-s5p64x0/clock-s5p6440.c +++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c | |||
@@ -261,7 +261,7 @@ static struct clk init_clocks_disable[] = { | |||
261 | .enable = s5p64x0_pclk_ctrl, | 261 | .enable = s5p64x0_pclk_ctrl, |
262 | .ctrlbit = (1 << 25), | 262 | .ctrlbit = (1 << 25), |
263 | }, { | 263 | }, { |
264 | .name = "i2s_v40", | 264 | .name = "iis", |
265 | .id = 0, | 265 | .id = 0, |
266 | .parent = &clk_pclk_low.clk, | 266 | .parent = &clk_pclk_low.clk, |
267 | .enable = s5p64x0_pclk_ctrl, | 267 | .enable = s5p64x0_pclk_ctrl, |
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c index 7dbf3c968f53..7fc6abd35914 100644 --- a/arch/arm/mach-s5p64x0/clock-s5p6450.c +++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c | |||
@@ -256,7 +256,7 @@ static struct clk init_clocks_disable[] = { | |||
256 | .ctrlbit = (1 << 22), | 256 | .ctrlbit = (1 << 22), |
257 | }, { | 257 | }, { |
258 | .name = "iis", | 258 | .name = "iis", |
259 | .id = -1, | 259 | .id = 0, |
260 | .parent = &clk_pclk_low.clk, | 260 | .parent = &clk_pclk_low.clk, |
261 | .enable = s5p64x0_pclk_ctrl, | 261 | .enable = s5p64x0_pclk_ctrl, |
262 | .ctrlbit = (1 << 26), | 262 | .ctrlbit = (1 << 26), |
diff --git a/arch/arm/mach-s5p64x0/dev-audio.c b/arch/arm/mach-s5p64x0/dev-audio.c index 396bacc0a39a..14f89e73b8de 100644 --- a/arch/arm/mach-s5p64x0/dev-audio.c +++ b/arch/arm/mach-s5p64x0/dev-audio.c | |||
@@ -19,15 +19,19 @@ | |||
19 | #include <mach/dma.h> | 19 | #include <mach/dma.h> |
20 | #include <mach/irqs.h> | 20 | #include <mach/irqs.h> |
21 | 21 | ||
22 | static int s5p6440_cfg_i2s(struct platform_device *pdev) | 22 | static const char *rclksrc[] = { |
23 | [0] = "iis", | ||
24 | [1] = "sclk_audio2", | ||
25 | }; | ||
26 | |||
27 | static int s5p64x0_cfg_i2s(struct platform_device *pdev) | ||
23 | { | 28 | { |
24 | /* configure GPIO for i2s port */ | 29 | /* configure GPIO for i2s port */ |
25 | switch (pdev->id) { | 30 | switch (pdev->id) { |
26 | case -1: | 31 | case 0: |
27 | s3c_gpio_cfgpin_range(S5P6440_GPR(4), 5, S3C_GPIO_SFN(5)); | 32 | s3c_gpio_cfgpin_range(S5P6440_GPR(4), 5, S3C_GPIO_SFN(5)); |
28 | s3c_gpio_cfgpin_range(S5P6440_GPR(13), 2, S3C_GPIO_SFN(5)); | 33 | s3c_gpio_cfgpin_range(S5P6440_GPR(13), 2, S3C_GPIO_SFN(5)); |
29 | break; | 34 | break; |
30 | |||
31 | default: | 35 | default: |
32 | printk(KERN_ERR "Invalid Device %d\n", pdev->id); | 36 | printk(KERN_ERR "Invalid Device %d\n", pdev->id); |
33 | return -EINVAL; | 37 | return -EINVAL; |
@@ -36,31 +40,14 @@ static int s5p6440_cfg_i2s(struct platform_device *pdev) | |||
36 | return 0; | 40 | return 0; |
37 | } | 41 | } |
38 | 42 | ||
39 | static int s5p6450_cfg_i2s(struct platform_device *pdev) | 43 | static struct s3c_audio_pdata s5p64x0_i2s_pdata = { |
40 | { | 44 | .cfg_gpio = s5p64x0_cfg_i2s, |
41 | /* configure GPIO for i2s port */ | 45 | .type = { |
42 | switch (pdev->id) { | 46 | .i2s = { |
43 | case -1: | 47 | .quirks = QUIRK_PRI_6CHAN, |
44 | s3c_gpio_cfgpin(S5P6450_GPB(4), S3C_GPIO_SFN(5)); | 48 | .src_clk = rclksrc, |
45 | s3c_gpio_cfgpin_range(S5P6450_GPR(4), 5, S3C_GPIO_SFN(5)); | 49 | }, |
46 | s3c_gpio_cfgpin_range(S5P6450_GPR(13), 2, S3C_GPIO_SFN(5)); | 50 | }, |
47 | |||
48 | break; | ||
49 | |||
50 | default: | ||
51 | printk(KERN_ERR "Invalid Device %d\n", pdev->id); | ||
52 | return -EINVAL; | ||
53 | } | ||
54 | |||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | static struct s3c_audio_pdata s5p6440_i2s_pdata = { | ||
59 | .cfg_gpio = s5p6440_cfg_i2s, | ||
60 | }; | ||
61 | |||
62 | static struct s3c_audio_pdata s5p6450_i2s_pdata = { | ||
63 | .cfg_gpio = s5p6450_cfg_i2s, | ||
64 | }; | 51 | }; |
65 | 52 | ||
66 | static struct resource s5p64x0_iis0_resource[] = { | 53 | static struct resource s5p64x0_iis0_resource[] = { |
@@ -82,22 +69,22 @@ static struct resource s5p64x0_iis0_resource[] = { | |||
82 | }; | 69 | }; |
83 | 70 | ||
84 | struct platform_device s5p6440_device_iis = { | 71 | struct platform_device s5p6440_device_iis = { |
85 | .name = "s3c64xx-iis-v4", | 72 | .name = "samsung-i2s", |
86 | .id = -1, | 73 | .id = 0, |
87 | .num_resources = ARRAY_SIZE(s5p64x0_iis0_resource), | 74 | .num_resources = ARRAY_SIZE(s5p64x0_iis0_resource), |
88 | .resource = s5p64x0_iis0_resource, | 75 | .resource = s5p64x0_iis0_resource, |
89 | .dev = { | 76 | .dev = { |
90 | .platform_data = &s5p6440_i2s_pdata, | 77 | .platform_data = &s5p64x0_i2s_pdata, |
91 | }, | 78 | }, |
92 | }; | 79 | }; |
93 | 80 | ||
94 | struct platform_device s5p6450_device_iis0 = { | 81 | struct platform_device s5p6450_device_iis0 = { |
95 | .name = "s3c64xx-iis-v4", | 82 | .name = "samsung-i2s", |
96 | .id = -1, | 83 | .id = 0, |
97 | .num_resources = ARRAY_SIZE(s5p64x0_iis0_resource), | 84 | .num_resources = ARRAY_SIZE(s5p64x0_iis0_resource), |
98 | .resource = s5p64x0_iis0_resource, | 85 | .resource = s5p64x0_iis0_resource, |
99 | .dev = { | 86 | .dev = { |
100 | .platform_data = &s5p6450_i2s_pdata, | 87 | .platform_data = &s5p64x0_i2s_pdata, |
101 | }, | 88 | }, |
102 | }; | 89 | }; |
103 | 90 | ||
diff --git a/arch/arm/mach-s5pc100/dev-audio.c b/arch/arm/mach-s5pc100/dev-audio.c index 564e195ec493..ab2d27172cbc 100644 --- a/arch/arm/mach-s5pc100/dev-audio.c +++ b/arch/arm/mach-s5pc100/dev-audio.c | |||
@@ -23,17 +23,14 @@ static int s5pc100_cfg_i2s(struct platform_device *pdev) | |||
23 | { | 23 | { |
24 | /* configure GPIO for i2s port */ | 24 | /* configure GPIO for i2s port */ |
25 | switch (pdev->id) { | 25 | switch (pdev->id) { |
26 | case 0: /* Dedicated pins */ | ||
27 | break; | ||
26 | case 1: | 28 | case 1: |
27 | s3c_gpio_cfgpin_range(S5PC100_GPC(0), 5, S3C_GPIO_SFN(2)); | 29 | s3c_gpio_cfgpin_range(S5PC100_GPC(0), 5, S3C_GPIO_SFN(2)); |
28 | break; | 30 | break; |
29 | |||
30 | case 2: | 31 | case 2: |
31 | s3c_gpio_cfgpin_range(S5PC100_GPG3(0), 5, S3C_GPIO_SFN(4)); | 32 | s3c_gpio_cfgpin_range(S5PC100_GPG3(0), 5, S3C_GPIO_SFN(4)); |
32 | break; | 33 | break; |
33 | |||
34 | case -1: /* Dedicated pins */ | ||
35 | break; | ||
36 | |||
37 | default: | 34 | default: |
38 | printk(KERN_ERR "Invalid Device %d\n", pdev->id); | 35 | printk(KERN_ERR "Invalid Device %d\n", pdev->id); |
39 | return -EINVAL; | 36 | return -EINVAL; |
@@ -42,8 +39,20 @@ static int s5pc100_cfg_i2s(struct platform_device *pdev) | |||
42 | return 0; | 39 | return 0; |
43 | } | 40 | } |
44 | 41 | ||
45 | static struct s3c_audio_pdata s3c_i2s_pdata = { | 42 | static const char *rclksrc_v5[] = { |
43 | [0] = "iis", | ||
44 | [1] = "i2sclkd2", | ||
45 | }; | ||
46 | |||
47 | static struct s3c_audio_pdata i2sv5_pdata = { | ||
46 | .cfg_gpio = s5pc100_cfg_i2s, | 48 | .cfg_gpio = s5pc100_cfg_i2s, |
49 | .type = { | ||
50 | .i2s = { | ||
51 | .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | ||
52 | | QUIRK_NEED_RSTCLR, | ||
53 | .src_clk = rclksrc_v5, | ||
54 | }, | ||
55 | }, | ||
47 | }; | 56 | }; |
48 | 57 | ||
49 | static struct resource s5pc100_iis0_resource[] = { | 58 | static struct resource s5pc100_iis0_resource[] = { |
@@ -62,15 +71,34 @@ static struct resource s5pc100_iis0_resource[] = { | |||
62 | .end = DMACH_I2S0_RX, | 71 | .end = DMACH_I2S0_RX, |
63 | .flags = IORESOURCE_DMA, | 72 | .flags = IORESOURCE_DMA, |
64 | }, | 73 | }, |
74 | [3] = { | ||
75 | .start = DMACH_I2S0S_TX, | ||
76 | .end = DMACH_I2S0S_TX, | ||
77 | .flags = IORESOURCE_DMA, | ||
78 | }, | ||
65 | }; | 79 | }; |
66 | 80 | ||
67 | struct platform_device s5pc100_device_iis0 = { | 81 | struct platform_device s5pc100_device_iis0 = { |
68 | .name = "s3c64xx-iis-v4", | 82 | .name = "samsung-i2s", |
69 | .id = -1, | 83 | .id = 0, |
70 | .num_resources = ARRAY_SIZE(s5pc100_iis0_resource), | 84 | .num_resources = ARRAY_SIZE(s5pc100_iis0_resource), |
71 | .resource = s5pc100_iis0_resource, | 85 | .resource = s5pc100_iis0_resource, |
72 | .dev = { | 86 | .dev = { |
73 | .platform_data = &s3c_i2s_pdata, | 87 | .platform_data = &i2sv5_pdata, |
88 | }, | ||
89 | }; | ||
90 | |||
91 | static const char *rclksrc_v3[] = { | ||
92 | [0] = "iis", | ||
93 | [1] = "sclk_audio", | ||
94 | }; | ||
95 | |||
96 | static struct s3c_audio_pdata i2sv3_pdata = { | ||
97 | .cfg_gpio = s5pc100_cfg_i2s, | ||
98 | .type = { | ||
99 | .i2s = { | ||
100 | .src_clk = rclksrc_v3, | ||
101 | }, | ||
74 | }, | 102 | }, |
75 | }; | 103 | }; |
76 | 104 | ||
@@ -93,12 +121,12 @@ static struct resource s5pc100_iis1_resource[] = { | |||
93 | }; | 121 | }; |
94 | 122 | ||
95 | struct platform_device s5pc100_device_iis1 = { | 123 | struct platform_device s5pc100_device_iis1 = { |
96 | .name = "s3c64xx-iis", | 124 | .name = "samsung-i2s", |
97 | .id = 1, | 125 | .id = 1, |
98 | .num_resources = ARRAY_SIZE(s5pc100_iis1_resource), | 126 | .num_resources = ARRAY_SIZE(s5pc100_iis1_resource), |
99 | .resource = s5pc100_iis1_resource, | 127 | .resource = s5pc100_iis1_resource, |
100 | .dev = { | 128 | .dev = { |
101 | .platform_data = &s3c_i2s_pdata, | 129 | .platform_data = &i2sv3_pdata, |
102 | }, | 130 | }, |
103 | }; | 131 | }; |
104 | 132 | ||
@@ -121,12 +149,12 @@ static struct resource s5pc100_iis2_resource[] = { | |||
121 | }; | 149 | }; |
122 | 150 | ||
123 | struct platform_device s5pc100_device_iis2 = { | 151 | struct platform_device s5pc100_device_iis2 = { |
124 | .name = "s3c64xx-iis", | 152 | .name = "samsung-i2s", |
125 | .id = 2, | 153 | .id = 2, |
126 | .num_resources = ARRAY_SIZE(s5pc100_iis2_resource), | 154 | .num_resources = ARRAY_SIZE(s5pc100_iis2_resource), |
127 | .resource = s5pc100_iis2_resource, | 155 | .resource = s5pc100_iis2_resource, |
128 | .dev = { | 156 | .dev = { |
129 | .platform_data = &s3c_i2s_pdata, | 157 | .platform_data = &i2sv3_pdata, |
130 | }, | 158 | }, |
131 | }; | 159 | }; |
132 | 160 | ||
@@ -253,7 +281,7 @@ static struct s3c_audio_pdata s3c_ac97_pdata = { | |||
253 | static u64 s5pc100_ac97_dmamask = DMA_BIT_MASK(32); | 281 | static u64 s5pc100_ac97_dmamask = DMA_BIT_MASK(32); |
254 | 282 | ||
255 | struct platform_device s5pc100_device_ac97 = { | 283 | struct platform_device s5pc100_device_ac97 = { |
256 | .name = "s3c-ac97", | 284 | .name = "samsung-ac97", |
257 | .id = -1, | 285 | .id = -1, |
258 | .num_resources = ARRAY_SIZE(s5pc100_ac97_resource), | 286 | .num_resources = ARRAY_SIZE(s5pc100_ac97_resource), |
259 | .resource = s5pc100_ac97_resource, | 287 | .resource = s5pc100_ac97_resource, |
diff --git a/arch/arm/mach-s5pc100/mach-smdkc100.c b/arch/arm/mach-s5pc100/mach-smdkc100.c index 18b405d514d6..dd192a27524d 100644 --- a/arch/arm/mach-s5pc100/mach-smdkc100.c +++ b/arch/arm/mach-s5pc100/mach-smdkc100.c | |||
@@ -96,6 +96,7 @@ static struct s3c2410_uartcfg smdkc100_uartcfgs[] __initdata = { | |||
96 | 96 | ||
97 | /* I2C0 */ | 97 | /* I2C0 */ |
98 | static struct i2c_board_info i2c_devs0[] __initdata = { | 98 | static struct i2c_board_info i2c_devs0[] __initdata = { |
99 | {I2C_BOARD_INFO("wm8580", 0x1b),}, | ||
99 | }; | 100 | }; |
100 | 101 | ||
101 | /* I2C1 */ | 102 | /* I2C1 */ |
@@ -190,6 +191,7 @@ static struct platform_device *smdkc100_devices[] __initdata = { | |||
190 | &s3c_device_ts, | 191 | &s3c_device_ts, |
191 | &s3c_device_wdt, | 192 | &s3c_device_wdt, |
192 | &smdkc100_lcd_powerdev, | 193 | &smdkc100_lcd_powerdev, |
194 | &samsung_asoc_dma, | ||
193 | &s5pc100_device_iis0, | 195 | &s5pc100_device_iis0, |
194 | &samsung_device_keypad, | 196 | &samsung_device_keypad, |
195 | &s5pc100_device_ac97, | 197 | &s5pc100_device_ac97, |
diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index 019c3a69b0e4..b774ff1805db 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c | |||
@@ -467,20 +467,20 @@ static struct clk init_clocks_disable[] = { | |||
467 | .enable = s5pv210_clk_ip3_ctrl, | 467 | .enable = s5pv210_clk_ip3_ctrl, |
468 | .ctrlbit = (1<<21), | 468 | .ctrlbit = (1<<21), |
469 | }, { | 469 | }, { |
470 | .name = "i2s_v50", | 470 | .name = "iis", |
471 | .id = 0, | 471 | .id = 0, |
472 | .parent = &clk_p, | 472 | .parent = &clk_p, |
473 | .enable = s5pv210_clk_ip3_ctrl, | 473 | .enable = s5pv210_clk_ip3_ctrl, |
474 | .ctrlbit = (1<<4), | 474 | .ctrlbit = (1<<4), |
475 | }, { | 475 | }, { |
476 | .name = "i2s_v32", | 476 | .name = "iis", |
477 | .id = 0, | 477 | .id = 1, |
478 | .parent = &clk_p, | 478 | .parent = &clk_p, |
479 | .enable = s5pv210_clk_ip3_ctrl, | 479 | .enable = s5pv210_clk_ip3_ctrl, |
480 | .ctrlbit = (1 << 5), | 480 | .ctrlbit = (1 << 5), |
481 | }, { | 481 | }, { |
482 | .name = "i2s_v32", | 482 | .name = "iis", |
483 | .id = 1, | 483 | .id = 2, |
484 | .parent = &clk_p, | 484 | .parent = &clk_p, |
485 | .enable = s5pv210_clk_ip3_ctrl, | 485 | .enable = s5pv210_clk_ip3_ctrl, |
486 | .ctrlbit = (1 << 6), | 486 | .ctrlbit = (1 << 6), |
diff --git a/arch/arm/mach-s5pv210/dev-audio.c b/arch/arm/mach-s5pv210/dev-audio.c index 1303fcb12b51..8d58f1926241 100644 --- a/arch/arm/mach-s5pv210/dev-audio.c +++ b/arch/arm/mach-s5pv210/dev-audio.c | |||
@@ -19,22 +19,24 @@ | |||
19 | #include <mach/dma.h> | 19 | #include <mach/dma.h> |
20 | #include <mach/irqs.h> | 20 | #include <mach/irqs.h> |
21 | 21 | ||
22 | static const char *rclksrc[] = { | ||
23 | [0] = "busclk", | ||
24 | [1] = "i2sclk", | ||
25 | }; | ||
26 | |||
22 | static int s5pv210_cfg_i2s(struct platform_device *pdev) | 27 | static int s5pv210_cfg_i2s(struct platform_device *pdev) |
23 | { | 28 | { |
24 | /* configure GPIO for i2s port */ | 29 | /* configure GPIO for i2s port */ |
25 | switch (pdev->id) { | 30 | switch (pdev->id) { |
31 | case 0: | ||
32 | s3c_gpio_cfgpin_range(S5PV210_GPI(0), 7, S3C_GPIO_SFN(2)); | ||
33 | break; | ||
26 | case 1: | 34 | case 1: |
27 | s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(2)); | 35 | s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(2)); |
28 | break; | 36 | break; |
29 | |||
30 | case 2: | 37 | case 2: |
31 | s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 5, S3C_GPIO_SFN(4)); | 38 | s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 5, S3C_GPIO_SFN(4)); |
32 | break; | 39 | break; |
33 | |||
34 | case -1: | ||
35 | s3c_gpio_cfgpin_range(S5PV210_GPI(0), 7, S3C_GPIO_SFN(2)); | ||
36 | break; | ||
37 | |||
38 | default: | 40 | default: |
39 | printk(KERN_ERR "Invalid Device %d\n", pdev->id); | 41 | printk(KERN_ERR "Invalid Device %d\n", pdev->id); |
40 | return -EINVAL; | 42 | return -EINVAL; |
@@ -43,8 +45,15 @@ static int s5pv210_cfg_i2s(struct platform_device *pdev) | |||
43 | return 0; | 45 | return 0; |
44 | } | 46 | } |
45 | 47 | ||
46 | static struct s3c_audio_pdata s3c_i2s_pdata = { | 48 | static struct s3c_audio_pdata i2sv5_pdata = { |
47 | .cfg_gpio = s5pv210_cfg_i2s, | 49 | .cfg_gpio = s5pv210_cfg_i2s, |
50 | .type = { | ||
51 | .i2s = { | ||
52 | .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | ||
53 | | QUIRK_NEED_RSTCLR, | ||
54 | .src_clk = rclksrc, | ||
55 | }, | ||
56 | }, | ||
48 | }; | 57 | }; |
49 | 58 | ||
50 | static struct resource s5pv210_iis0_resource[] = { | 59 | static struct resource s5pv210_iis0_resource[] = { |
@@ -63,15 +72,34 @@ static struct resource s5pv210_iis0_resource[] = { | |||
63 | .end = DMACH_I2S0_RX, | 72 | .end = DMACH_I2S0_RX, |
64 | .flags = IORESOURCE_DMA, | 73 | .flags = IORESOURCE_DMA, |
65 | }, | 74 | }, |
75 | [3] = { | ||
76 | .start = DMACH_I2S0S_TX, | ||
77 | .end = DMACH_I2S0S_TX, | ||
78 | .flags = IORESOURCE_DMA, | ||
79 | }, | ||
66 | }; | 80 | }; |
67 | 81 | ||
68 | struct platform_device s5pv210_device_iis0 = { | 82 | struct platform_device s5pv210_device_iis0 = { |
69 | .name = "s3c64xx-iis-v4", | 83 | .name = "samsung-i2s", |
70 | .id = -1, | 84 | .id = 0, |
71 | .num_resources = ARRAY_SIZE(s5pv210_iis0_resource), | 85 | .num_resources = ARRAY_SIZE(s5pv210_iis0_resource), |
72 | .resource = s5pv210_iis0_resource, | 86 | .resource = s5pv210_iis0_resource, |
73 | .dev = { | 87 | .dev = { |
74 | .platform_data = &s3c_i2s_pdata, | 88 | .platform_data = &i2sv5_pdata, |
89 | }, | ||
90 | }; | ||
91 | |||
92 | static const char *rclksrc_v3[] = { | ||
93 | [0] = "iis", | ||
94 | [1] = "audio-bus", | ||
95 | }; | ||
96 | |||
97 | static struct s3c_audio_pdata i2sv3_pdata = { | ||
98 | .cfg_gpio = s5pv210_cfg_i2s, | ||
99 | .type = { | ||
100 | .i2s = { | ||
101 | .src_clk = rclksrc_v3, | ||
102 | }, | ||
75 | }, | 103 | }, |
76 | }; | 104 | }; |
77 | 105 | ||
@@ -94,12 +122,12 @@ static struct resource s5pv210_iis1_resource[] = { | |||
94 | }; | 122 | }; |
95 | 123 | ||
96 | struct platform_device s5pv210_device_iis1 = { | 124 | struct platform_device s5pv210_device_iis1 = { |
97 | .name = "s3c64xx-iis", | 125 | .name = "samsung-i2s", |
98 | .id = 1, | 126 | .id = 1, |
99 | .num_resources = ARRAY_SIZE(s5pv210_iis1_resource), | 127 | .num_resources = ARRAY_SIZE(s5pv210_iis1_resource), |
100 | .resource = s5pv210_iis1_resource, | 128 | .resource = s5pv210_iis1_resource, |
101 | .dev = { | 129 | .dev = { |
102 | .platform_data = &s3c_i2s_pdata, | 130 | .platform_data = &i2sv3_pdata, |
103 | }, | 131 | }, |
104 | }; | 132 | }; |
105 | 133 | ||
@@ -122,12 +150,12 @@ static struct resource s5pv210_iis2_resource[] = { | |||
122 | }; | 150 | }; |
123 | 151 | ||
124 | struct platform_device s5pv210_device_iis2 = { | 152 | struct platform_device s5pv210_device_iis2 = { |
125 | .name = "s3c64xx-iis", | 153 | .name = "samsung-i2s", |
126 | .id = 2, | 154 | .id = 2, |
127 | .num_resources = ARRAY_SIZE(s5pv210_iis2_resource), | 155 | .num_resources = ARRAY_SIZE(s5pv210_iis2_resource), |
128 | .resource = s5pv210_iis2_resource, | 156 | .resource = s5pv210_iis2_resource, |
129 | .dev = { | 157 | .dev = { |
130 | .platform_data = &s3c_i2s_pdata, | 158 | .platform_data = &i2sv3_pdata, |
131 | }, | 159 | }, |
132 | }; | 160 | }; |
133 | 161 | ||
@@ -283,7 +311,7 @@ static struct s3c_audio_pdata s3c_ac97_pdata = { | |||
283 | static u64 s5pv210_ac97_dmamask = DMA_BIT_MASK(32); | 311 | static u64 s5pv210_ac97_dmamask = DMA_BIT_MASK(32); |
284 | 312 | ||
285 | struct platform_device s5pv210_device_ac97 = { | 313 | struct platform_device s5pv210_device_ac97 = { |
286 | .name = "s3c-ac97", | 314 | .name = "samsung-ac97", |
287 | .id = -1, | 315 | .id = -1, |
288 | .num_resources = ARRAY_SIZE(s5pv210_ac97_resource), | 316 | .num_resources = ARRAY_SIZE(s5pv210_ac97_resource), |
289 | .resource = s5pv210_ac97_resource, | 317 | .resource = s5pv210_ac97_resource, |
diff --git a/arch/arm/mach-s5pv310/Kconfig b/arch/arm/mach-s5pv310/Kconfig index 1150b360f38c..d64efe0d4c97 100644 --- a/arch/arm/mach-s5pv310/Kconfig +++ b/arch/arm/mach-s5pv310/Kconfig | |||
@@ -11,6 +11,7 @@ if ARCH_S5PV310 | |||
11 | 11 | ||
12 | config CPU_S5PV310 | 12 | config CPU_S5PV310 |
13 | bool | 13 | bool |
14 | select S3C_PL330_DMA | ||
14 | help | 15 | help |
15 | Enable S5PV310 CPU support | 16 | Enable S5PV310 CPU support |
16 | 17 | ||
diff --git a/arch/arm/mach-s5pv310/Makefile b/arch/arm/mach-s5pv310/Makefile index 84afc64e7c01..61e3cb654269 100644 --- a/arch/arm/mach-s5pv310/Makefile +++ b/arch/arm/mach-s5pv310/Makefile | |||
@@ -13,7 +13,7 @@ obj- := | |||
13 | # Core support for S5PV310 system | 13 | # Core support for S5PV310 system |
14 | 14 | ||
15 | obj-$(CONFIG_CPU_S5PV310) += cpu.o init.o clock.o irq-combiner.o | 15 | obj-$(CONFIG_CPU_S5PV310) += cpu.o init.o clock.o irq-combiner.o |
16 | obj-$(CONFIG_CPU_S5PV310) += setup-i2c0.o time.o gpiolib.o irq-eint.o | 16 | obj-$(CONFIG_CPU_S5PV310) += setup-i2c0.o time.o gpiolib.o irq-eint.o dma.o |
17 | 17 | ||
18 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o | 18 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o |
19 | obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o | 19 | obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o |
@@ -27,6 +27,7 @@ obj-$(CONFIG_MACH_UNIVERSAL_C210) += mach-universal_c210.o | |||
27 | 27 | ||
28 | # device support | 28 | # device support |
29 | 29 | ||
30 | obj-y += dev-audio.o | ||
30 | obj-$(CONFIG_S5PV310_SETUP_I2C1) += setup-i2c1.o | 31 | obj-$(CONFIG_S5PV310_SETUP_I2C1) += setup-i2c1.o |
31 | obj-$(CONFIG_S5PV310_SETUP_I2C2) += setup-i2c2.o | 32 | obj-$(CONFIG_S5PV310_SETUP_I2C2) += setup-i2c2.o |
32 | obj-$(CONFIG_S5PV310_SETUP_I2C3) += setup-i2c3.o | 33 | obj-$(CONFIG_S5PV310_SETUP_I2C3) += setup-i2c3.o |
diff --git a/arch/arm/mach-s5pv310/dev-audio.c b/arch/arm/mach-s5pv310/dev-audio.c new file mode 100644 index 000000000000..a1964242f0fa --- /dev/null +++ b/arch/arm/mach-s5pv310/dev-audio.c | |||
@@ -0,0 +1,364 @@ | |||
1 | /* linux/arch/arm/mach-s5pv310/dev-audio.c | ||
2 | * | ||
3 | * Copyright (c) 2010 Samsung Electronics Co. Ltd | ||
4 | * Jaswinder Singh <jassi.brar@samsung.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/platform_device.h> | ||
12 | #include <linux/dma-mapping.h> | ||
13 | #include <linux/gpio.h> | ||
14 | |||
15 | #include <plat/gpio-cfg.h> | ||
16 | #include <plat/audio.h> | ||
17 | |||
18 | #include <mach/map.h> | ||
19 | #include <mach/dma.h> | ||
20 | #include <mach/irqs.h> | ||
21 | |||
22 | static const char *rclksrc[] = { | ||
23 | [0] = "busclk", | ||
24 | [1] = "i2sclk", | ||
25 | }; | ||
26 | |||
27 | static int s5pv310_cfg_i2s(struct platform_device *pdev) | ||
28 | { | ||
29 | /* configure GPIO for i2s port */ | ||
30 | switch (pdev->id) { | ||
31 | case 0: | ||
32 | s3c_gpio_cfgpin_range(S5PV310_GPZ(0), 7, S3C_GPIO_SFN(2)); | ||
33 | break; | ||
34 | case 1: | ||
35 | s3c_gpio_cfgpin_range(S5PV310_GPC0(0), 5, S3C_GPIO_SFN(2)); | ||
36 | break; | ||
37 | case 2: | ||
38 | s3c_gpio_cfgpin_range(S5PV310_GPC1(0), 5, S3C_GPIO_SFN(4)); | ||
39 | break; | ||
40 | default: | ||
41 | printk(KERN_ERR "Invalid Device %d\n", pdev->id); | ||
42 | return -EINVAL; | ||
43 | } | ||
44 | |||
45 | return 0; | ||
46 | } | ||
47 | |||
48 | static struct s3c_audio_pdata i2sv5_pdata = { | ||
49 | .cfg_gpio = s5pv310_cfg_i2s, | ||
50 | .type = { | ||
51 | .i2s = { | ||
52 | .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | ||
53 | | QUIRK_NEED_RSTCLR, | ||
54 | .src_clk = rclksrc, | ||
55 | }, | ||
56 | }, | ||
57 | }; | ||
58 | |||
59 | static struct resource s5pv310_i2s0_resource[] = { | ||
60 | [0] = { | ||
61 | .start = S5PV310_PA_I2S0, | ||
62 | .end = S5PV310_PA_I2S0 + 0x100 - 1, | ||
63 | .flags = IORESOURCE_MEM, | ||
64 | }, | ||
65 | [1] = { | ||
66 | .start = DMACH_I2S0_TX, | ||
67 | .end = DMACH_I2S0_TX, | ||
68 | .flags = IORESOURCE_DMA, | ||
69 | }, | ||
70 | [2] = { | ||
71 | .start = DMACH_I2S0_RX, | ||
72 | .end = DMACH_I2S0_RX, | ||
73 | .flags = IORESOURCE_DMA, | ||
74 | }, | ||
75 | [3] = { | ||
76 | .start = DMACH_I2S0S_TX, | ||
77 | .end = DMACH_I2S0S_TX, | ||
78 | .flags = IORESOURCE_DMA, | ||
79 | }, | ||
80 | }; | ||
81 | |||
82 | struct platform_device s5pv310_device_i2s0 = { | ||
83 | .name = "samsung-i2s", | ||
84 | .id = 0, | ||
85 | .num_resources = ARRAY_SIZE(s5pv310_i2s0_resource), | ||
86 | .resource = s5pv310_i2s0_resource, | ||
87 | .dev = { | ||
88 | .platform_data = &i2sv5_pdata, | ||
89 | }, | ||
90 | }; | ||
91 | |||
92 | static const char *rclksrc_v3[] = { | ||
93 | [0] = "sclk_i2s", | ||
94 | [1] = "no_such_clock", | ||
95 | }; | ||
96 | |||
97 | static struct s3c_audio_pdata i2sv3_pdata = { | ||
98 | .cfg_gpio = s5pv310_cfg_i2s, | ||
99 | .type = { | ||
100 | .i2s = { | ||
101 | .quirks = QUIRK_NO_MUXPSR, | ||
102 | .src_clk = rclksrc_v3, | ||
103 | }, | ||
104 | }, | ||
105 | }; | ||
106 | |||
107 | static struct resource s5pv310_i2s1_resource[] = { | ||
108 | [0] = { | ||
109 | .start = S5PV310_PA_I2S1, | ||
110 | .end = S5PV310_PA_I2S1 + 0x100 - 1, | ||
111 | .flags = IORESOURCE_MEM, | ||
112 | }, | ||
113 | [1] = { | ||
114 | .start = DMACH_I2S1_TX, | ||
115 | .end = DMACH_I2S1_TX, | ||
116 | .flags = IORESOURCE_DMA, | ||
117 | }, | ||
118 | [2] = { | ||
119 | .start = DMACH_I2S1_RX, | ||
120 | .end = DMACH_I2S1_RX, | ||
121 | .flags = IORESOURCE_DMA, | ||
122 | }, | ||
123 | }; | ||
124 | |||
125 | struct platform_device s5pv310_device_i2s1 = { | ||
126 | .name = "samsung-i2s", | ||
127 | .id = 1, | ||
128 | .num_resources = ARRAY_SIZE(s5pv310_i2s1_resource), | ||
129 | .resource = s5pv310_i2s1_resource, | ||
130 | .dev = { | ||
131 | .platform_data = &i2sv3_pdata, | ||
132 | }, | ||
133 | }; | ||
134 | |||
135 | static struct resource s5pv310_i2s2_resource[] = { | ||
136 | [0] = { | ||
137 | .start = S5PV310_PA_I2S2, | ||
138 | .end = S5PV310_PA_I2S2 + 0x100 - 1, | ||
139 | .flags = IORESOURCE_MEM, | ||
140 | }, | ||
141 | [1] = { | ||
142 | .start = DMACH_I2S2_TX, | ||
143 | .end = DMACH_I2S2_TX, | ||
144 | .flags = IORESOURCE_DMA, | ||
145 | }, | ||
146 | [2] = { | ||
147 | .start = DMACH_I2S2_RX, | ||
148 | .end = DMACH_I2S2_RX, | ||
149 | .flags = IORESOURCE_DMA, | ||
150 | }, | ||
151 | }; | ||
152 | |||
153 | struct platform_device s5pv310_device_i2s2 = { | ||
154 | .name = "samsung-i2s", | ||
155 | .id = 2, | ||
156 | .num_resources = ARRAY_SIZE(s5pv310_i2s2_resource), | ||
157 | .resource = s5pv310_i2s2_resource, | ||
158 | .dev = { | ||
159 | .platform_data = &i2sv3_pdata, | ||
160 | }, | ||
161 | }; | ||
162 | |||
163 | /* PCM Controller platform_devices */ | ||
164 | |||
165 | static int s5pv310_pcm_cfg_gpio(struct platform_device *pdev) | ||
166 | { | ||
167 | switch (pdev->id) { | ||
168 | case 0: | ||
169 | s3c_gpio_cfgpin_range(S5PV310_GPZ(0), 5, S3C_GPIO_SFN(3)); | ||
170 | break; | ||
171 | case 1: | ||
172 | s3c_gpio_cfgpin_range(S5PV310_GPC0(0), 5, S3C_GPIO_SFN(3)); | ||
173 | break; | ||
174 | case 2: | ||
175 | s3c_gpio_cfgpin_range(S5PV310_GPC1(0), 5, S3C_GPIO_SFN(3)); | ||
176 | break; | ||
177 | default: | ||
178 | printk(KERN_DEBUG "Invalid PCM Controller number!"); | ||
179 | return -EINVAL; | ||
180 | } | ||
181 | |||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | static struct s3c_audio_pdata s3c_pcm_pdata = { | ||
186 | .cfg_gpio = s5pv310_pcm_cfg_gpio, | ||
187 | }; | ||
188 | |||
189 | static struct resource s5pv310_pcm0_resource[] = { | ||
190 | [0] = { | ||
191 | .start = S5PV310_PA_PCM0, | ||
192 | .end = S5PV310_PA_PCM0 + 0x100 - 1, | ||
193 | .flags = IORESOURCE_MEM, | ||
194 | }, | ||
195 | [1] = { | ||
196 | .start = DMACH_PCM0_TX, | ||
197 | .end = DMACH_PCM0_TX, | ||
198 | .flags = IORESOURCE_DMA, | ||
199 | }, | ||
200 | [2] = { | ||
201 | .start = DMACH_PCM0_RX, | ||
202 | .end = DMACH_PCM0_RX, | ||
203 | .flags = IORESOURCE_DMA, | ||
204 | }, | ||
205 | }; | ||
206 | |||
207 | struct platform_device s5pv310_device_pcm0 = { | ||
208 | .name = "samsung-pcm", | ||
209 | .id = 0, | ||
210 | .num_resources = ARRAY_SIZE(s5pv310_pcm0_resource), | ||
211 | .resource = s5pv310_pcm0_resource, | ||
212 | .dev = { | ||
213 | .platform_data = &s3c_pcm_pdata, | ||
214 | }, | ||
215 | }; | ||
216 | |||
217 | static struct resource s5pv310_pcm1_resource[] = { | ||
218 | [0] = { | ||
219 | .start = S5PV310_PA_PCM1, | ||
220 | .end = S5PV310_PA_PCM1 + 0x100 - 1, | ||
221 | .flags = IORESOURCE_MEM, | ||
222 | }, | ||
223 | [1] = { | ||
224 | .start = DMACH_PCM1_TX, | ||
225 | .end = DMACH_PCM1_TX, | ||
226 | .flags = IORESOURCE_DMA, | ||
227 | }, | ||
228 | [2] = { | ||
229 | .start = DMACH_PCM1_RX, | ||
230 | .end = DMACH_PCM1_RX, | ||
231 | .flags = IORESOURCE_DMA, | ||
232 | }, | ||
233 | }; | ||
234 | |||
235 | struct platform_device s5pv310_device_pcm1 = { | ||
236 | .name = "samsung-pcm", | ||
237 | .id = 1, | ||
238 | .num_resources = ARRAY_SIZE(s5pv310_pcm1_resource), | ||
239 | .resource = s5pv310_pcm1_resource, | ||
240 | .dev = { | ||
241 | .platform_data = &s3c_pcm_pdata, | ||
242 | }, | ||
243 | }; | ||
244 | |||
245 | static struct resource s5pv310_pcm2_resource[] = { | ||
246 | [0] = { | ||
247 | .start = S5PV310_PA_PCM2, | ||
248 | .end = S5PV310_PA_PCM2 + 0x100 - 1, | ||
249 | .flags = IORESOURCE_MEM, | ||
250 | }, | ||
251 | [1] = { | ||
252 | .start = DMACH_PCM2_TX, | ||
253 | .end = DMACH_PCM2_TX, | ||
254 | .flags = IORESOURCE_DMA, | ||
255 | }, | ||
256 | [2] = { | ||
257 | .start = DMACH_PCM2_RX, | ||
258 | .end = DMACH_PCM2_RX, | ||
259 | .flags = IORESOURCE_DMA, | ||
260 | }, | ||
261 | }; | ||
262 | |||
263 | struct platform_device s5pv310_device_pcm2 = { | ||
264 | .name = "samsung-pcm", | ||
265 | .id = 2, | ||
266 | .num_resources = ARRAY_SIZE(s5pv310_pcm2_resource), | ||
267 | .resource = s5pv310_pcm2_resource, | ||
268 | .dev = { | ||
269 | .platform_data = &s3c_pcm_pdata, | ||
270 | }, | ||
271 | }; | ||
272 | |||
273 | /* AC97 Controller platform devices */ | ||
274 | |||
275 | static int s5pv310_ac97_cfg_gpio(struct platform_device *pdev) | ||
276 | { | ||
277 | return s3c_gpio_cfgpin_range(S5PV310_GPC0(0), 5, S3C_GPIO_SFN(4)); | ||
278 | } | ||
279 | |||
280 | static struct resource s5pv310_ac97_resource[] = { | ||
281 | [0] = { | ||
282 | .start = S5PV310_PA_AC97, | ||
283 | .end = S5PV310_PA_AC97 + 0x100 - 1, | ||
284 | .flags = IORESOURCE_MEM, | ||
285 | }, | ||
286 | [1] = { | ||
287 | .start = DMACH_AC97_PCMOUT, | ||
288 | .end = DMACH_AC97_PCMOUT, | ||
289 | .flags = IORESOURCE_DMA, | ||
290 | }, | ||
291 | [2] = { | ||
292 | .start = DMACH_AC97_PCMIN, | ||
293 | .end = DMACH_AC97_PCMIN, | ||
294 | .flags = IORESOURCE_DMA, | ||
295 | }, | ||
296 | [3] = { | ||
297 | .start = DMACH_AC97_MICIN, | ||
298 | .end = DMACH_AC97_MICIN, | ||
299 | .flags = IORESOURCE_DMA, | ||
300 | }, | ||
301 | [4] = { | ||
302 | .start = IRQ_AC97, | ||
303 | .end = IRQ_AC97, | ||
304 | .flags = IORESOURCE_IRQ, | ||
305 | }, | ||
306 | }; | ||
307 | |||
308 | static struct s3c_audio_pdata s3c_ac97_pdata = { | ||
309 | .cfg_gpio = s5pv310_ac97_cfg_gpio, | ||
310 | }; | ||
311 | |||
312 | static u64 s5pv310_ac97_dmamask = DMA_BIT_MASK(32); | ||
313 | |||
314 | struct platform_device s5pv310_device_ac97 = { | ||
315 | .name = "samsung-ac97", | ||
316 | .id = -1, | ||
317 | .num_resources = ARRAY_SIZE(s5pv310_ac97_resource), | ||
318 | .resource = s5pv310_ac97_resource, | ||
319 | .dev = { | ||
320 | .platform_data = &s3c_ac97_pdata, | ||
321 | .dma_mask = &s5pv310_ac97_dmamask, | ||
322 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
323 | }, | ||
324 | }; | ||
325 | |||
326 | /* S/PDIF Controller platform_device */ | ||
327 | |||
328 | static int s5pv310_spdif_cfg_gpio(struct platform_device *pdev) | ||
329 | { | ||
330 | s3c_gpio_cfgpin_range(S5PV310_GPC1(0), 2, S3C_GPIO_SFN(3)); | ||
331 | |||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | static struct resource s5pv310_spdif_resource[] = { | ||
336 | [0] = { | ||
337 | .start = S5PV310_PA_SPDIF, | ||
338 | .end = S5PV310_PA_SPDIF + 0x100 - 1, | ||
339 | .flags = IORESOURCE_MEM, | ||
340 | }, | ||
341 | [1] = { | ||
342 | .start = DMACH_SPDIF, | ||
343 | .end = DMACH_SPDIF, | ||
344 | .flags = IORESOURCE_DMA, | ||
345 | }, | ||
346 | }; | ||
347 | |||
348 | static struct s3c_audio_pdata samsung_spdif_pdata = { | ||
349 | .cfg_gpio = s5pv310_spdif_cfg_gpio, | ||
350 | }; | ||
351 | |||
352 | static u64 s5pv310_spdif_dmamask = DMA_BIT_MASK(32); | ||
353 | |||
354 | struct platform_device s5pv310_device_spdif = { | ||
355 | .name = "samsung-spdif", | ||
356 | .id = -1, | ||
357 | .num_resources = ARRAY_SIZE(s5pv310_spdif_resource), | ||
358 | .resource = s5pv310_spdif_resource, | ||
359 | .dev = { | ||
360 | .platform_data = &samsung_spdif_pdata, | ||
361 | .dma_mask = &s5pv310_spdif_dmamask, | ||
362 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
363 | }, | ||
364 | }; | ||
diff --git a/arch/arm/mach-s5pv310/dma.c b/arch/arm/mach-s5pv310/dma.c new file mode 100644 index 000000000000..20066c7c9e56 --- /dev/null +++ b/arch/arm/mach-s5pv310/dma.c | |||
@@ -0,0 +1,168 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 Samsung Electronics Co. Ltd. | ||
3 | * Jaswinder Singh <jassi.brar@samsung.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | */ | ||
19 | |||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/dma-mapping.h> | ||
22 | |||
23 | #include <plat/devs.h> | ||
24 | #include <plat/irqs.h> | ||
25 | |||
26 | #include <mach/map.h> | ||
27 | #include <mach/irqs.h> | ||
28 | |||
29 | #include <plat/s3c-pl330-pdata.h> | ||
30 | |||
31 | static u64 dma_dmamask = DMA_BIT_MASK(32); | ||
32 | |||
33 | static struct resource s5pv310_pdma0_resource[] = { | ||
34 | [0] = { | ||
35 | .start = S5PV310_PA_PDMA0, | ||
36 | .end = S5PV310_PA_PDMA0 + SZ_4K, | ||
37 | .flags = IORESOURCE_MEM, | ||
38 | }, | ||
39 | [1] = { | ||
40 | .start = IRQ_PDMA0, | ||
41 | .end = IRQ_PDMA0, | ||
42 | .flags = IORESOURCE_IRQ, | ||
43 | }, | ||
44 | }; | ||
45 | |||
46 | static struct s3c_pl330_platdata s5pv310_pdma0_pdata = { | ||
47 | .peri = { | ||
48 | [0] = DMACH_PCM0_RX, | ||
49 | [1] = DMACH_PCM0_TX, | ||
50 | [2] = DMACH_PCM2_RX, | ||
51 | [3] = DMACH_PCM2_TX, | ||
52 | [4] = DMACH_MSM_REQ0, | ||
53 | [5] = DMACH_MSM_REQ2, | ||
54 | [6] = DMACH_SPI0_RX, | ||
55 | [7] = DMACH_SPI0_TX, | ||
56 | [8] = DMACH_SPI2_RX, | ||
57 | [9] = DMACH_SPI2_TX, | ||
58 | [10] = DMACH_I2S0S_TX, | ||
59 | [11] = DMACH_I2S0_RX, | ||
60 | [12] = DMACH_I2S0_TX, | ||
61 | [13] = DMACH_I2S2_RX, | ||
62 | [14] = DMACH_I2S2_TX, | ||
63 | [15] = DMACH_UART0_RX, | ||
64 | [16] = DMACH_UART0_TX, | ||
65 | [17] = DMACH_UART2_RX, | ||
66 | [18] = DMACH_UART2_TX, | ||
67 | [19] = DMACH_UART4_RX, | ||
68 | [20] = DMACH_UART4_TX, | ||
69 | [21] = DMACH_SLIMBUS0_RX, | ||
70 | [22] = DMACH_SLIMBUS0_TX, | ||
71 | [23] = DMACH_SLIMBUS2_RX, | ||
72 | [24] = DMACH_SLIMBUS2_TX, | ||
73 | [25] = DMACH_SLIMBUS4_RX, | ||
74 | [26] = DMACH_SLIMBUS4_TX, | ||
75 | [27] = DMACH_AC97_MICIN, | ||
76 | [28] = DMACH_AC97_PCMIN, | ||
77 | [29] = DMACH_AC97_PCMOUT, | ||
78 | [30] = DMACH_MAX, | ||
79 | [31] = DMACH_MAX, | ||
80 | }, | ||
81 | }; | ||
82 | |||
83 | static struct platform_device s5pv310_device_pdma0 = { | ||
84 | .name = "s3c-pl330", | ||
85 | .id = 0, | ||
86 | .num_resources = ARRAY_SIZE(s5pv310_pdma0_resource), | ||
87 | .resource = s5pv310_pdma0_resource, | ||
88 | .dev = { | ||
89 | .dma_mask = &dma_dmamask, | ||
90 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
91 | .platform_data = &s5pv310_pdma0_pdata, | ||
92 | }, | ||
93 | }; | ||
94 | |||
95 | static struct resource s5pv310_pdma1_resource[] = { | ||
96 | [0] = { | ||
97 | .start = S5PV310_PA_PDMA1, | ||
98 | .end = S5PV310_PA_PDMA1 + SZ_4K, | ||
99 | .flags = IORESOURCE_MEM, | ||
100 | }, | ||
101 | [1] = { | ||
102 | .start = IRQ_PDMA1, | ||
103 | .end = IRQ_PDMA1, | ||
104 | .flags = IORESOURCE_IRQ, | ||
105 | }, | ||
106 | }; | ||
107 | |||
108 | static struct s3c_pl330_platdata s5pv310_pdma1_pdata = { | ||
109 | .peri = { | ||
110 | [0] = DMACH_PCM0_RX, | ||
111 | [1] = DMACH_PCM0_TX, | ||
112 | [2] = DMACH_PCM1_RX, | ||
113 | [3] = DMACH_PCM1_TX, | ||
114 | [4] = DMACH_MSM_REQ1, | ||
115 | [5] = DMACH_MSM_REQ3, | ||
116 | [6] = DMACH_SPI1_RX, | ||
117 | [7] = DMACH_SPI1_TX, | ||
118 | [8] = DMACH_I2S0S_TX, | ||
119 | [9] = DMACH_I2S0_RX, | ||
120 | [10] = DMACH_I2S0_TX, | ||
121 | [11] = DMACH_I2S1_RX, | ||
122 | [12] = DMACH_I2S1_TX, | ||
123 | [13] = DMACH_UART0_RX, | ||
124 | [14] = DMACH_UART0_TX, | ||
125 | [15] = DMACH_UART1_RX, | ||
126 | [16] = DMACH_UART1_TX, | ||
127 | [17] = DMACH_UART3_RX, | ||
128 | [18] = DMACH_UART3_TX, | ||
129 | [19] = DMACH_SLIMBUS1_RX, | ||
130 | [20] = DMACH_SLIMBUS1_TX, | ||
131 | [21] = DMACH_SLIMBUS3_RX, | ||
132 | [22] = DMACH_SLIMBUS3_TX, | ||
133 | [23] = DMACH_SLIMBUS5_RX, | ||
134 | [24] = DMACH_SLIMBUS5_TX, | ||
135 | [25] = DMACH_SLIMBUS0AUX_RX, | ||
136 | [26] = DMACH_SLIMBUS0AUX_TX, | ||
137 | [27] = DMACH_SPDIF, | ||
138 | [28] = DMACH_MAX, | ||
139 | [29] = DMACH_MAX, | ||
140 | [30] = DMACH_MAX, | ||
141 | [31] = DMACH_MAX, | ||
142 | }, | ||
143 | }; | ||
144 | |||
145 | static struct platform_device s5pv310_device_pdma1 = { | ||
146 | .name = "s3c-pl330", | ||
147 | .id = 1, | ||
148 | .num_resources = ARRAY_SIZE(s5pv310_pdma1_resource), | ||
149 | .resource = s5pv310_pdma1_resource, | ||
150 | .dev = { | ||
151 | .dma_mask = &dma_dmamask, | ||
152 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
153 | .platform_data = &s5pv310_pdma1_pdata, | ||
154 | }, | ||
155 | }; | ||
156 | |||
157 | static struct platform_device *s5pv310_dmacs[] __initdata = { | ||
158 | &s5pv310_device_pdma0, | ||
159 | &s5pv310_device_pdma1, | ||
160 | }; | ||
161 | |||
162 | static int __init s5pv310_dma_init(void) | ||
163 | { | ||
164 | platform_add_devices(s5pv310_dmacs, ARRAY_SIZE(s5pv310_dmacs)); | ||
165 | |||
166 | return 0; | ||
167 | } | ||
168 | arch_initcall(s5pv310_dma_init); | ||
diff --git a/arch/arm/mach-s5pv310/include/mach/dma.h b/arch/arm/mach-s5pv310/include/mach/dma.h new file mode 100644 index 000000000000..81209eb1409b --- /dev/null +++ b/arch/arm/mach-s5pv310/include/mach/dma.h | |||
@@ -0,0 +1,26 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 Samsung Electronics Co. Ltd. | ||
3 | * Jaswinder Singh <jassi.brar@samsung.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | */ | ||
19 | |||
20 | #ifndef __MACH_DMA_H | ||
21 | #define __MACH_DMA_H | ||
22 | |||
23 | /* This platform uses the common S3C DMA API driver for PL330 */ | ||
24 | #include <plat/s3c-dma-pl330.h> | ||
25 | |||
26 | #endif /* __MACH_DMA_H */ | ||
diff --git a/arch/arm/mach-s5pv310/include/mach/irqs.h b/arch/arm/mach-s5pv310/include/mach/irqs.h index 99e7dad8a85a..3c05c58b5392 100644 --- a/arch/arm/mach-s5pv310/include/mach/irqs.h +++ b/arch/arm/mach-s5pv310/include/mach/irqs.h | |||
@@ -54,6 +54,9 @@ | |||
54 | #define COMBINER_GROUP(x) ((x) * MAX_IRQ_IN_COMBINER + IRQ_SPI(64)) | 54 | #define COMBINER_GROUP(x) ((x) * MAX_IRQ_IN_COMBINER + IRQ_SPI(64)) |
55 | #define COMBINER_IRQ(x, y) (COMBINER_GROUP(x) + y) | 55 | #define COMBINER_IRQ(x, y) (COMBINER_GROUP(x) + y) |
56 | 56 | ||
57 | #define IRQ_PDMA0 COMBINER_IRQ(21, 0) | ||
58 | #define IRQ_PDMA1 COMBINER_IRQ(21, 1) | ||
59 | |||
57 | #define IRQ_TIMER0_VIC COMBINER_IRQ(22, 0) | 60 | #define IRQ_TIMER0_VIC COMBINER_IRQ(22, 0) |
58 | #define IRQ_TIMER1_VIC COMBINER_IRQ(22, 1) | 61 | #define IRQ_TIMER1_VIC COMBINER_IRQ(22, 1) |
59 | #define IRQ_TIMER2_VIC COMBINER_IRQ(22, 2) | 62 | #define IRQ_TIMER2_VIC COMBINER_IRQ(22, 2) |
diff --git a/arch/arm/mach-s5pv310/include/mach/map.h b/arch/arm/mach-s5pv310/include/mach/map.h index 7acf4e77e92e..53994467605d 100644 --- a/arch/arm/mach-s5pv310/include/mach/map.h +++ b/arch/arm/mach-s5pv310/include/mach/map.h | |||
@@ -52,6 +52,11 @@ | |||
52 | #define S5PV310_PA_GIC_DIST (0x10501000) | 52 | #define S5PV310_PA_GIC_DIST (0x10501000) |
53 | #define S5PV310_PA_L2CC (0x10502000) | 53 | #define S5PV310_PA_L2CC (0x10502000) |
54 | 54 | ||
55 | /* DMA */ | ||
56 | #define S5PV310_PA_MDMA 0x10810000 | ||
57 | #define S5PV310_PA_PDMA0 0x12680000 | ||
58 | #define S5PV310_PA_PDMA1 0x12690000 | ||
59 | |||
55 | #define S5PV310_PA_GPIO1 (0x11400000) | 60 | #define S5PV310_PA_GPIO1 (0x11400000) |
56 | #define S5PV310_PA_GPIO2 (0x11000000) | 61 | #define S5PV310_PA_GPIO2 (0x11000000) |
57 | #define S5PV310_PA_GPIO3 (0x03860000) | 62 | #define S5PV310_PA_GPIO3 (0x03860000) |
@@ -60,6 +65,22 @@ | |||
60 | 65 | ||
61 | #define S5PV310_PA_SROMC (0x12570000) | 66 | #define S5PV310_PA_SROMC (0x12570000) |
62 | 67 | ||
68 | /* S/PDIF */ | ||
69 | #define S5PV310_PA_SPDIF 0xE1100000 | ||
70 | |||
71 | /* I2S */ | ||
72 | #define S5PV310_PA_I2S0 0x03830000 | ||
73 | #define S5PV310_PA_I2S1 0xE3100000 | ||
74 | #define S5PV310_PA_I2S2 0xE2A00000 | ||
75 | |||
76 | /* PCM */ | ||
77 | #define S5PV310_PA_PCM0 0x03840000 | ||
78 | #define S5PV310_PA_PCM1 0x13980000 | ||
79 | #define S5PV310_PA_PCM2 0x13990000 | ||
80 | |||
81 | /* AC97 */ | ||
82 | #define S5PV310_PA_AC97 0x139A0000 | ||
83 | |||
63 | #define S5PV310_PA_UART (0x13800000) | 84 | #define S5PV310_PA_UART (0x13800000) |
64 | 85 | ||
65 | #define S5P_PA_UART(x) (S5PV310_PA_UART + ((x) * S3C_UART_OFFSET)) | 86 | #define S5P_PA_UART(x) (S5PV310_PA_UART + ((x) * S3C_UART_OFFSET)) |
diff --git a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c index c83fdc80edfd..ab9fc4470d36 100644 --- a/arch/arm/mach-sa1100/pm.c +++ b/arch/arm/mach-sa1100/pm.c | |||
@@ -120,7 +120,7 @@ unsigned long sleep_phys_sp(void *sp) | |||
120 | return virt_to_phys(sp); | 120 | return virt_to_phys(sp); |
121 | } | 121 | } |
122 | 122 | ||
123 | static struct platform_suspend_ops sa11x0_pm_ops = { | 123 | static const struct platform_suspend_ops sa11x0_pm_ops = { |
124 | .enter = sa11x0_pm_enter, | 124 | .enter = sa11x0_pm_enter, |
125 | .valid = suspend_valid_only_mem, | 125 | .valid = suspend_valid_only_mem, |
126 | }; | 126 | }; |
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index cd79d7c1ba0d..3cf0951caa2d 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c | |||
@@ -247,10 +247,7 @@ static struct platform_device smc911x_device = { | |||
247 | */ | 247 | */ |
248 | static int slot_cn7_get_cd(struct platform_device *pdev) | 248 | static int slot_cn7_get_cd(struct platform_device *pdev) |
249 | { | 249 | { |
250 | if (gpio_is_valid(GPIO_PORT41)) | 250 | return !gpio_get_value(GPIO_PORT41); |
251 | return !gpio_get_value(GPIO_PORT41); | ||
252 | else | ||
253 | return -ENXIO; | ||
254 | } | 251 | } |
255 | 252 | ||
256 | /* SH_MMCIF */ | 253 | /* SH_MMCIF */ |
@@ -308,6 +305,7 @@ static struct platform_device sh_mmcif_device = { | |||
308 | static struct sh_mobile_sdhi_info sdhi0_info = { | 305 | static struct sh_mobile_sdhi_info sdhi0_info = { |
309 | .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, | 306 | .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, |
310 | .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, | 307 | .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, |
308 | .tmio_caps = MMC_CAP_SDIO_IRQ, | ||
311 | }; | 309 | }; |
312 | 310 | ||
313 | static struct resource sdhi0_resources[] = { | 311 | static struct resource sdhi0_resources[] = { |
@@ -339,7 +337,7 @@ static struct sh_mobile_sdhi_info sdhi1_info = { | |||
339 | .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX, | 337 | .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX, |
340 | .tmio_ocr_mask = MMC_VDD_165_195, | 338 | .tmio_ocr_mask = MMC_VDD_165_195, |
341 | .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE, | 339 | .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE, |
342 | .tmio_caps = MMC_CAP_NEEDS_POLL, | 340 | .tmio_caps = MMC_CAP_NEEDS_POLL | MMC_CAP_SDIO_IRQ, |
343 | .get_cd = slot_cn7_get_cd, | 341 | .get_cd = slot_cn7_get_cd, |
344 | }; | 342 | }; |
345 | 343 | ||
@@ -711,6 +709,10 @@ static struct platform_device fsi_device = { | |||
711 | }, | 709 | }, |
712 | }; | 710 | }; |
713 | 711 | ||
712 | static struct platform_device fsi_ak4643_device = { | ||
713 | .name = "sh_fsi2_a_ak4643", | ||
714 | }; | ||
715 | |||
714 | static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info = { | 716 | static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info = { |
715 | .clock_source = LCDC_CLK_EXTERNAL, | 717 | .clock_source = LCDC_CLK_EXTERNAL, |
716 | .ch[0] = { | 718 | .ch[0] = { |
@@ -933,6 +935,7 @@ static struct platform_device *ap4evb_devices[] __initdata = { | |||
933 | &sdhi1_device, | 935 | &sdhi1_device, |
934 | &usb1_host_device, | 936 | &usb1_host_device, |
935 | &fsi_device, | 937 | &fsi_device, |
938 | &fsi_ak4643_device, | ||
936 | &sh_mmcif_device, | 939 | &sh_mmcif_device, |
937 | &lcdc1_device, | 940 | &lcdc1_device, |
938 | &lcdc_device, | 941 | &lcdc_device, |
diff --git a/arch/arm/mach-shmobile/board-g4evm.c b/arch/arm/mach-shmobile/board-g4evm.c index c13f01280b7e..dee3e9231fb9 100644 --- a/arch/arm/mach-shmobile/board-g4evm.c +++ b/arch/arm/mach-shmobile/board-g4evm.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/io.h> | 30 | #include <linux/io.h> |
31 | #include <linux/input.h> | 31 | #include <linux/input.h> |
32 | #include <linux/input/sh_keysc.h> | 32 | #include <linux/input/sh_keysc.h> |
33 | #include <linux/mmc/host.h> | ||
33 | #include <linux/mfd/sh_mobile_sdhi.h> | 34 | #include <linux/mfd/sh_mobile_sdhi.h> |
34 | #include <linux/gpio.h> | 35 | #include <linux/gpio.h> |
35 | #include <mach/sh7377.h> | 36 | #include <mach/sh7377.h> |
@@ -196,6 +197,10 @@ static struct platform_device keysc_device = { | |||
196 | }; | 197 | }; |
197 | 198 | ||
198 | /* SDHI */ | 199 | /* SDHI */ |
200 | static struct sh_mobile_sdhi_info sdhi0_info = { | ||
201 | .tmio_caps = MMC_CAP_SDIO_IRQ, | ||
202 | }; | ||
203 | |||
199 | static struct resource sdhi0_resources[] = { | 204 | static struct resource sdhi0_resources[] = { |
200 | [0] = { | 205 | [0] = { |
201 | .name = "SDHI0", | 206 | .name = "SDHI0", |
@@ -214,6 +219,13 @@ static struct platform_device sdhi0_device = { | |||
214 | .num_resources = ARRAY_SIZE(sdhi0_resources), | 219 | .num_resources = ARRAY_SIZE(sdhi0_resources), |
215 | .resource = sdhi0_resources, | 220 | .resource = sdhi0_resources, |
216 | .id = 0, | 221 | .id = 0, |
222 | .dev = { | ||
223 | .platform_data = &sdhi0_info, | ||
224 | }, | ||
225 | }; | ||
226 | |||
227 | static struct sh_mobile_sdhi_info sdhi1_info = { | ||
228 | .tmio_caps = MMC_CAP_NONREMOVABLE | MMC_CAP_SDIO_IRQ, | ||
217 | }; | 229 | }; |
218 | 230 | ||
219 | static struct resource sdhi1_resources[] = { | 231 | static struct resource sdhi1_resources[] = { |
@@ -234,6 +246,9 @@ static struct platform_device sdhi1_device = { | |||
234 | .num_resources = ARRAY_SIZE(sdhi1_resources), | 246 | .num_resources = ARRAY_SIZE(sdhi1_resources), |
235 | .resource = sdhi1_resources, | 247 | .resource = sdhi1_resources, |
236 | .id = 1, | 248 | .id = 1, |
249 | .dev = { | ||
250 | .platform_data = &sdhi1_info, | ||
251 | }, | ||
237 | }; | 252 | }; |
238 | 253 | ||
239 | static struct platform_device *g4evm_devices[] __initdata = { | 254 | static struct platform_device *g4evm_devices[] __initdata = { |
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index 5bcf5c1e1399..7b15d21f0f68 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c | |||
@@ -657,17 +657,14 @@ static struct platform_device fsi_ak4643_device = { | |||
657 | */ | 657 | */ |
658 | static int slot_cn7_get_cd(struct platform_device *pdev) | 658 | static int slot_cn7_get_cd(struct platform_device *pdev) |
659 | { | 659 | { |
660 | if (gpio_is_valid(GPIO_PORT41)) | 660 | return !gpio_get_value(GPIO_PORT41); |
661 | return !gpio_get_value(GPIO_PORT41); | ||
662 | else | ||
663 | return -ENXIO; | ||
664 | } | 661 | } |
665 | 662 | ||
666 | /* SDHI0 */ | 663 | /* SDHI0 */ |
667 | static struct sh_mobile_sdhi_info sdhi0_info = { | 664 | static struct sh_mobile_sdhi_info sdhi0_info = { |
668 | .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, | 665 | .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, |
669 | .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, | 666 | .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, |
670 | .tmio_caps = MMC_CAP_SD_HIGHSPEED, | 667 | .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ, |
671 | }; | 668 | }; |
672 | 669 | ||
673 | static struct resource sdhi0_resources[] = { | 670 | static struct resource sdhi0_resources[] = { |
@@ -700,7 +697,7 @@ static struct sh_mobile_sdhi_info sdhi1_info = { | |||
700 | .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX, | 697 | .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX, |
701 | .tmio_ocr_mask = MMC_VDD_165_195, | 698 | .tmio_ocr_mask = MMC_VDD_165_195, |
702 | .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE, | 699 | .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE, |
703 | .tmio_caps = MMC_CAP_SD_HIGHSPEED | | 700 | .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | |
704 | MMC_CAP_NEEDS_POLL, | 701 | MMC_CAP_NEEDS_POLL, |
705 | .get_cd = slot_cn7_get_cd, | 702 | .get_cd = slot_cn7_get_cd, |
706 | }; | 703 | }; |
@@ -729,13 +726,23 @@ static struct platform_device sdhi1_device = { | |||
729 | }; | 726 | }; |
730 | #endif | 727 | #endif |
731 | 728 | ||
729 | /* | ||
730 | * The card detect pin of the top SD/MMC slot (CN23) is active low and is | ||
731 | * connected to GPIO SCIFB_SCK of SH7372 (GPIO_PORT162). | ||
732 | */ | ||
733 | static int slot_cn23_get_cd(struct platform_device *pdev) | ||
734 | { | ||
735 | return !gpio_get_value(GPIO_PORT162); | ||
736 | } | ||
737 | |||
732 | /* SDHI2 */ | 738 | /* SDHI2 */ |
733 | static struct sh_mobile_sdhi_info sdhi2_info = { | 739 | static struct sh_mobile_sdhi_info sdhi2_info = { |
734 | .dma_slave_tx = SHDMA_SLAVE_SDHI2_TX, | 740 | .dma_slave_tx = SHDMA_SLAVE_SDHI2_TX, |
735 | .dma_slave_rx = SHDMA_SLAVE_SDHI2_RX, | 741 | .dma_slave_rx = SHDMA_SLAVE_SDHI2_RX, |
736 | .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE, | 742 | .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE, |
737 | .tmio_caps = MMC_CAP_SD_HIGHSPEED | | 743 | .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | |
738 | MMC_CAP_NEEDS_POLL, | 744 | MMC_CAP_NEEDS_POLL, |
745 | .get_cd = slot_cn23_get_cd, | ||
739 | }; | 746 | }; |
740 | 747 | ||
741 | static struct resource sdhi2_resources[] = { | 748 | static struct resource sdhi2_resources[] = { |
@@ -953,6 +960,7 @@ static struct tca6416_keys_platform_data mackerel_tca6416_keys_info = { | |||
953 | }; | 960 | }; |
954 | 961 | ||
955 | /* I2C */ | 962 | /* I2C */ |
963 | #define IRQ7 evt2irq(0x02e0) | ||
956 | #define IRQ9 evt2irq(0x0320) | 964 | #define IRQ9 evt2irq(0x0320) |
957 | 965 | ||
958 | static struct i2c_board_info i2c0_devices[] = { | 966 | static struct i2c_board_info i2c0_devices[] = { |
@@ -965,6 +973,11 @@ static struct i2c_board_info i2c0_devices[] = { | |||
965 | .platform_data = &mackerel_tca6416_keys_info, | 973 | .platform_data = &mackerel_tca6416_keys_info, |
966 | .irq = IRQ9, | 974 | .irq = IRQ9, |
967 | }, | 975 | }, |
976 | /* Touchscreen */ | ||
977 | { | ||
978 | I2C_BOARD_INFO("st1232-ts", 0x55), | ||
979 | .irq = IRQ7, | ||
980 | }, | ||
968 | }; | 981 | }; |
969 | 982 | ||
970 | #define IRQ21 evt2irq(0x32a0) | 983 | #define IRQ21 evt2irq(0x32a0) |
@@ -1092,6 +1105,10 @@ static void __init mackerel_init(void) | |||
1092 | gpio_request(GPIO_FN_IRQ9_42, NULL); | 1105 | gpio_request(GPIO_FN_IRQ9_42, NULL); |
1093 | set_irq_type(IRQ9, IRQ_TYPE_LEVEL_HIGH); | 1106 | set_irq_type(IRQ9, IRQ_TYPE_LEVEL_HIGH); |
1094 | 1107 | ||
1108 | /* enable Touchscreen */ | ||
1109 | gpio_request(GPIO_FN_IRQ7_40, NULL); | ||
1110 | set_irq_type(IRQ7, IRQ_TYPE_LEVEL_LOW); | ||
1111 | |||
1095 | /* enable Accelerometer */ | 1112 | /* enable Accelerometer */ |
1096 | gpio_request(GPIO_FN_IRQ21, NULL); | 1113 | gpio_request(GPIO_FN_IRQ21, NULL); |
1097 | set_irq_type(IRQ21, IRQ_TYPE_LEVEL_HIGH); | 1114 | set_irq_type(IRQ21, IRQ_TYPE_LEVEL_HIGH); |
@@ -1127,6 +1144,10 @@ static void __init mackerel_init(void) | |||
1127 | gpio_request(GPIO_FN_SDHID2_1, NULL); | 1144 | gpio_request(GPIO_FN_SDHID2_1, NULL); |
1128 | gpio_request(GPIO_FN_SDHID2_0, NULL); | 1145 | gpio_request(GPIO_FN_SDHID2_0, NULL); |
1129 | 1146 | ||
1147 | /* card detect pin for microSD slot (CN23) */ | ||
1148 | gpio_request(GPIO_PORT162, NULL); | ||
1149 | gpio_direction_input(GPIO_PORT162); | ||
1150 | |||
1130 | /* MMCIF */ | 1151 | /* MMCIF */ |
1131 | gpio_request(GPIO_FN_MMCD0_0, NULL); | 1152 | gpio_request(GPIO_FN_MMCD0_0, NULL); |
1132 | gpio_request(GPIO_FN_MMCD0_1, NULL); | 1153 | gpio_request(GPIO_FN_MMCD0_1, NULL); |
diff --git a/arch/arm/mach-shmobile/include/mach/head-ap4evb.txt b/arch/arm/mach-shmobile/include/mach/head-ap4evb.txt index e3ebfa73956e..efd3687ba190 100644 --- a/arch/arm/mach-shmobile/include/mach/head-ap4evb.txt +++ b/arch/arm/mach-shmobile/include/mach/head-ap4evb.txt | |||
@@ -85,3 +85,10 @@ ED 0xE6150004, 0x80331050 | |||
85 | WAIT 1, 0xFE40009C | 85 | WAIT 1, 0xFE40009C |
86 | 86 | ||
87 | ED 0xE6150354, 0x00000002 | 87 | ED 0xE6150354, 0x00000002 |
88 | |||
89 | LIST "SCIF0 - Serial port for earlyprintk" | ||
90 | EB 0xE6053098, 0x11 | ||
91 | EB 0xE6053098, 0xe1 | ||
92 | EW 0xE6C40000, 0x0000 | ||
93 | EB 0xE6C40004, 0x19 | ||
94 | EW 0xE6C40008, 0x3000 | ||
diff --git a/arch/arm/mach-shmobile/include/mach/head-mackerel.txt b/arch/arm/mach-shmobile/include/mach/head-mackerel.txt index e3ebfa73956e..efd3687ba190 100644 --- a/arch/arm/mach-shmobile/include/mach/head-mackerel.txt +++ b/arch/arm/mach-shmobile/include/mach/head-mackerel.txt | |||
@@ -85,3 +85,10 @@ ED 0xE6150004, 0x80331050 | |||
85 | WAIT 1, 0xFE40009C | 85 | WAIT 1, 0xFE40009C |
86 | 86 | ||
87 | ED 0xE6150354, 0x00000002 | 87 | ED 0xE6150354, 0x00000002 |
88 | |||
89 | LIST "SCIF0 - Serial port for earlyprintk" | ||
90 | EB 0xE6053098, 0x11 | ||
91 | EB 0xE6053098, 0xe1 | ||
92 | EW 0xE6C40000, 0x0000 | ||
93 | EB 0xE6C40004, 0x19 | ||
94 | EW 0xE6C40008, 0x3000 | ||
diff --git a/arch/arm/mach-shmobile/intc-sh7367.c b/arch/arm/mach-shmobile/intc-sh7367.c index 1a20c489b20d..2fe9704d5ea1 100644 --- a/arch/arm/mach-shmobile/intc-sh7367.c +++ b/arch/arm/mach-shmobile/intc-sh7367.c | |||
@@ -189,10 +189,10 @@ static struct intc_mask_reg intca_mask_registers[] __initdata = { | |||
189 | { SCIFB, SCIFA5, SCIFA4, MSIOF1, | 189 | { SCIFB, SCIFA5, SCIFA4, MSIOF1, |
190 | 0, 0, MSIOF2, 0 } }, | 190 | 0, 0, MSIOF2, 0 } }, |
191 | { 0xe694009c, 0xe69400dc, 8, /* IMR7A / IMCR7A */ | 191 | { 0xe694009c, 0xe69400dc, 8, /* IMR7A / IMCR7A */ |
192 | { DISABLED, DISABLED, ENABLED, ENABLED, | 192 | { DISABLED, ENABLED, ENABLED, ENABLED, |
193 | FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } }, | 193 | FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } }, |
194 | { 0xe69400a0, 0xe69400e0, 8, /* IMR8A / IMCR8A */ | 194 | { 0xe69400a0, 0xe69400e0, 8, /* IMR8A / IMCR8A */ |
195 | { DISABLED, DISABLED, ENABLED, ENABLED, | 195 | { DISABLED, ENABLED, ENABLED, ENABLED, |
196 | TTI20, USBDMAC_USHDMI, SPU, SIU } }, | 196 | TTI20, USBDMAC_USHDMI, SPU, SIU } }, |
197 | { 0xe69400a4, 0xe69400e4, 8, /* IMR9A / IMCR9A */ | 197 | { 0xe69400a4, 0xe69400e4, 8, /* IMR9A / IMCR9A */ |
198 | { CMT1_CMT13, CMT1_CMT12, CMT1_CMT11, CMT1_CMT10, | 198 | { CMT1_CMT13, CMT1_CMT12, CMT1_CMT11, CMT1_CMT10, |
@@ -207,7 +207,7 @@ static struct intc_mask_reg intca_mask_registers[] __initdata = { | |||
207 | { 0, 0, TPU0, TPU1, | 207 | { 0, 0, TPU0, TPU1, |
208 | TPU2, TPU3, TPU4, 0 } }, | 208 | TPU2, TPU3, TPU4, 0 } }, |
209 | { 0xe69400b4, 0xe69400f4, 8, /* IMR13A / IMCR13A */ | 209 | { 0xe69400b4, 0xe69400f4, 8, /* IMR13A / IMCR13A */ |
210 | { DISABLED, DISABLED, ENABLED, ENABLED, | 210 | { DISABLED, ENABLED, ENABLED, ENABLED, |
211 | MISTY, CMT3, RWDT1, RWDT0 } }, | 211 | MISTY, CMT3, RWDT1, RWDT0 } }, |
212 | }; | 212 | }; |
213 | 213 | ||
diff --git a/arch/arm/mach-shmobile/intc-sh7372.c b/arch/arm/mach-shmobile/intc-sh7372.c index 30b2f400666a..f78a1ead71a5 100644 --- a/arch/arm/mach-shmobile/intc-sh7372.c +++ b/arch/arm/mach-shmobile/intc-sh7372.c | |||
@@ -230,10 +230,10 @@ static struct intc_mask_reg intca_mask_registers[] __initdata = { | |||
230 | { SCIFB, SCIFA5, SCIFA4, MSIOF1, | 230 | { SCIFB, SCIFA5, SCIFA4, MSIOF1, |
231 | 0, 0, MSIOF2, 0 } }, | 231 | 0, 0, MSIOF2, 0 } }, |
232 | { 0xe694009c, 0xe69400dc, 8, /* IMR7A / IMCR7A */ | 232 | { 0xe694009c, 0xe69400dc, 8, /* IMR7A / IMCR7A */ |
233 | { DISABLED, DISABLED, ENABLED, ENABLED, | 233 | { DISABLED, ENABLED, ENABLED, ENABLED, |
234 | FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } }, | 234 | FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } }, |
235 | { 0xe69400a0, 0xe69400e0, 8, /* IMR8A / IMCR8A */ | 235 | { 0xe69400a0, 0xe69400e0, 8, /* IMR8A / IMCR8A */ |
236 | { 0, DISABLED, ENABLED, ENABLED, | 236 | { 0, ENABLED, ENABLED, ENABLED, |
237 | TTI20, USBHSDMAC0_USHDMI, 0, 0 } }, | 237 | TTI20, USBHSDMAC0_USHDMI, 0, 0 } }, |
238 | { 0xe69400a4, 0xe69400e4, 8, /* IMR9A / IMCR9A */ | 238 | { 0xe69400a4, 0xe69400e4, 8, /* IMR9A / IMCR9A */ |
239 | { CMT1_CMT13, CMT1_CMT12, CMT1_CMT11, CMT1_CMT10, | 239 | { CMT1_CMT13, CMT1_CMT12, CMT1_CMT11, CMT1_CMT10, |
diff --git a/arch/arm/mach-shmobile/intc-sh7377.c b/arch/arm/mach-shmobile/intc-sh7377.c index 2cdeb8ccd821..dd568382cc9f 100644 --- a/arch/arm/mach-shmobile/intc-sh7377.c +++ b/arch/arm/mach-shmobile/intc-sh7377.c | |||
@@ -234,10 +234,10 @@ static struct intc_mask_reg intca_mask_registers[] __initdata = { | |||
234 | { SCIFB, SCIFA5, SCIFA4, MSIOF1, | 234 | { SCIFB, SCIFA5, SCIFA4, MSIOF1, |
235 | 0, 0, MSIOF2, 0 } }, | 235 | 0, 0, MSIOF2, 0 } }, |
236 | { 0xe694009c, 0xe69400dc, 8, /* IMR7A / IMCR7A */ | 236 | { 0xe694009c, 0xe69400dc, 8, /* IMR7A / IMCR7A */ |
237 | { DISABLED, DISABLED, ENABLED, ENABLED, | 237 | { DISABLED, ENABLED, ENABLED, ENABLED, |
238 | FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } }, | 238 | FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } }, |
239 | { 0xe69400a0, 0xe69400e0, 8, /* IMR8A / IMCR8A */ | 239 | { 0xe69400a0, 0xe69400e0, 8, /* IMR8A / IMCR8A */ |
240 | { DISABLED, DISABLED, ENABLED, ENABLED, | 240 | { DISABLED, ENABLED, ENABLED, ENABLED, |
241 | TTI20, USBDMAC_USHDMI, 0, MSUG } }, | 241 | TTI20, USBDMAC_USHDMI, 0, MSUG } }, |
242 | { 0xe69400a4, 0xe69400e4, 8, /* IMR9A / IMCR9A */ | 242 | { 0xe69400a4, 0xe69400e4, 8, /* IMR9A / IMCR9A */ |
243 | { CMT1_CMT13, CMT1_CMT12, CMT1_CMT11, CMT1_CMT10, | 243 | { CMT1_CMT13, CMT1_CMT12, CMT1_CMT11, CMT1_CMT10, |
diff --git a/arch/arm/mach-shmobile/setup-sh7367.c b/arch/arm/mach-shmobile/setup-sh7367.c index 003008c18360..ce28141662da 100644 --- a/arch/arm/mach-shmobile/setup-sh7367.c +++ b/arch/arm/mach-shmobile/setup-sh7367.c | |||
@@ -35,6 +35,8 @@ | |||
35 | static struct plat_sci_port scif0_platform_data = { | 35 | static struct plat_sci_port scif0_platform_data = { |
36 | .mapbase = 0xe6c40000, | 36 | .mapbase = 0xe6c40000, |
37 | .flags = UPF_BOOT_AUTOCONF, | 37 | .flags = UPF_BOOT_AUTOCONF, |
38 | .scscr = SCSCR_RE | SCSCR_TE, | ||
39 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
38 | .type = PORT_SCIF, | 40 | .type = PORT_SCIF, |
39 | .irqs = { evt2irq(0xc00), evt2irq(0xc00), | 41 | .irqs = { evt2irq(0xc00), evt2irq(0xc00), |
40 | evt2irq(0xc00), evt2irq(0xc00) }, | 42 | evt2irq(0xc00), evt2irq(0xc00) }, |
@@ -52,6 +54,8 @@ static struct platform_device scif0_device = { | |||
52 | static struct plat_sci_port scif1_platform_data = { | 54 | static struct plat_sci_port scif1_platform_data = { |
53 | .mapbase = 0xe6c50000, | 55 | .mapbase = 0xe6c50000, |
54 | .flags = UPF_BOOT_AUTOCONF, | 56 | .flags = UPF_BOOT_AUTOCONF, |
57 | .scscr = SCSCR_RE | SCSCR_TE, | ||
58 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
55 | .type = PORT_SCIF, | 59 | .type = PORT_SCIF, |
56 | .irqs = { evt2irq(0xc20), evt2irq(0xc20), | 60 | .irqs = { evt2irq(0xc20), evt2irq(0xc20), |
57 | evt2irq(0xc20), evt2irq(0xc20) }, | 61 | evt2irq(0xc20), evt2irq(0xc20) }, |
@@ -69,6 +73,8 @@ static struct platform_device scif1_device = { | |||
69 | static struct plat_sci_port scif2_platform_data = { | 73 | static struct plat_sci_port scif2_platform_data = { |
70 | .mapbase = 0xe6c60000, | 74 | .mapbase = 0xe6c60000, |
71 | .flags = UPF_BOOT_AUTOCONF, | 75 | .flags = UPF_BOOT_AUTOCONF, |
76 | .scscr = SCSCR_RE | SCSCR_TE, | ||
77 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
72 | .type = PORT_SCIF, | 78 | .type = PORT_SCIF, |
73 | .irqs = { evt2irq(0xc40), evt2irq(0xc40), | 79 | .irqs = { evt2irq(0xc40), evt2irq(0xc40), |
74 | evt2irq(0xc40), evt2irq(0xc40) }, | 80 | evt2irq(0xc40), evt2irq(0xc40) }, |
@@ -86,6 +92,8 @@ static struct platform_device scif2_device = { | |||
86 | static struct plat_sci_port scif3_platform_data = { | 92 | static struct plat_sci_port scif3_platform_data = { |
87 | .mapbase = 0xe6c70000, | 93 | .mapbase = 0xe6c70000, |
88 | .flags = UPF_BOOT_AUTOCONF, | 94 | .flags = UPF_BOOT_AUTOCONF, |
95 | .scscr = SCSCR_RE | SCSCR_TE, | ||
96 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
89 | .type = PORT_SCIF, | 97 | .type = PORT_SCIF, |
90 | .irqs = { evt2irq(0xc60), evt2irq(0xc60), | 98 | .irqs = { evt2irq(0xc60), evt2irq(0xc60), |
91 | evt2irq(0xc60), evt2irq(0xc60) }, | 99 | evt2irq(0xc60), evt2irq(0xc60) }, |
@@ -103,6 +111,8 @@ static struct platform_device scif3_device = { | |||
103 | static struct plat_sci_port scif4_platform_data = { | 111 | static struct plat_sci_port scif4_platform_data = { |
104 | .mapbase = 0xe6c80000, | 112 | .mapbase = 0xe6c80000, |
105 | .flags = UPF_BOOT_AUTOCONF, | 113 | .flags = UPF_BOOT_AUTOCONF, |
114 | .scscr = SCSCR_RE | SCSCR_TE, | ||
115 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
106 | .type = PORT_SCIF, | 116 | .type = PORT_SCIF, |
107 | .irqs = { evt2irq(0xd20), evt2irq(0xd20), | 117 | .irqs = { evt2irq(0xd20), evt2irq(0xd20), |
108 | evt2irq(0xd20), evt2irq(0xd20) }, | 118 | evt2irq(0xd20), evt2irq(0xd20) }, |
@@ -120,6 +130,8 @@ static struct platform_device scif4_device = { | |||
120 | static struct plat_sci_port scif5_platform_data = { | 130 | static struct plat_sci_port scif5_platform_data = { |
121 | .mapbase = 0xe6cb0000, | 131 | .mapbase = 0xe6cb0000, |
122 | .flags = UPF_BOOT_AUTOCONF, | 132 | .flags = UPF_BOOT_AUTOCONF, |
133 | .scscr = SCSCR_RE | SCSCR_TE, | ||
134 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
123 | .type = PORT_SCIF, | 135 | .type = PORT_SCIF, |
124 | .irqs = { evt2irq(0xd40), evt2irq(0xd40), | 136 | .irqs = { evt2irq(0xd40), evt2irq(0xd40), |
125 | evt2irq(0xd40), evt2irq(0xd40) }, | 137 | evt2irq(0xd40), evt2irq(0xd40) }, |
@@ -137,6 +149,8 @@ static struct platform_device scif5_device = { | |||
137 | static struct plat_sci_port scif6_platform_data = { | 149 | static struct plat_sci_port scif6_platform_data = { |
138 | .mapbase = 0xe6c30000, | 150 | .mapbase = 0xe6c30000, |
139 | .flags = UPF_BOOT_AUTOCONF, | 151 | .flags = UPF_BOOT_AUTOCONF, |
152 | .scscr = SCSCR_RE | SCSCR_TE, | ||
153 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
140 | .type = PORT_SCIF, | 154 | .type = PORT_SCIF, |
141 | .irqs = { evt2irq(0xd60), evt2irq(0xd60), | 155 | .irqs = { evt2irq(0xd60), evt2irq(0xd60), |
142 | evt2irq(0xd60), evt2irq(0xd60) }, | 156 | evt2irq(0xd60), evt2irq(0xd60) }, |
diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c index 2e3e11ee7c43..ff0494f3d00c 100644 --- a/arch/arm/mach-shmobile/setup-sh7372.c +++ b/arch/arm/mach-shmobile/setup-sh7372.c | |||
@@ -38,6 +38,8 @@ | |||
38 | static struct plat_sci_port scif0_platform_data = { | 38 | static struct plat_sci_port scif0_platform_data = { |
39 | .mapbase = 0xe6c40000, | 39 | .mapbase = 0xe6c40000, |
40 | .flags = UPF_BOOT_AUTOCONF, | 40 | .flags = UPF_BOOT_AUTOCONF, |
41 | .scscr = SCSCR_RE | SCSCR_TE, | ||
42 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
41 | .type = PORT_SCIFA, | 43 | .type = PORT_SCIFA, |
42 | .irqs = { evt2irq(0x0c00), evt2irq(0x0c00), | 44 | .irqs = { evt2irq(0x0c00), evt2irq(0x0c00), |
43 | evt2irq(0x0c00), evt2irq(0x0c00) }, | 45 | evt2irq(0x0c00), evt2irq(0x0c00) }, |
@@ -55,6 +57,8 @@ static struct platform_device scif0_device = { | |||
55 | static struct plat_sci_port scif1_platform_data = { | 57 | static struct plat_sci_port scif1_platform_data = { |
56 | .mapbase = 0xe6c50000, | 58 | .mapbase = 0xe6c50000, |
57 | .flags = UPF_BOOT_AUTOCONF, | 59 | .flags = UPF_BOOT_AUTOCONF, |
60 | .scscr = SCSCR_RE | SCSCR_TE, | ||
61 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
58 | .type = PORT_SCIFA, | 62 | .type = PORT_SCIFA, |
59 | .irqs = { evt2irq(0x0c20), evt2irq(0x0c20), | 63 | .irqs = { evt2irq(0x0c20), evt2irq(0x0c20), |
60 | evt2irq(0x0c20), evt2irq(0x0c20) }, | 64 | evt2irq(0x0c20), evt2irq(0x0c20) }, |
@@ -72,6 +76,8 @@ static struct platform_device scif1_device = { | |||
72 | static struct plat_sci_port scif2_platform_data = { | 76 | static struct plat_sci_port scif2_platform_data = { |
73 | .mapbase = 0xe6c60000, | 77 | .mapbase = 0xe6c60000, |
74 | .flags = UPF_BOOT_AUTOCONF, | 78 | .flags = UPF_BOOT_AUTOCONF, |
79 | .scscr = SCSCR_RE | SCSCR_TE, | ||
80 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
75 | .type = PORT_SCIFA, | 81 | .type = PORT_SCIFA, |
76 | .irqs = { evt2irq(0x0c40), evt2irq(0x0c40), | 82 | .irqs = { evt2irq(0x0c40), evt2irq(0x0c40), |
77 | evt2irq(0x0c40), evt2irq(0x0c40) }, | 83 | evt2irq(0x0c40), evt2irq(0x0c40) }, |
@@ -89,6 +95,8 @@ static struct platform_device scif2_device = { | |||
89 | static struct plat_sci_port scif3_platform_data = { | 95 | static struct plat_sci_port scif3_platform_data = { |
90 | .mapbase = 0xe6c70000, | 96 | .mapbase = 0xe6c70000, |
91 | .flags = UPF_BOOT_AUTOCONF, | 97 | .flags = UPF_BOOT_AUTOCONF, |
98 | .scscr = SCSCR_RE | SCSCR_TE, | ||
99 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
92 | .type = PORT_SCIFA, | 100 | .type = PORT_SCIFA, |
93 | .irqs = { evt2irq(0x0c60), evt2irq(0x0c60), | 101 | .irqs = { evt2irq(0x0c60), evt2irq(0x0c60), |
94 | evt2irq(0x0c60), evt2irq(0x0c60) }, | 102 | evt2irq(0x0c60), evt2irq(0x0c60) }, |
@@ -106,6 +114,8 @@ static struct platform_device scif3_device = { | |||
106 | static struct plat_sci_port scif4_platform_data = { | 114 | static struct plat_sci_port scif4_platform_data = { |
107 | .mapbase = 0xe6c80000, | 115 | .mapbase = 0xe6c80000, |
108 | .flags = UPF_BOOT_AUTOCONF, | 116 | .flags = UPF_BOOT_AUTOCONF, |
117 | .scscr = SCSCR_RE | SCSCR_TE, | ||
118 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
109 | .type = PORT_SCIFA, | 119 | .type = PORT_SCIFA, |
110 | .irqs = { evt2irq(0x0d20), evt2irq(0x0d20), | 120 | .irqs = { evt2irq(0x0d20), evt2irq(0x0d20), |
111 | evt2irq(0x0d20), evt2irq(0x0d20) }, | 121 | evt2irq(0x0d20), evt2irq(0x0d20) }, |
@@ -123,6 +133,8 @@ static struct platform_device scif4_device = { | |||
123 | static struct plat_sci_port scif5_platform_data = { | 133 | static struct plat_sci_port scif5_platform_data = { |
124 | .mapbase = 0xe6cb0000, | 134 | .mapbase = 0xe6cb0000, |
125 | .flags = UPF_BOOT_AUTOCONF, | 135 | .flags = UPF_BOOT_AUTOCONF, |
136 | .scscr = SCSCR_RE | SCSCR_TE, | ||
137 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
126 | .type = PORT_SCIFA, | 138 | .type = PORT_SCIFA, |
127 | .irqs = { evt2irq(0x0d40), evt2irq(0x0d40), | 139 | .irqs = { evt2irq(0x0d40), evt2irq(0x0d40), |
128 | evt2irq(0x0d40), evt2irq(0x0d40) }, | 140 | evt2irq(0x0d40), evt2irq(0x0d40) }, |
@@ -140,6 +152,8 @@ static struct platform_device scif5_device = { | |||
140 | static struct plat_sci_port scif6_platform_data = { | 152 | static struct plat_sci_port scif6_platform_data = { |
141 | .mapbase = 0xe6c30000, | 153 | .mapbase = 0xe6c30000, |
142 | .flags = UPF_BOOT_AUTOCONF, | 154 | .flags = UPF_BOOT_AUTOCONF, |
155 | .scscr = SCSCR_RE | SCSCR_TE, | ||
156 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
143 | .type = PORT_SCIFB, | 157 | .type = PORT_SCIFB, |
144 | .irqs = { evt2irq(0x0d60), evt2irq(0x0d60), | 158 | .irqs = { evt2irq(0x0d60), evt2irq(0x0d60), |
145 | evt2irq(0x0d60), evt2irq(0x0d60) }, | 159 | evt2irq(0x0d60), evt2irq(0x0d60) }, |
diff --git a/arch/arm/mach-shmobile/setup-sh7377.c b/arch/arm/mach-shmobile/setup-sh7377.c index 575dbd6c2f1d..8099b0b8a934 100644 --- a/arch/arm/mach-shmobile/setup-sh7377.c +++ b/arch/arm/mach-shmobile/setup-sh7377.c | |||
@@ -36,6 +36,8 @@ | |||
36 | static struct plat_sci_port scif0_platform_data = { | 36 | static struct plat_sci_port scif0_platform_data = { |
37 | .mapbase = 0xe6c40000, | 37 | .mapbase = 0xe6c40000, |
38 | .flags = UPF_BOOT_AUTOCONF, | 38 | .flags = UPF_BOOT_AUTOCONF, |
39 | .scscr = SCSCR_RE | SCSCR_TE, | ||
40 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
39 | .type = PORT_SCIF, | 41 | .type = PORT_SCIF, |
40 | .irqs = { evt2irq(0xc00), evt2irq(0xc00), | 42 | .irqs = { evt2irq(0xc00), evt2irq(0xc00), |
41 | evt2irq(0xc00), evt2irq(0xc00) }, | 43 | evt2irq(0xc00), evt2irq(0xc00) }, |
@@ -53,6 +55,8 @@ static struct platform_device scif0_device = { | |||
53 | static struct plat_sci_port scif1_platform_data = { | 55 | static struct plat_sci_port scif1_platform_data = { |
54 | .mapbase = 0xe6c50000, | 56 | .mapbase = 0xe6c50000, |
55 | .flags = UPF_BOOT_AUTOCONF, | 57 | .flags = UPF_BOOT_AUTOCONF, |
58 | .scscr = SCSCR_RE | SCSCR_TE, | ||
59 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
56 | .type = PORT_SCIF, | 60 | .type = PORT_SCIF, |
57 | .irqs = { evt2irq(0xc20), evt2irq(0xc20), | 61 | .irqs = { evt2irq(0xc20), evt2irq(0xc20), |
58 | evt2irq(0xc20), evt2irq(0xc20) }, | 62 | evt2irq(0xc20), evt2irq(0xc20) }, |
@@ -70,6 +74,8 @@ static struct platform_device scif1_device = { | |||
70 | static struct plat_sci_port scif2_platform_data = { | 74 | static struct plat_sci_port scif2_platform_data = { |
71 | .mapbase = 0xe6c60000, | 75 | .mapbase = 0xe6c60000, |
72 | .flags = UPF_BOOT_AUTOCONF, | 76 | .flags = UPF_BOOT_AUTOCONF, |
77 | .scscr = SCSCR_RE | SCSCR_TE, | ||
78 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
73 | .type = PORT_SCIF, | 79 | .type = PORT_SCIF, |
74 | .irqs = { evt2irq(0xc40), evt2irq(0xc40), | 80 | .irqs = { evt2irq(0xc40), evt2irq(0xc40), |
75 | evt2irq(0xc40), evt2irq(0xc40) }, | 81 | evt2irq(0xc40), evt2irq(0xc40) }, |
@@ -87,6 +93,8 @@ static struct platform_device scif2_device = { | |||
87 | static struct plat_sci_port scif3_platform_data = { | 93 | static struct plat_sci_port scif3_platform_data = { |
88 | .mapbase = 0xe6c70000, | 94 | .mapbase = 0xe6c70000, |
89 | .flags = UPF_BOOT_AUTOCONF, | 95 | .flags = UPF_BOOT_AUTOCONF, |
96 | .scscr = SCSCR_RE | SCSCR_TE, | ||
97 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
90 | .type = PORT_SCIF, | 98 | .type = PORT_SCIF, |
91 | .irqs = { evt2irq(0xc60), evt2irq(0xc60), | 99 | .irqs = { evt2irq(0xc60), evt2irq(0xc60), |
92 | evt2irq(0xc60), evt2irq(0xc60) }, | 100 | evt2irq(0xc60), evt2irq(0xc60) }, |
@@ -104,6 +112,8 @@ static struct platform_device scif3_device = { | |||
104 | static struct plat_sci_port scif4_platform_data = { | 112 | static struct plat_sci_port scif4_platform_data = { |
105 | .mapbase = 0xe6c80000, | 113 | .mapbase = 0xe6c80000, |
106 | .flags = UPF_BOOT_AUTOCONF, | 114 | .flags = UPF_BOOT_AUTOCONF, |
115 | .scscr = SCSCR_RE | SCSCR_TE, | ||
116 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
107 | .type = PORT_SCIF, | 117 | .type = PORT_SCIF, |
108 | .irqs = { evt2irq(0xd20), evt2irq(0xd20), | 118 | .irqs = { evt2irq(0xd20), evt2irq(0xd20), |
109 | evt2irq(0xd20), evt2irq(0xd20) }, | 119 | evt2irq(0xd20), evt2irq(0xd20) }, |
@@ -121,6 +131,8 @@ static struct platform_device scif4_device = { | |||
121 | static struct plat_sci_port scif5_platform_data = { | 131 | static struct plat_sci_port scif5_platform_data = { |
122 | .mapbase = 0xe6cb0000, | 132 | .mapbase = 0xe6cb0000, |
123 | .flags = UPF_BOOT_AUTOCONF, | 133 | .flags = UPF_BOOT_AUTOCONF, |
134 | .scscr = SCSCR_RE | SCSCR_TE, | ||
135 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
124 | .type = PORT_SCIF, | 136 | .type = PORT_SCIF, |
125 | .irqs = { evt2irq(0xd40), evt2irq(0xd40), | 137 | .irqs = { evt2irq(0xd40), evt2irq(0xd40), |
126 | evt2irq(0xd40), evt2irq(0xd40) }, | 138 | evt2irq(0xd40), evt2irq(0xd40) }, |
@@ -138,6 +150,8 @@ static struct platform_device scif5_device = { | |||
138 | static struct plat_sci_port scif6_platform_data = { | 150 | static struct plat_sci_port scif6_platform_data = { |
139 | .mapbase = 0xe6cc0000, | 151 | .mapbase = 0xe6cc0000, |
140 | .flags = UPF_BOOT_AUTOCONF, | 152 | .flags = UPF_BOOT_AUTOCONF, |
153 | .scscr = SCSCR_RE | SCSCR_TE, | ||
154 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
141 | .type = PORT_SCIF, | 155 | .type = PORT_SCIF, |
142 | .irqs = { intcs_evt2irq(0x1a80), intcs_evt2irq(0x1a80), | 156 | .irqs = { intcs_evt2irq(0x1a80), intcs_evt2irq(0x1a80), |
143 | intcs_evt2irq(0x1a80), intcs_evt2irq(0x1a80) }, | 157 | intcs_evt2irq(0x1a80), intcs_evt2irq(0x1a80) }, |
@@ -155,6 +169,8 @@ static struct platform_device scif6_device = { | |||
155 | static struct plat_sci_port scif7_platform_data = { | 169 | static struct plat_sci_port scif7_platform_data = { |
156 | .mapbase = 0xe6c30000, | 170 | .mapbase = 0xe6c30000, |
157 | .flags = UPF_BOOT_AUTOCONF, | 171 | .flags = UPF_BOOT_AUTOCONF, |
172 | .scscr = SCSCR_RE | SCSCR_TE, | ||
173 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
158 | .type = PORT_SCIF, | 174 | .type = PORT_SCIF, |
159 | .irqs = { evt2irq(0xd60), evt2irq(0xd60), | 175 | .irqs = { evt2irq(0xd60), evt2irq(0xd60), |
160 | evt2irq(0xd60), evt2irq(0xd60) }, | 176 | evt2irq(0xd60), evt2irq(0xd60) }, |
diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c index f1eff8b37bd6..685c40a2f5e6 100644 --- a/arch/arm/mach-shmobile/setup-sh73a0.c +++ b/arch/arm/mach-shmobile/setup-sh73a0.c | |||
@@ -36,6 +36,8 @@ | |||
36 | static struct plat_sci_port scif0_platform_data = { | 36 | static struct plat_sci_port scif0_platform_data = { |
37 | .mapbase = 0xe6c40000, | 37 | .mapbase = 0xe6c40000, |
38 | .flags = UPF_BOOT_AUTOCONF, | 38 | .flags = UPF_BOOT_AUTOCONF, |
39 | .scscr = SCSCR_RE | SCSCR_TE, | ||
40 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
39 | .type = PORT_SCIFA, | 41 | .type = PORT_SCIFA, |
40 | .irqs = { gic_spi(72), gic_spi(72), | 42 | .irqs = { gic_spi(72), gic_spi(72), |
41 | gic_spi(72), gic_spi(72) }, | 43 | gic_spi(72), gic_spi(72) }, |
@@ -52,6 +54,8 @@ static struct platform_device scif0_device = { | |||
52 | static struct plat_sci_port scif1_platform_data = { | 54 | static struct plat_sci_port scif1_platform_data = { |
53 | .mapbase = 0xe6c50000, | 55 | .mapbase = 0xe6c50000, |
54 | .flags = UPF_BOOT_AUTOCONF, | 56 | .flags = UPF_BOOT_AUTOCONF, |
57 | .scscr = SCSCR_RE | SCSCR_TE, | ||
58 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
55 | .type = PORT_SCIFA, | 59 | .type = PORT_SCIFA, |
56 | .irqs = { gic_spi(73), gic_spi(73), | 60 | .irqs = { gic_spi(73), gic_spi(73), |
57 | gic_spi(73), gic_spi(73) }, | 61 | gic_spi(73), gic_spi(73) }, |
@@ -68,6 +72,8 @@ static struct platform_device scif1_device = { | |||
68 | static struct plat_sci_port scif2_platform_data = { | 72 | static struct plat_sci_port scif2_platform_data = { |
69 | .mapbase = 0xe6c60000, | 73 | .mapbase = 0xe6c60000, |
70 | .flags = UPF_BOOT_AUTOCONF, | 74 | .flags = UPF_BOOT_AUTOCONF, |
75 | .scscr = SCSCR_RE | SCSCR_TE, | ||
76 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
71 | .type = PORT_SCIFA, | 77 | .type = PORT_SCIFA, |
72 | .irqs = { gic_spi(74), gic_spi(74), | 78 | .irqs = { gic_spi(74), gic_spi(74), |
73 | gic_spi(74), gic_spi(74) }, | 79 | gic_spi(74), gic_spi(74) }, |
@@ -84,6 +90,8 @@ static struct platform_device scif2_device = { | |||
84 | static struct plat_sci_port scif3_platform_data = { | 90 | static struct plat_sci_port scif3_platform_data = { |
85 | .mapbase = 0xe6c70000, | 91 | .mapbase = 0xe6c70000, |
86 | .flags = UPF_BOOT_AUTOCONF, | 92 | .flags = UPF_BOOT_AUTOCONF, |
93 | .scscr = SCSCR_RE | SCSCR_TE, | ||
94 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
87 | .type = PORT_SCIFA, | 95 | .type = PORT_SCIFA, |
88 | .irqs = { gic_spi(75), gic_spi(75), | 96 | .irqs = { gic_spi(75), gic_spi(75), |
89 | gic_spi(75), gic_spi(75) }, | 97 | gic_spi(75), gic_spi(75) }, |
@@ -100,6 +108,8 @@ static struct platform_device scif3_device = { | |||
100 | static struct plat_sci_port scif4_platform_data = { | 108 | static struct plat_sci_port scif4_platform_data = { |
101 | .mapbase = 0xe6c80000, | 109 | .mapbase = 0xe6c80000, |
102 | .flags = UPF_BOOT_AUTOCONF, | 110 | .flags = UPF_BOOT_AUTOCONF, |
111 | .scscr = SCSCR_RE | SCSCR_TE, | ||
112 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
103 | .type = PORT_SCIFA, | 113 | .type = PORT_SCIFA, |
104 | .irqs = { gic_spi(78), gic_spi(78), | 114 | .irqs = { gic_spi(78), gic_spi(78), |
105 | gic_spi(78), gic_spi(78) }, | 115 | gic_spi(78), gic_spi(78) }, |
@@ -116,6 +126,8 @@ static struct platform_device scif4_device = { | |||
116 | static struct plat_sci_port scif5_platform_data = { | 126 | static struct plat_sci_port scif5_platform_data = { |
117 | .mapbase = 0xe6cb0000, | 127 | .mapbase = 0xe6cb0000, |
118 | .flags = UPF_BOOT_AUTOCONF, | 128 | .flags = UPF_BOOT_AUTOCONF, |
129 | .scscr = SCSCR_RE | SCSCR_TE, | ||
130 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
119 | .type = PORT_SCIFA, | 131 | .type = PORT_SCIFA, |
120 | .irqs = { gic_spi(79), gic_spi(79), | 132 | .irqs = { gic_spi(79), gic_spi(79), |
121 | gic_spi(79), gic_spi(79) }, | 133 | gic_spi(79), gic_spi(79) }, |
@@ -132,6 +144,8 @@ static struct platform_device scif5_device = { | |||
132 | static struct plat_sci_port scif6_platform_data = { | 144 | static struct plat_sci_port scif6_platform_data = { |
133 | .mapbase = 0xe6cc0000, | 145 | .mapbase = 0xe6cc0000, |
134 | .flags = UPF_BOOT_AUTOCONF, | 146 | .flags = UPF_BOOT_AUTOCONF, |
147 | .scscr = SCSCR_RE | SCSCR_TE, | ||
148 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
135 | .type = PORT_SCIFA, | 149 | .type = PORT_SCIFA, |
136 | .irqs = { gic_spi(156), gic_spi(156), | 150 | .irqs = { gic_spi(156), gic_spi(156), |
137 | gic_spi(156), gic_spi(156) }, | 151 | gic_spi(156), gic_spi(156) }, |
@@ -148,6 +162,8 @@ static struct platform_device scif6_device = { | |||
148 | static struct plat_sci_port scif7_platform_data = { | 162 | static struct plat_sci_port scif7_platform_data = { |
149 | .mapbase = 0xe6cd0000, | 163 | .mapbase = 0xe6cd0000, |
150 | .flags = UPF_BOOT_AUTOCONF, | 164 | .flags = UPF_BOOT_AUTOCONF, |
165 | .scscr = SCSCR_RE | SCSCR_TE, | ||
166 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
151 | .type = PORT_SCIFA, | 167 | .type = PORT_SCIFA, |
152 | .irqs = { gic_spi(143), gic_spi(143), | 168 | .irqs = { gic_spi(143), gic_spi(143), |
153 | gic_spi(143), gic_spi(143) }, | 169 | gic_spi(143), gic_spi(143) }, |
@@ -164,6 +180,8 @@ static struct platform_device scif7_device = { | |||
164 | static struct plat_sci_port scif8_platform_data = { | 180 | static struct plat_sci_port scif8_platform_data = { |
165 | .mapbase = 0xe6c30000, | 181 | .mapbase = 0xe6c30000, |
166 | .flags = UPF_BOOT_AUTOCONF, | 182 | .flags = UPF_BOOT_AUTOCONF, |
183 | .scscr = SCSCR_RE | SCSCR_TE, | ||
184 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
167 | .type = PORT_SCIFB, | 185 | .type = PORT_SCIFB, |
168 | .irqs = { gic_spi(80), gic_spi(80), | 186 | .irqs = { gic_spi(80), gic_spi(80), |
169 | gic_spi(80), gic_spi(80) }, | 187 | gic_spi(80), gic_spi(80) }, |
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c index 3560f8c1e723..5aa2d54ebfaa 100644 --- a/arch/arm/mach-spear3xx/spear300.c +++ b/arch/arm/mach-spear3xx/spear300.c | |||
@@ -371,7 +371,7 @@ struct pmx_driver pmx_driver = { | |||
371 | }; | 371 | }; |
372 | 372 | ||
373 | /* Add spear300 specific devices here */ | 373 | /* Add spear300 specific devices here */ |
374 | /* arm gpio1 device registeration */ | 374 | /* arm gpio1 device registration */ |
375 | static struct pl061_platform_data gpio1_plat_data = { | 375 | static struct pl061_platform_data gpio1_plat_data = { |
376 | .gpio_base = 8, | 376 | .gpio_base = 8, |
377 | .irq_base = SPEAR_GPIO1_INT_BASE, | 377 | .irq_base = SPEAR_GPIO1_INT_BASE, |
@@ -451,7 +451,7 @@ void __init spear300_init(void) | |||
451 | /* call spear3xx family common init function */ | 451 | /* call spear3xx family common init function */ |
452 | spear3xx_init(); | 452 | spear3xx_init(); |
453 | 453 | ||
454 | /* shared irq registeration */ | 454 | /* shared irq registration */ |
455 | shirq_ras1.regs.base = | 455 | shirq_ras1.regs.base = |
456 | ioremap(SPEAR300_TELECOM_BASE, SPEAR300_TELECOM_REG_SIZE); | 456 | ioremap(SPEAR300_TELECOM_BASE, SPEAR300_TELECOM_REG_SIZE); |
457 | if (shirq_ras1.regs.base) { | 457 | if (shirq_ras1.regs.base) { |
diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c index 96a1ab824bac..53b41b52d7ee 100644 --- a/arch/arm/mach-spear3xx/spear310.c +++ b/arch/arm/mach-spear3xx/spear310.c | |||
@@ -266,7 +266,7 @@ void __init spear310_init(void) | |||
266 | /* call spear3xx family common init function */ | 266 | /* call spear3xx family common init function */ |
267 | spear3xx_init(); | 267 | spear3xx_init(); |
268 | 268 | ||
269 | /* shared irq registeration */ | 269 | /* shared irq registration */ |
270 | base = ioremap(SPEAR310_SOC_CONFIG_BASE, SPEAR310_SOC_CONFIG_SIZE); | 270 | base = ioremap(SPEAR310_SOC_CONFIG_BASE, SPEAR310_SOC_CONFIG_SIZE); |
271 | if (base) { | 271 | if (base) { |
272 | /* shirq 1 */ | 272 | /* shirq 1 */ |
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c index 6a1219549369..88b465284c36 100644 --- a/arch/arm/mach-spear3xx/spear320.c +++ b/arch/arm/mach-spear3xx/spear320.c | |||
@@ -519,7 +519,7 @@ void __init spear320_init(void) | |||
519 | /* call spear3xx family common init function */ | 519 | /* call spear3xx family common init function */ |
520 | spear3xx_init(); | 520 | spear3xx_init(); |
521 | 521 | ||
522 | /* shared irq registeration */ | 522 | /* shared irq registration */ |
523 | base = ioremap(SPEAR320_SOC_CONFIG_BASE, SPEAR320_SOC_CONFIG_SIZE); | 523 | base = ioremap(SPEAR320_SOC_CONFIG_BASE, SPEAR320_SOC_CONFIG_SIZE); |
524 | if (base) { | 524 | if (base) { |
525 | /* shirq 1 */ | 525 | /* shirq 1 */ |
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c index e87313aeae20..52f553c8c46d 100644 --- a/arch/arm/mach-spear3xx/spear3xx.c +++ b/arch/arm/mach-spear3xx/spear3xx.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <mach/spear.h> | 22 | #include <mach/spear.h> |
23 | 23 | ||
24 | /* Add spear3xx machines common devices here */ | 24 | /* Add spear3xx machines common devices here */ |
25 | /* gpio device registeration */ | 25 | /* gpio device registration */ |
26 | static struct pl061_platform_data gpio_plat_data = { | 26 | static struct pl061_platform_data gpio_plat_data = { |
27 | .gpio_base = 0, | 27 | .gpio_base = 0, |
28 | .irq_base = SPEAR_GPIO_INT_BASE, | 28 | .irq_base = SPEAR_GPIO_INT_BASE, |
@@ -41,7 +41,7 @@ struct amba_device gpio_device = { | |||
41 | .irq = {IRQ_BASIC_GPIO, NO_IRQ}, | 41 | .irq = {IRQ_BASIC_GPIO, NO_IRQ}, |
42 | }; | 42 | }; |
43 | 43 | ||
44 | /* uart device registeration */ | 44 | /* uart device registration */ |
45 | struct amba_device uart_device = { | 45 | struct amba_device uart_device = { |
46 | .dev = { | 46 | .dev = { |
47 | .init_name = "uart", | 47 | .init_name = "uart", |
@@ -543,6 +543,6 @@ void spear_pmx_init(struct pmx_driver *pmx_driver, uint base, uint size) | |||
543 | 543 | ||
544 | pmx_fail: | 544 | pmx_fail: |
545 | if (ret) | 545 | if (ret) |
546 | printk(KERN_ERR "padmux: registeration failed. err no: %d\n", | 546 | printk(KERN_ERR "padmux: registration failed. err no: %d\n", |
547 | ret); | 547 | ret); |
548 | } | 548 | } |
diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c index baf6bcc3169c..f2fe14e8471d 100644 --- a/arch/arm/mach-spear6xx/spear6xx.c +++ b/arch/arm/mach-spear6xx/spear6xx.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #include <mach/spear.h> | 23 | #include <mach/spear.h> |
24 | 24 | ||
25 | /* Add spear6xx machines common devices here */ | 25 | /* Add spear6xx machines common devices here */ |
26 | /* uart device registeration */ | 26 | /* uart device registration */ |
27 | struct amba_device uart_device[] = { | 27 | struct amba_device uart_device[] = { |
28 | { | 28 | { |
29 | .dev = { | 29 | .dev = { |
@@ -50,7 +50,7 @@ struct amba_device uart_device[] = { | |||
50 | } | 50 | } |
51 | }; | 51 | }; |
52 | 52 | ||
53 | /* gpio device registeration */ | 53 | /* gpio device registration */ |
54 | static struct pl061_platform_data gpio_plat_data[] = { | 54 | static struct pl061_platform_data gpio_plat_data[] = { |
55 | { | 55 | { |
56 | .gpio_base = 0, | 56 | .gpio_base = 0, |
diff --git a/arch/arm/mach-u300/Kconfig b/arch/arm/mach-u300/Kconfig index 801b21e7f677..32a7b0f7e9f7 100644 --- a/arch/arm/mach-u300/Kconfig +++ b/arch/arm/mach-u300/Kconfig | |||
@@ -64,7 +64,7 @@ config MACH_U300_DUAL_RAM | |||
64 | bool "Dual RAM" | 64 | bool "Dual RAM" |
65 | help | 65 | help |
66 | Select this if you want support for Dual RAM phones. | 66 | Select this if you want support for Dual RAM phones. |
67 | This is two RAM memorys on different EMIFs. | 67 | This is two RAM memories on different EMIFs. |
68 | endchoice | 68 | endchoice |
69 | 69 | ||
70 | config U300_DEBUG | 70 | config U300_DEBUG |
diff --git a/arch/arm/mach-u300/include/mach/coh901318.h b/arch/arm/mach-u300/include/mach/coh901318.h index 193da2df732c..6193aaa47794 100644 --- a/arch/arm/mach-u300/include/mach/coh901318.h +++ b/arch/arm/mach-u300/include/mach/coh901318.h | |||
@@ -24,7 +24,7 @@ | |||
24 | * @src_addr: transfer source address | 24 | * @src_addr: transfer source address |
25 | * @dst_addr: transfer destination address | 25 | * @dst_addr: transfer destination address |
26 | * @link_addr: physical address to next lli | 26 | * @link_addr: physical address to next lli |
27 | * @virt_link_addr: virtual addres of next lli (only used by pool_free) | 27 | * @virt_link_addr: virtual address of next lli (only used by pool_free) |
28 | * @phy_this: physical address of current lli (only used by pool_free) | 28 | * @phy_this: physical address of current lli (only used by pool_free) |
29 | */ | 29 | */ |
30 | struct coh901318_lli { | 30 | struct coh901318_lli { |
@@ -90,7 +90,7 @@ struct powersave { | |||
90 | * struct coh901318_platform - platform arch structure | 90 | * struct coh901318_platform - platform arch structure |
91 | * @chans_slave: specifying dma slave channels | 91 | * @chans_slave: specifying dma slave channels |
92 | * @chans_memcpy: specifying dma memcpy channels | 92 | * @chans_memcpy: specifying dma memcpy channels |
93 | * @access_memory_state: requesting DMA memeory access (on / off) | 93 | * @access_memory_state: requesting DMA memory access (on / off) |
94 | * @chan_conf: dma channel configurations | 94 | * @chan_conf: dma channel configurations |
95 | * @max_channels: max number of dma chanenls | 95 | * @max_channels: max number of dma chanenls |
96 | */ | 96 | */ |
diff --git a/arch/arm/mach-ux500/board-mop500-regulators.c b/arch/arm/mach-ux500/board-mop500-regulators.c index 1187f1fc2e53..533967c2d095 100644 --- a/arch/arm/mach-ux500/board-mop500-regulators.c +++ b/arch/arm/mach-ux500/board-mop500-regulators.c | |||
@@ -3,99 +3,94 @@ | |||
3 | * | 3 | * |
4 | * License Terms: GNU General Public License v2 | 4 | * License Terms: GNU General Public License v2 |
5 | * | 5 | * |
6 | * Author: Sundar Iyer <sundar.iyer@stericsson.com> | 6 | * Authors: Sundar Iyer <sundar.iyer@stericsson.com> |
7 | * Bengt Jonsson <bengt.g.jonsson@stericsson.com> | ||
7 | * | 8 | * |
8 | * MOP500 board specific initialization for regulators | 9 | * MOP500 board specific initialization for regulators |
9 | */ | 10 | */ |
10 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
11 | #include <linux/regulator/machine.h> | 12 | #include <linux/regulator/machine.h> |
13 | #include <linux/regulator/ab8500.h> | ||
12 | 14 | ||
13 | /* supplies to the display/camera */ | 15 | /* AB8500 regulators */ |
14 | static struct regulator_init_data ab8500_vaux1_regulator = { | 16 | struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { |
15 | .constraints = { | 17 | /* supplies to the display/camera */ |
16 | .name = "V-DISPLAY", | 18 | [AB8500_LDO_AUX1] = { |
17 | .min_uV = 2500000, | 19 | .constraints = { |
18 | .max_uV = 2900000, | 20 | .name = "V-DISPLAY", |
19 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE| | 21 | .min_uV = 2500000, |
20 | REGULATOR_CHANGE_STATUS, | 22 | .max_uV = 2900000, |
23 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | | ||
24 | REGULATOR_CHANGE_STATUS, | ||
25 | }, | ||
21 | }, | 26 | }, |
22 | }; | 27 | /* supplies to the on-board eMMC */ |
23 | 28 | [AB8500_LDO_AUX2] = { | |
24 | /* supplies to the on-board eMMC */ | 29 | .constraints = { |
25 | static struct regulator_init_data ab8500_vaux2_regulator = { | 30 | .name = "V-eMMC1", |
26 | .constraints = { | 31 | .min_uV = 1100000, |
27 | .name = "V-eMMC1", | 32 | .max_uV = 3300000, |
28 | .min_uV = 1100000, | 33 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | |
29 | .max_uV = 3300000, | 34 | REGULATOR_CHANGE_STATUS, |
30 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE| | 35 | }, |
31 | REGULATOR_CHANGE_STATUS, | ||
32 | }, | 36 | }, |
33 | }; | 37 | /* supply for VAUX3, supplies to SDcard slots */ |
34 | 38 | [AB8500_LDO_AUX3] = { | |
35 | /* supply for VAUX3, supplies to SDcard slots */ | 39 | .constraints = { |
36 | static struct regulator_init_data ab8500_vaux3_regulator = { | 40 | .name = "V-MMC-SD", |
37 | .constraints = { | 41 | .min_uV = 1100000, |
38 | .name = "V-MMC-SD", | 42 | .max_uV = 3300000, |
39 | .min_uV = 1100000, | 43 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | |
40 | .max_uV = 3300000, | 44 | REGULATOR_CHANGE_STATUS, |
41 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE| | 45 | }, |
42 | REGULATOR_CHANGE_STATUS, | ||
43 | }, | 46 | }, |
44 | }; | 47 | /* supply for tvout, gpadc, TVOUT LDO */ |
45 | 48 | [AB8500_LDO_TVOUT] = { | |
46 | /* supply for tvout, gpadc, TVOUT LDO */ | 49 | .constraints = { |
47 | static struct regulator_init_data ab8500_vtvout_init = { | 50 | .name = "V-TVOUT", |
48 | .constraints = { | 51 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, |
49 | .name = "V-TVOUT", | 52 | }, |
50 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
51 | }, | 53 | }, |
52 | }; | 54 | /* supply for ab8500-vaudio, VAUDIO LDO */ |
53 | 55 | [AB8500_LDO_AUDIO] = { | |
54 | /* supply for ab8500-vaudio, VAUDIO LDO */ | 56 | .constraints = { |
55 | static struct regulator_init_data ab8500_vaudio_init = { | 57 | .name = "V-AUD", |
56 | .constraints = { | 58 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, |
57 | .name = "V-AUD", | 59 | }, |
58 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
59 | }, | 60 | }, |
60 | }; | 61 | /* supply for v-anamic1 VAMic1-LDO */ |
61 | 62 | [AB8500_LDO_ANAMIC1] = { | |
62 | /* supply for v-anamic1 VAMic1-LDO */ | 63 | .constraints = { |
63 | static struct regulator_init_data ab8500_vamic1_init = { | 64 | .name = "V-AMIC1", |
64 | .constraints = { | 65 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, |
65 | .name = "V-AMIC1", | 66 | }, |
66 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
67 | }, | 67 | }, |
68 | }; | 68 | /* supply for v-amic2, VAMIC2 LDO, reuse constants for AMIC1 */ |
69 | 69 | [AB8500_LDO_ANAMIC2] = { | |
70 | /* supply for v-amic2, VAMIC2 LDO, reuse constants for AMIC1 */ | 70 | .constraints = { |
71 | static struct regulator_init_data ab8500_vamic2_init = { | 71 | .name = "V-AMIC2", |
72 | .constraints = { | 72 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, |
73 | .name = "V-AMIC2", | 73 | }, |
74 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
75 | }, | 74 | }, |
76 | }; | 75 | /* supply for v-dmic, VDMIC LDO */ |
77 | 76 | [AB8500_LDO_DMIC] = { | |
78 | /* supply for v-dmic, VDMIC LDO */ | 77 | .constraints = { |
79 | static struct regulator_init_data ab8500_vdmic_init = { | 78 | .name = "V-DMIC", |
80 | .constraints = { | 79 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, |
81 | .name = "V-DMIC", | 80 | }, |
82 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
83 | }, | 81 | }, |
84 | }; | 82 | /* supply for v-intcore12, VINTCORE12 LDO */ |
85 | 83 | [AB8500_LDO_INTCORE] = { | |
86 | /* supply for v-intcore12, VINTCORE12 LDO */ | 84 | .constraints = { |
87 | static struct regulator_init_data ab8500_vintcore_init = { | 85 | .name = "V-INTCORE", |
88 | .constraints = { | 86 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, |
89 | .name = "V-INTCORE", | 87 | }, |
90 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
91 | }, | 88 | }, |
92 | }; | 89 | /* supply for U8500 CSI/DSI, VANA LDO */ |
93 | 90 | [AB8500_LDO_ANA] = { | |
94 | /* supply for U8500 CSI/DSI, VANA LDO */ | 91 | .constraints = { |
95 | static struct regulator_init_data ab8500_vana_init = { | 92 | .name = "V-CSI/DSI", |
96 | .constraints = { | 93 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, |
97 | .name = "V-CSI/DSI", | 94 | }, |
98 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
99 | }, | 95 | }, |
100 | }; | 96 | }; |
101 | |||
diff --git a/arch/arm/mach-ux500/board-mop500-regulators.h b/arch/arm/mach-ux500/board-mop500-regulators.h new file mode 100644 index 000000000000..2675fae52537 --- /dev/null +++ b/arch/arm/mach-ux500/board-mop500-regulators.h | |||
@@ -0,0 +1,19 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * License Terms: GNU General Public License v2 | ||
5 | * | ||
6 | * Author: Bengt Jonsson <bengt.g.jonsson@stericsson.com> for ST-Ericsson | ||
7 | * | ||
8 | * MOP500 board specific initialization for regulators | ||
9 | */ | ||
10 | |||
11 | #ifndef __BOARD_MOP500_REGULATORS_H | ||
12 | #define __BOARD_MOP500_REGULATORS_H | ||
13 | |||
14 | #include <linux/regulator/machine.h> | ||
15 | #include <linux/regulator/ab8500.h> | ||
16 | |||
17 | extern struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS]; | ||
18 | |||
19 | #endif | ||
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index a1c9ea1a66df..a393f57ed2a8 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include "devices-db8500.h" | 35 | #include "devices-db8500.h" |
36 | #include "pins-db8500.h" | 36 | #include "pins-db8500.h" |
37 | #include "board-mop500.h" | 37 | #include "board-mop500.h" |
38 | #include "board-mop500-regulators.h" | ||
38 | 39 | ||
39 | static pin_cfg_t mop500_pins[] = { | 40 | static pin_cfg_t mop500_pins[] = { |
40 | /* SSP0 */ | 41 | /* SSP0 */ |
@@ -80,6 +81,8 @@ static pin_cfg_t mop500_pins[] = { | |||
80 | 81 | ||
81 | static struct ab8500_platform_data ab8500_platdata = { | 82 | static struct ab8500_platform_data ab8500_platdata = { |
82 | .irq_base = MOP500_AB8500_IRQ_BASE, | 83 | .irq_base = MOP500_AB8500_IRQ_BASE, |
84 | .regulator = ab8500_regulators, | ||
85 | .num_regulator = ARRAY_SIZE(ab8500_regulators), | ||
83 | }; | 86 | }; |
84 | 87 | ||
85 | static struct resource ab8500_resources[] = { | 88 | static struct resource ab8500_resources[] = { |
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index c29f2839f1d2..2b269c955524 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <asm/smp_plat.h> | 18 | #include <asm/smp_plat.h> |
19 | #include <asm/system.h> | 19 | #include <asm/system.h> |
20 | #include <asm/tlbflush.h> | 20 | #include <asm/tlbflush.h> |
21 | #include <asm/smp_plat.h> | ||
22 | 21 | ||
23 | #include "mm.h" | 22 | #include "mm.h" |
24 | 23 | ||
diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c index 93292a18cf77..709244c66fa3 100644 --- a/arch/arm/mm/pgd.c +++ b/arch/arm/mm/pgd.c | |||
@@ -50,7 +50,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm) | |||
50 | if (!new_pmd) | 50 | if (!new_pmd) |
51 | goto no_pmd; | 51 | goto no_pmd; |
52 | 52 | ||
53 | new_pte = pte_alloc_map(mm, new_pmd, 0); | 53 | new_pte = pte_alloc_map(mm, NULL, new_pmd, 0); |
54 | if (!new_pte) | 54 | if (!new_pte) |
55 | goto no_pte; | 55 | goto no_pte; |
56 | 56 | ||
diff --git a/arch/arm/plat-mxc/include/mach/irqs.h b/arch/arm/plat-mxc/include/mach/irqs.h index 58a49cc83797..ba65c9231a78 100644 --- a/arch/arm/plat-mxc/include/mach/irqs.h +++ b/arch/arm/plat-mxc/include/mach/irqs.h | |||
@@ -70,7 +70,7 @@ extern int imx_irq_set_priority(unsigned char irq, unsigned char prio); | |||
70 | 70 | ||
71 | /* all normal IRQs can be FIQs */ | 71 | /* all normal IRQs can be FIQs */ |
72 | #define FIQ_START 0 | 72 | #define FIQ_START 0 |
73 | /* switch betwean IRQ and FIQ */ | 73 | /* switch between IRQ and FIQ */ |
74 | extern int mxc_set_irq_fiq(unsigned int irq, unsigned int type); | 74 | extern int mxc_set_irq_fiq(unsigned int irq, unsigned int type); |
75 | 75 | ||
76 | #endif /* __ASM_ARCH_MXC_IRQS_H__ */ | 76 | #endif /* __ASM_ARCH_MXC_IRQS_H__ */ |
diff --git a/arch/arm/plat-omap/include/plat/display.h b/arch/arm/plat-omap/include/plat/display.h index c915a661f1f5..537f4e449f50 100644 --- a/arch/arm/plat-omap/include/plat/display.h +++ b/arch/arm/plat-omap/include/plat/display.h | |||
@@ -42,6 +42,10 @@ | |||
42 | #define DISPC_IRQ_SYNC_LOST (1 << 14) | 42 | #define DISPC_IRQ_SYNC_LOST (1 << 14) |
43 | #define DISPC_IRQ_SYNC_LOST_DIGIT (1 << 15) | 43 | #define DISPC_IRQ_SYNC_LOST_DIGIT (1 << 15) |
44 | #define DISPC_IRQ_WAKEUP (1 << 16) | 44 | #define DISPC_IRQ_WAKEUP (1 << 16) |
45 | #define DISPC_IRQ_SYNC_LOST2 (1 << 17) | ||
46 | #define DISPC_IRQ_VSYNC2 (1 << 18) | ||
47 | #define DISPC_IRQ_ACBIAS_COUNT_STAT2 (1 << 21) | ||
48 | #define DISPC_IRQ_FRAMEDONE2 (1 << 22) | ||
45 | 49 | ||
46 | struct omap_dss_device; | 50 | struct omap_dss_device; |
47 | struct omap_overlay_manager; | 51 | struct omap_overlay_manager; |
@@ -64,6 +68,7 @@ enum omap_plane { | |||
64 | enum omap_channel { | 68 | enum omap_channel { |
65 | OMAP_DSS_CHANNEL_LCD = 0, | 69 | OMAP_DSS_CHANNEL_LCD = 0, |
66 | OMAP_DSS_CHANNEL_DIGIT = 1, | 70 | OMAP_DSS_CHANNEL_DIGIT = 1, |
71 | OMAP_DSS_CHANNEL_LCD2 = 2, | ||
67 | }; | 72 | }; |
68 | 73 | ||
69 | enum omap_color_mode { | 74 | enum omap_color_mode { |
@@ -142,6 +147,7 @@ enum omap_dss_display_state { | |||
142 | enum omap_dss_overlay_managers { | 147 | enum omap_dss_overlay_managers { |
143 | OMAP_DSS_OVL_MGR_LCD, | 148 | OMAP_DSS_OVL_MGR_LCD, |
144 | OMAP_DSS_OVL_MGR_TV, | 149 | OMAP_DSS_OVL_MGR_TV, |
150 | OMAP_DSS_OVL_MGR_LCD2, | ||
145 | }; | 151 | }; |
146 | 152 | ||
147 | enum omap_dss_rotation_type { | 153 | enum omap_dss_rotation_type { |
@@ -268,6 +274,7 @@ struct omap_overlay_info { | |||
268 | u16 out_width; /* if 0, out_width == width */ | 274 | u16 out_width; /* if 0, out_width == width */ |
269 | u16 out_height; /* if 0, out_height == height */ | 275 | u16 out_height; /* if 0, out_height == height */ |
270 | u8 global_alpha; | 276 | u8 global_alpha; |
277 | u8 pre_mult_alpha; | ||
271 | }; | 278 | }; |
272 | 279 | ||
273 | struct omap_overlay { | 280 | struct omap_overlay { |
@@ -351,6 +358,8 @@ struct omap_dss_device { | |||
351 | 358 | ||
352 | enum omap_display_type type; | 359 | enum omap_display_type type; |
353 | 360 | ||
361 | enum omap_channel channel; | ||
362 | |||
354 | union { | 363 | union { |
355 | struct { | 364 | struct { |
356 | u8 data_lines; | 365 | u8 data_lines; |
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index 6864a997f2ca..1eee85a8abb3 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h | |||
@@ -351,7 +351,7 @@ struct omap_hwmod_omap2_prcm { | |||
351 | /** | 351 | /** |
352 | * struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data | 352 | * struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data |
353 | * @clkctrl_reg: PRCM address of the clock control register | 353 | * @clkctrl_reg: PRCM address of the clock control register |
354 | * @rstctrl_reg: adress of the XXX_RSTCTRL register located in the PRM | 354 | * @rstctrl_reg: address of the XXX_RSTCTRL register located in the PRM |
355 | * @submodule_wkdep_bit: bit shift of the WKDEP range | 355 | * @submodule_wkdep_bit: bit shift of the WKDEP range |
356 | */ | 356 | */ |
357 | struct omap_hwmod_omap4_prcm { | 357 | struct omap_hwmod_omap4_prcm { |
diff --git a/arch/arm/plat-omap/include/plat/panel-generic-dpi.h b/arch/arm/plat-omap/include/plat/panel-generic-dpi.h new file mode 100644 index 000000000000..790619734bcd --- /dev/null +++ b/arch/arm/plat-omap/include/plat/panel-generic-dpi.h | |||
@@ -0,0 +1,37 @@ | |||
1 | /* | ||
2 | * Header for generic DPI panel driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Canonical Ltd. | ||
5 | * Author: Bryan Wu <bryan.wu@canonical.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License version 2 as published by | ||
9 | * the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along with | ||
17 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | #ifndef __ARCH_ARM_PLAT_OMAP_PANEL_GENERIC_DPI_H | ||
21 | #define __ARCH_ARM_PLAT_OMAP_PANEL_GENERIC_DPI_H | ||
22 | |||
23 | #include "display.h" | ||
24 | |||
25 | /** | ||
26 | * struct panel_generic_dpi_data - panel driver configuration data | ||
27 | * @name: panel name | ||
28 | * @platform_enable: platform specific panel enable function | ||
29 | * @platform_disable: platform specific panel disable function | ||
30 | */ | ||
31 | struct panel_generic_dpi_data { | ||
32 | const char *name; | ||
33 | int (*platform_enable)(struct omap_dss_device *dssdev); | ||
34 | void (*platform_disable)(struct omap_dss_device *dssdev); | ||
35 | }; | ||
36 | |||
37 | #endif /* __ARCH_ARM_PLAT_OMAP_PANEL_GENERIC_DPI_H */ | ||
diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c index 2f91057a0c02..8a42bc48dbf0 100644 --- a/arch/arm/plat-s3c24xx/devs.c +++ b/arch/arm/plat-s3c24xx/devs.c | |||
@@ -259,21 +259,6 @@ struct platform_device s3c_device_iis = { | |||
259 | 259 | ||
260 | EXPORT_SYMBOL(s3c_device_iis); | 260 | EXPORT_SYMBOL(s3c_device_iis); |
261 | 261 | ||
262 | /* ASoC PCM DMA */ | ||
263 | |||
264 | static u64 s3c_device_audio_dmamask = 0xffffffffUL; | ||
265 | |||
266 | struct platform_device s3c_device_pcm = { | ||
267 | .name = "s3c24xx-pcm-audio", | ||
268 | .id = -1, | ||
269 | .dev = { | ||
270 | .dma_mask = &s3c_device_audio_dmamask, | ||
271 | .coherent_dma_mask = 0xffffffffUL | ||
272 | } | ||
273 | }; | ||
274 | |||
275 | EXPORT_SYMBOL(s3c_device_pcm); | ||
276 | |||
277 | /* RTC */ | 262 | /* RTC */ |
278 | 263 | ||
279 | static struct resource s3c_rtc_resource[] = { | 264 | static struct resource s3c_rtc_resource[] = { |
@@ -496,8 +481,10 @@ static struct resource s3c_ac97_resource[] = { | |||
496 | }, | 481 | }, |
497 | }; | 482 | }; |
498 | 483 | ||
484 | static u64 s3c_device_audio_dmamask = 0xffffffffUL; | ||
485 | |||
499 | struct platform_device s3c_device_ac97 = { | 486 | struct platform_device s3c_device_ac97 = { |
500 | .name = "s3c-ac97", | 487 | .name = "samsung-ac97", |
501 | .id = -1, | 488 | .id = -1, |
502 | .num_resources = ARRAY_SIZE(s3c_ac97_resource), | 489 | .num_resources = ARRAY_SIZE(s3c_ac97_resource), |
503 | .resource = s3c_ac97_resource, | 490 | .resource = s3c_ac97_resource, |
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index afcce474af8e..19d8a16c3066 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile | |||
@@ -17,6 +17,7 @@ obj-y += clock.o | |||
17 | obj-y += pwm-clock.o | 17 | obj-y += pwm-clock.o |
18 | obj-y += gpio.o | 18 | obj-y += gpio.o |
19 | obj-y += gpio-config.o | 19 | obj-y += gpio-config.o |
20 | obj-y += dev-asocdma.o | ||
20 | 21 | ||
21 | obj-$(CONFIG_SAMSUNG_GPIOLIB_4BIT) += gpiolib.o | 22 | obj-$(CONFIG_SAMSUNG_GPIOLIB_4BIT) += gpiolib.o |
22 | obj-$(CONFIG_SAMSUNG_CLKSRC) += clock-clksrc.o | 23 | obj-$(CONFIG_SAMSUNG_CLKSRC) += clock-clksrc.o |
diff --git a/arch/arm/plat-samsung/dev-asocdma.c b/arch/arm/plat-samsung/dev-asocdma.c new file mode 100644 index 000000000000..a068c4f42d56 --- /dev/null +++ b/arch/arm/plat-samsung/dev-asocdma.c | |||
@@ -0,0 +1,25 @@ | |||
1 | /* linux/arch/arm/plat-samsung/dev-asocdma.c | ||
2 | * | ||
3 | * Copyright (c) 2010 Samsung Electronics Co. Ltd | ||
4 | * Jaswinder Singh <jassi.brar@samsung.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/platform_device.h> | ||
12 | #include <linux/dma-mapping.h> | ||
13 | #include <plat/devs.h> | ||
14 | |||
15 | static u64 audio_dmamask = DMA_BIT_MASK(32); | ||
16 | |||
17 | struct platform_device samsung_asoc_dma = { | ||
18 | .name = "samsung-audio", | ||
19 | .id = -1, | ||
20 | .dev = { | ||
21 | .dma_mask = &audio_dmamask, | ||
22 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
23 | } | ||
24 | }; | ||
25 | EXPORT_SYMBOL(samsung_asoc_dma); | ||
diff --git a/arch/arm/plat-samsung/include/plat/audio.h b/arch/arm/plat-samsung/include/plat/audio.h index 7712ff6336f4..a0826ed2f9fe 100644 --- a/arch/arm/plat-samsung/include/plat/audio.h +++ b/arch/arm/plat-samsung/include/plat/audio.h | |||
@@ -25,10 +25,34 @@ extern void s3c64xx_ac97_setup_gpio(int); | |||
25 | #define S5PC100_SPDIF_GPG3 1 | 25 | #define S5PC100_SPDIF_GPG3 1 |
26 | extern void s5pc100_spdif_setup_gpio(int); | 26 | extern void s5pc100_spdif_setup_gpio(int); |
27 | 27 | ||
28 | struct samsung_i2s { | ||
29 | /* If the Primary DAI has 5.1 Channels */ | ||
30 | #define QUIRK_PRI_6CHAN (1 << 0) | ||
31 | /* If the I2S block has a Stereo Overlay Channel */ | ||
32 | #define QUIRK_SEC_DAI (1 << 1) | ||
33 | /* | ||
34 | * If the I2S block has no internal prescalar or MUX (I2SMOD[10] bit) | ||
35 | * The Machine driver must provide suitably set clock to the I2S block. | ||
36 | */ | ||
37 | #define QUIRK_NO_MUXPSR (1 << 2) | ||
38 | #define QUIRK_NEED_RSTCLR (1 << 3) | ||
39 | /* Quirks of the I2S controller */ | ||
40 | u32 quirks; | ||
41 | |||
42 | /* | ||
43 | * Array of clock names that can be used to generate I2S signals. | ||
44 | * Also corresponds to clocks of I2SMOD[10] | ||
45 | */ | ||
46 | const char **src_clk; | ||
47 | }; | ||
48 | |||
28 | /** | 49 | /** |
29 | * struct s3c_audio_pdata - common platform data for audio device drivers | 50 | * struct s3c_audio_pdata - common platform data for audio device drivers |
30 | * @cfg_gpio: Callback function to setup mux'ed pins in I2S/PCM/AC97 mode | 51 | * @cfg_gpio: Callback function to setup mux'ed pins in I2S/PCM/AC97 mode |
31 | */ | 52 | */ |
32 | struct s3c_audio_pdata { | 53 | struct s3c_audio_pdata { |
33 | int (*cfg_gpio)(struct platform_device *); | 54 | int (*cfg_gpio)(struct platform_device *); |
55 | union { | ||
56 | struct samsung_i2s i2s; | ||
57 | } type; | ||
34 | }; | 58 | }; |
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h index 2d82a6cb1444..e9e3b6e3ec74 100644 --- a/arch/arm/plat-samsung/include/plat/devs.h +++ b/arch/arm/plat-samsung/include/plat/devs.h | |||
@@ -32,7 +32,7 @@ extern struct platform_device s3c64xx_device_iisv4; | |||
32 | extern struct platform_device s3c64xx_device_spi0; | 32 | extern struct platform_device s3c64xx_device_spi0; |
33 | extern struct platform_device s3c64xx_device_spi1; | 33 | extern struct platform_device s3c64xx_device_spi1; |
34 | 34 | ||
35 | extern struct platform_device s3c_device_pcm; | 35 | extern struct platform_device samsung_asoc_dma; |
36 | 36 | ||
37 | extern struct platform_device s3c64xx_device_pcm0; | 37 | extern struct platform_device s3c64xx_device_pcm0; |
38 | extern struct platform_device s3c64xx_device_pcm1; | 38 | extern struct platform_device s3c64xx_device_pcm1; |
@@ -96,6 +96,15 @@ extern struct platform_device s5pv210_device_iis1; | |||
96 | extern struct platform_device s5pv210_device_iis2; | 96 | extern struct platform_device s5pv210_device_iis2; |
97 | extern struct platform_device s5pv210_device_spdif; | 97 | extern struct platform_device s5pv210_device_spdif; |
98 | 98 | ||
99 | extern struct platform_device s5pv310_device_ac97; | ||
100 | extern struct platform_device s5pv310_device_pcm0; | ||
101 | extern struct platform_device s5pv310_device_pcm1; | ||
102 | extern struct platform_device s5pv310_device_pcm2; | ||
103 | extern struct platform_device s5pv310_device_i2s0; | ||
104 | extern struct platform_device s5pv310_device_i2s1; | ||
105 | extern struct platform_device s5pv310_device_i2s2; | ||
106 | extern struct platform_device s5pv310_device_spdif; | ||
107 | |||
99 | extern struct platform_device s5p6442_device_pcm0; | 108 | extern struct platform_device s5p6442_device_pcm0; |
100 | extern struct platform_device s5p6442_device_pcm1; | 109 | extern struct platform_device s5p6442_device_pcm1; |
101 | extern struct platform_device s5p6442_device_iis0; | 110 | extern struct platform_device s5p6442_device_iis0; |
diff --git a/arch/arm/plat-samsung/pm.c b/arch/arm/plat-samsung/pm.c index 27cfca597699..5bf3f2f09e74 100644 --- a/arch/arm/plat-samsung/pm.c +++ b/arch/arm/plat-samsung/pm.c | |||
@@ -355,7 +355,7 @@ static void s3c_pm_finish(void) | |||
355 | s3c_pm_check_cleanup(); | 355 | s3c_pm_check_cleanup(); |
356 | } | 356 | } |
357 | 357 | ||
358 | static struct platform_suspend_ops s3c_pm_ops = { | 358 | static const struct platform_suspend_ops s3c_pm_ops = { |
359 | .enter = s3c_pm_enter, | 359 | .enter = s3c_pm_enter, |
360 | .prepare = s3c_pm_prepare, | 360 | .prepare = s3c_pm_prepare, |
361 | .finish = s3c_pm_finish, | 361 | .finish = s3c_pm_finish, |
diff --git a/arch/avr32/boards/atngw100/setup.c b/arch/avr32/boards/atngw100/setup.c index 8c6a2440e345..659d119ce712 100644 --- a/arch/avr32/boards/atngw100/setup.c +++ b/arch/avr32/boards/atngw100/setup.c | |||
@@ -188,7 +188,7 @@ static void __init set_hw_addr(struct platform_device *pdev) | |||
188 | */ | 188 | */ |
189 | regs = (void __iomem __force *)res->start; | 189 | regs = (void __iomem __force *)res->start; |
190 | pclk = clk_get(&pdev->dev, "pclk"); | 190 | pclk = clk_get(&pdev->dev, "pclk"); |
191 | if (!pclk) | 191 | if (IS_ERR(pclk)) |
192 | return; | 192 | return; |
193 | 193 | ||
194 | clk_enable(pclk); | 194 | clk_enable(pclk); |
diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c index 2adc261c9e3d..6ce30fb2ec94 100644 --- a/arch/avr32/boards/atstk1000/atstk1002.c +++ b/arch/avr32/boards/atstk1000/atstk1002.c | |||
@@ -203,7 +203,7 @@ static void __init set_hw_addr(struct platform_device *pdev) | |||
203 | */ | 203 | */ |
204 | regs = (void __iomem __force *)res->start; | 204 | regs = (void __iomem __force *)res->start; |
205 | pclk = clk_get(&pdev->dev, "pclk"); | 205 | pclk = clk_get(&pdev->dev, "pclk"); |
206 | if (!pclk) | 206 | if (IS_ERR(pclk)) |
207 | return; | 207 | return; |
208 | 208 | ||
209 | clk_enable(pclk); | 209 | clk_enable(pclk); |
diff --git a/arch/avr32/boards/favr-32/setup.c b/arch/avr32/boards/favr-32/setup.c index 75f19f47fb2f..86fab77a5a00 100644 --- a/arch/avr32/boards/favr-32/setup.c +++ b/arch/avr32/boards/favr-32/setup.c | |||
@@ -206,7 +206,7 @@ static void __init set_hw_addr(struct platform_device *pdev) | |||
206 | */ | 206 | */ |
207 | regs = (void __iomem __force *)res->start; | 207 | regs = (void __iomem __force *)res->start; |
208 | pclk = clk_get(&pdev->dev, "pclk"); | 208 | pclk = clk_get(&pdev->dev, "pclk"); |
209 | if (!pclk) | 209 | if (IS_ERR(pclk)) |
210 | return; | 210 | return; |
211 | 211 | ||
212 | clk_enable(pclk); | 212 | clk_enable(pclk); |
diff --git a/arch/avr32/boards/hammerhead/setup.c b/arch/avr32/boards/hammerhead/setup.c index dd009875a405..da14fbdd4e8e 100644 --- a/arch/avr32/boards/hammerhead/setup.c +++ b/arch/avr32/boards/hammerhead/setup.c | |||
@@ -150,7 +150,7 @@ static void __init set_hw_addr(struct platform_device *pdev) | |||
150 | regs = (void __iomem __force *)res->start; | 150 | regs = (void __iomem __force *)res->start; |
151 | pclk = clk_get(&pdev->dev, "pclk"); | 151 | pclk = clk_get(&pdev->dev, "pclk"); |
152 | 152 | ||
153 | if (!pclk) | 153 | if (IS_ERR(pclk)) |
154 | return; | 154 | return; |
155 | 155 | ||
156 | clk_enable(pclk); | 156 | clk_enable(pclk); |
diff --git a/arch/avr32/boards/merisc/setup.c b/arch/avr32/boards/merisc/setup.c index 623b077594fc..e61bc948f959 100644 --- a/arch/avr32/boards/merisc/setup.c +++ b/arch/avr32/boards/merisc/setup.c | |||
@@ -134,7 +134,7 @@ static void __init set_hw_addr(struct platform_device *pdev) | |||
134 | 134 | ||
135 | regs = (void __iomem __force *)res->start; | 135 | regs = (void __iomem __force *)res->start; |
136 | pclk = clk_get(&pdev->dev, "pclk"); | 136 | pclk = clk_get(&pdev->dev, "pclk"); |
137 | if (!pclk) | 137 | if (IS_ERR(pclk)) |
138 | return; | 138 | return; |
139 | 139 | ||
140 | clk_enable(pclk); | 140 | clk_enable(pclk); |
diff --git a/arch/avr32/boards/mimc200/setup.c b/arch/avr32/boards/mimc200/setup.c index 523d8e183bef..c4da5cba2dbf 100644 --- a/arch/avr32/boards/mimc200/setup.c +++ b/arch/avr32/boards/mimc200/setup.c | |||
@@ -162,7 +162,7 @@ static void __init set_hw_addr(struct platform_device *pdev) | |||
162 | */ | 162 | */ |
163 | regs = (void __iomem __force *)res->start; | 163 | regs = (void __iomem __force *)res->start; |
164 | pclk = clk_get(&pdev->dev, "pclk"); | 164 | pclk = clk_get(&pdev->dev, "pclk"); |
165 | if (!pclk) | 165 | if (IS_ERR(pclk)) |
166 | return; | 166 | return; |
167 | 167 | ||
168 | clk_enable(pclk); | 168 | clk_enable(pclk); |
diff --git a/arch/avr32/configs/atngw100_defconfig b/arch/avr32/configs/atngw100_defconfig index 9854013d2728..6f9ca56de1f6 100644 --- a/arch/avr32/configs/atngw100_defconfig +++ b/arch/avr32/configs/atngw100_defconfig | |||
@@ -2,20 +2,17 @@ CONFIG_EXPERIMENTAL=y | |||
2 | # CONFIG_LOCALVERSION_AUTO is not set | 2 | # CONFIG_LOCALVERSION_AUTO is not set |
3 | CONFIG_SYSVIPC=y | 3 | CONFIG_SYSVIPC=y |
4 | CONFIG_POSIX_MQUEUE=y | 4 | CONFIG_POSIX_MQUEUE=y |
5 | CONFIG_BSD_PROCESS_ACCT=y | ||
6 | CONFIG_BSD_PROCESS_ACCT_V3=y | ||
7 | CONFIG_LOG_BUF_SHIFT=14 | 5 | CONFIG_LOG_BUF_SHIFT=14 |
8 | CONFIG_SYSFS_DEPRECATED_V2=y | 6 | CONFIG_RELAY=y |
9 | CONFIG_BLK_DEV_INITRD=y | 7 | CONFIG_BLK_DEV_INITRD=y |
10 | # CONFIG_SYSCTL_SYSCALL is not set | 8 | # CONFIG_SYSCTL_SYSCALL is not set |
11 | # CONFIG_BASE_FULL is not set | 9 | # CONFIG_BASE_FULL is not set |
12 | # CONFIG_COMPAT_BRK is not set | 10 | # CONFIG_COMPAT_BRK is not set |
13 | CONFIG_PROFILING=y | 11 | CONFIG_PROFILING=y |
14 | CONFIG_OPROFILE=m | 12 | CONFIG_OPROFILE=m |
15 | CONFIG_KPROBES=y | 13 | # CONFIG_KPROBES is not set |
16 | CONFIG_MODULES=y | 14 | CONFIG_MODULES=y |
17 | CONFIG_MODULE_UNLOAD=y | 15 | CONFIG_MODULE_UNLOAD=y |
18 | CONFIG_MODULE_FORCE_UNLOAD=y | ||
19 | # CONFIG_BLK_DEV_BSG is not set | 16 | # CONFIG_BLK_DEV_BSG is not set |
20 | # CONFIG_IOSCHED_DEADLINE is not set | 17 | # CONFIG_IOSCHED_DEADLINE is not set |
21 | CONFIG_NO_HZ=y | 18 | CONFIG_NO_HZ=y |
@@ -29,6 +26,7 @@ CONFIG_CPU_FREQ=y | |||
29 | CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y | 26 | CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y |
30 | CONFIG_CPU_FREQ_GOV_USERSPACE=y | 27 | CONFIG_CPU_FREQ_GOV_USERSPACE=y |
31 | CONFIG_CPU_FREQ_AT32AP=y | 28 | CONFIG_CPU_FREQ_AT32AP=y |
29 | CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y | ||
32 | CONFIG_NET=y | 30 | CONFIG_NET=y |
33 | CONFIG_PACKET=y | 31 | CONFIG_PACKET=y |
34 | CONFIG_UNIX=y | 32 | CONFIG_UNIX=y |
@@ -72,8 +70,8 @@ CONFIG_MTD_UBI=y | |||
72 | CONFIG_BLK_DEV_LOOP=m | 70 | CONFIG_BLK_DEV_LOOP=m |
73 | CONFIG_BLK_DEV_NBD=m | 71 | CONFIG_BLK_DEV_NBD=m |
74 | CONFIG_BLK_DEV_RAM=m | 72 | CONFIG_BLK_DEV_RAM=m |
73 | CONFIG_MISC_DEVICES=y | ||
75 | CONFIG_ATMEL_TCLIB=y | 74 | CONFIG_ATMEL_TCLIB=y |
76 | CONFIG_EEPROM_AT24=m | ||
77 | CONFIG_NETDEVICES=y | 75 | CONFIG_NETDEVICES=y |
78 | CONFIG_TUN=m | 76 | CONFIG_TUN=m |
79 | CONFIG_NET_ETHERNET=y | 77 | CONFIG_NET_ETHERNET=y |
@@ -106,6 +104,7 @@ CONFIG_GPIO_SYSFS=y | |||
106 | CONFIG_WATCHDOG=y | 104 | CONFIG_WATCHDOG=y |
107 | CONFIG_AT32AP700X_WDT=y | 105 | CONFIG_AT32AP700X_WDT=y |
108 | CONFIG_USB_GADGET=y | 106 | CONFIG_USB_GADGET=y |
107 | CONFIG_USB_GADGET_VBUS_DRAW=350 | ||
109 | CONFIG_USB_ZERO=m | 108 | CONFIG_USB_ZERO=m |
110 | CONFIG_USB_ETH=m | 109 | CONFIG_USB_ETH=m |
111 | CONFIG_USB_GADGETFS=m | 110 | CONFIG_USB_GADGETFS=m |
@@ -115,14 +114,12 @@ CONFIG_USB_CDC_COMPOSITE=m | |||
115 | CONFIG_MMC=y | 114 | CONFIG_MMC=y |
116 | CONFIG_MMC_TEST=m | 115 | CONFIG_MMC_TEST=m |
117 | CONFIG_MMC_ATMELMCI=y | 116 | CONFIG_MMC_ATMELMCI=y |
118 | CONFIG_MMC_SPI=m | ||
119 | CONFIG_NEW_LEDS=y | 117 | CONFIG_NEW_LEDS=y |
120 | CONFIG_LEDS_CLASS=y | 118 | CONFIG_LEDS_CLASS=y |
121 | CONFIG_LEDS_GPIO=y | 119 | CONFIG_LEDS_GPIO=y |
122 | CONFIG_LEDS_TRIGGERS=y | 120 | CONFIG_LEDS_TRIGGERS=y |
123 | CONFIG_LEDS_TRIGGER_TIMER=y | 121 | CONFIG_LEDS_TRIGGER_TIMER=y |
124 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y | 122 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y |
125 | CONFIG_LEDS_TRIGGER_DEFAULT_ON=y | ||
126 | CONFIG_RTC_CLASS=y | 123 | CONFIG_RTC_CLASS=y |
127 | CONFIG_RTC_DRV_AT32AP700X=y | 124 | CONFIG_RTC_DRV_AT32AP700X=y |
128 | CONFIG_DMADEVICES=y | 125 | CONFIG_DMADEVICES=y |
@@ -130,21 +127,23 @@ CONFIG_EXT2_FS=y | |||
130 | CONFIG_EXT3_FS=y | 127 | CONFIG_EXT3_FS=y |
131 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | 128 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set |
132 | # CONFIG_EXT3_FS_XATTR is not set | 129 | # CONFIG_EXT3_FS_XATTR is not set |
130 | CONFIG_EXT4_FS=y | ||
131 | # CONFIG_EXT4_FS_XATTR is not set | ||
133 | # CONFIG_DNOTIFY is not set | 132 | # CONFIG_DNOTIFY is not set |
134 | CONFIG_FUSE_FS=m | 133 | CONFIG_FUSE_FS=m |
135 | CONFIG_MSDOS_FS=m | 134 | CONFIG_MSDOS_FS=m |
136 | CONFIG_VFAT_FS=m | 135 | CONFIG_VFAT_FS=m |
137 | CONFIG_FAT_DEFAULT_CODEPAGE=850 | 136 | CONFIG_FAT_DEFAULT_CODEPAGE=850 |
137 | CONFIG_PROC_KCORE=y | ||
138 | CONFIG_TMPFS=y | 138 | CONFIG_TMPFS=y |
139 | CONFIG_CONFIGFS_FS=m | 139 | CONFIG_CONFIGFS_FS=y |
140 | CONFIG_JFFS2_FS=y | 140 | CONFIG_JFFS2_FS=y |
141 | CONFIG_UFS_FS=y | 141 | CONFIG_UBIFS_FS=y |
142 | CONFIG_NFS_FS=y | 142 | CONFIG_NFS_FS=y |
143 | CONFIG_NFS_V3=y | 143 | CONFIG_NFS_V3=y |
144 | CONFIG_ROOT_NFS=y | 144 | CONFIG_ROOT_NFS=y |
145 | CONFIG_NFSD=m | 145 | CONFIG_NFSD=m |
146 | CONFIG_NFSD_V3=y | 146 | CONFIG_NFSD_V3=y |
147 | CONFIG_SMB_FS=m | ||
148 | CONFIG_CIFS=m | 147 | CONFIG_CIFS=m |
149 | CONFIG_NLS_CODEPAGE_437=m | 148 | CONFIG_NLS_CODEPAGE_437=m |
150 | CONFIG_NLS_CODEPAGE_850=m | 149 | CONFIG_NLS_CODEPAGE_850=m |
@@ -155,5 +154,3 @@ CONFIG_DEBUG_FS=y | |||
155 | CONFIG_DEBUG_KERNEL=y | 154 | CONFIG_DEBUG_KERNEL=y |
156 | CONFIG_DETECT_HUNG_TASK=y | 155 | CONFIG_DETECT_HUNG_TASK=y |
157 | CONFIG_FRAME_POINTER=y | 156 | CONFIG_FRAME_POINTER=y |
158 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
159 | CONFIG_CRYPTO_PCBC=m | ||
diff --git a/arch/avr32/configs/atngw100_evklcd100_defconfig b/arch/avr32/configs/atngw100_evklcd100_defconfig index 7ceda354597b..7eece0af34c9 100644 --- a/arch/avr32/configs/atngw100_evklcd100_defconfig +++ b/arch/avr32/configs/atngw100_evklcd100_defconfig | |||
@@ -2,20 +2,17 @@ CONFIG_EXPERIMENTAL=y | |||
2 | # CONFIG_LOCALVERSION_AUTO is not set | 2 | # CONFIG_LOCALVERSION_AUTO is not set |
3 | CONFIG_SYSVIPC=y | 3 | CONFIG_SYSVIPC=y |
4 | CONFIG_POSIX_MQUEUE=y | 4 | CONFIG_POSIX_MQUEUE=y |
5 | CONFIG_BSD_PROCESS_ACCT=y | ||
6 | CONFIG_BSD_PROCESS_ACCT_V3=y | ||
7 | CONFIG_LOG_BUF_SHIFT=14 | 5 | CONFIG_LOG_BUF_SHIFT=14 |
8 | CONFIG_SYSFS_DEPRECATED_V2=y | 6 | CONFIG_RELAY=y |
9 | CONFIG_BLK_DEV_INITRD=y | 7 | CONFIG_BLK_DEV_INITRD=y |
10 | # CONFIG_SYSCTL_SYSCALL is not set | 8 | # CONFIG_SYSCTL_SYSCALL is not set |
11 | # CONFIG_BASE_FULL is not set | 9 | # CONFIG_BASE_FULL is not set |
12 | # CONFIG_COMPAT_BRK is not set | 10 | # CONFIG_COMPAT_BRK is not set |
13 | CONFIG_PROFILING=y | 11 | CONFIG_PROFILING=y |
14 | CONFIG_OPROFILE=m | 12 | CONFIG_OPROFILE=m |
15 | CONFIG_KPROBES=y | 13 | # CONFIG_KPROBES is not set |
16 | CONFIG_MODULES=y | 14 | CONFIG_MODULES=y |
17 | CONFIG_MODULE_UNLOAD=y | 15 | CONFIG_MODULE_UNLOAD=y |
18 | CONFIG_MODULE_FORCE_UNLOAD=y | ||
19 | # CONFIG_BLK_DEV_BSG is not set | 16 | # CONFIG_BLK_DEV_BSG is not set |
20 | # CONFIG_IOSCHED_DEADLINE is not set | 17 | # CONFIG_IOSCHED_DEADLINE is not set |
21 | CONFIG_NO_HZ=y | 18 | CONFIG_NO_HZ=y |
@@ -31,6 +28,7 @@ CONFIG_CPU_FREQ=y | |||
31 | CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y | 28 | CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y |
32 | CONFIG_CPU_FREQ_GOV_USERSPACE=y | 29 | CONFIG_CPU_FREQ_GOV_USERSPACE=y |
33 | CONFIG_CPU_FREQ_AT32AP=y | 30 | CONFIG_CPU_FREQ_AT32AP=y |
31 | CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y | ||
34 | CONFIG_NET=y | 32 | CONFIG_NET=y |
35 | CONFIG_PACKET=y | 33 | CONFIG_PACKET=y |
36 | CONFIG_UNIX=y | 34 | CONFIG_UNIX=y |
@@ -74,8 +72,10 @@ CONFIG_MTD_UBI=y | |||
74 | CONFIG_BLK_DEV_LOOP=m | 72 | CONFIG_BLK_DEV_LOOP=m |
75 | CONFIG_BLK_DEV_NBD=m | 73 | CONFIG_BLK_DEV_NBD=m |
76 | CONFIG_BLK_DEV_RAM=m | 74 | CONFIG_BLK_DEV_RAM=m |
75 | CONFIG_MISC_DEVICES=y | ||
77 | CONFIG_ATMEL_TCLIB=y | 76 | CONFIG_ATMEL_TCLIB=y |
78 | CONFIG_NETDEVICES=y | 77 | CONFIG_NETDEVICES=y |
78 | CONFIG_TUN=m | ||
79 | CONFIG_NET_ETHERNET=y | 79 | CONFIG_NET_ETHERNET=y |
80 | CONFIG_MACB=y | 80 | CONFIG_MACB=y |
81 | # CONFIG_NETDEV_1000 is not set | 81 | # CONFIG_NETDEV_1000 is not set |
@@ -104,6 +104,7 @@ CONFIG_I2C_GPIO=m | |||
104 | CONFIG_SPI=y | 104 | CONFIG_SPI=y |
105 | CONFIG_SPI_ATMEL=y | 105 | CONFIG_SPI_ATMEL=y |
106 | CONFIG_SPI_SPIDEV=m | 106 | CONFIG_SPI_SPIDEV=m |
107 | CONFIG_GPIO_SYSFS=y | ||
107 | # CONFIG_HWMON is not set | 108 | # CONFIG_HWMON is not set |
108 | CONFIG_WATCHDOG=y | 109 | CONFIG_WATCHDOG=y |
109 | CONFIG_AT32AP700X_WDT=y | 110 | CONFIG_AT32AP700X_WDT=y |
@@ -127,6 +128,7 @@ CONFIG_USB_FILE_STORAGE=m | |||
127 | CONFIG_USB_G_SERIAL=m | 128 | CONFIG_USB_G_SERIAL=m |
128 | CONFIG_USB_CDC_COMPOSITE=m | 129 | CONFIG_USB_CDC_COMPOSITE=m |
129 | CONFIG_MMC=y | 130 | CONFIG_MMC=y |
131 | CONFIG_MMC_TEST=m | ||
130 | CONFIG_MMC_ATMELMCI=y | 132 | CONFIG_MMC_ATMELMCI=y |
131 | CONFIG_NEW_LEDS=y | 133 | CONFIG_NEW_LEDS=y |
132 | CONFIG_LEDS_CLASS=y | 134 | CONFIG_LEDS_CLASS=y |
@@ -141,11 +143,14 @@ CONFIG_EXT2_FS=y | |||
141 | CONFIG_EXT3_FS=y | 143 | CONFIG_EXT3_FS=y |
142 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | 144 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set |
143 | # CONFIG_EXT3_FS_XATTR is not set | 145 | # CONFIG_EXT3_FS_XATTR is not set |
146 | CONFIG_EXT4_FS=y | ||
147 | # CONFIG_EXT4_FS_XATTR is not set | ||
144 | # CONFIG_DNOTIFY is not set | 148 | # CONFIG_DNOTIFY is not set |
145 | CONFIG_FUSE_FS=m | 149 | CONFIG_FUSE_FS=m |
146 | CONFIG_MSDOS_FS=m | 150 | CONFIG_MSDOS_FS=m |
147 | CONFIG_VFAT_FS=m | 151 | CONFIG_VFAT_FS=m |
148 | CONFIG_FAT_DEFAULT_CODEPAGE=850 | 152 | CONFIG_FAT_DEFAULT_CODEPAGE=850 |
153 | CONFIG_PROC_KCORE=y | ||
149 | CONFIG_TMPFS=y | 154 | CONFIG_TMPFS=y |
150 | CONFIG_CONFIGFS_FS=y | 155 | CONFIG_CONFIGFS_FS=y |
151 | CONFIG_JFFS2_FS=y | 156 | CONFIG_JFFS2_FS=y |
@@ -155,7 +160,6 @@ CONFIG_NFS_V3=y | |||
155 | CONFIG_ROOT_NFS=y | 160 | CONFIG_ROOT_NFS=y |
156 | CONFIG_NFSD=m | 161 | CONFIG_NFSD=m |
157 | CONFIG_NFSD_V3=y | 162 | CONFIG_NFSD_V3=y |
158 | CONFIG_SMB_FS=m | ||
159 | CONFIG_CIFS=m | 163 | CONFIG_CIFS=m |
160 | CONFIG_NLS_CODEPAGE_437=m | 164 | CONFIG_NLS_CODEPAGE_437=m |
161 | CONFIG_NLS_CODEPAGE_850=m | 165 | CONFIG_NLS_CODEPAGE_850=m |
@@ -166,4 +170,3 @@ CONFIG_DEBUG_FS=y | |||
166 | CONFIG_DEBUG_KERNEL=y | 170 | CONFIG_DEBUG_KERNEL=y |
167 | CONFIG_DETECT_HUNG_TASK=y | 171 | CONFIG_DETECT_HUNG_TASK=y |
168 | CONFIG_FRAME_POINTER=y | 172 | CONFIG_FRAME_POINTER=y |
169 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
diff --git a/arch/avr32/configs/atngw100_evklcd101_defconfig b/arch/avr32/configs/atngw100_evklcd101_defconfig index 7bc5b2ce68d5..387eb9d6e423 100644 --- a/arch/avr32/configs/atngw100_evklcd101_defconfig +++ b/arch/avr32/configs/atngw100_evklcd101_defconfig | |||
@@ -2,20 +2,17 @@ CONFIG_EXPERIMENTAL=y | |||
2 | # CONFIG_LOCALVERSION_AUTO is not set | 2 | # CONFIG_LOCALVERSION_AUTO is not set |
3 | CONFIG_SYSVIPC=y | 3 | CONFIG_SYSVIPC=y |
4 | CONFIG_POSIX_MQUEUE=y | 4 | CONFIG_POSIX_MQUEUE=y |
5 | CONFIG_BSD_PROCESS_ACCT=y | ||
6 | CONFIG_BSD_PROCESS_ACCT_V3=y | ||
7 | CONFIG_LOG_BUF_SHIFT=14 | 5 | CONFIG_LOG_BUF_SHIFT=14 |
8 | CONFIG_SYSFS_DEPRECATED_V2=y | 6 | CONFIG_RELAY=y |
9 | CONFIG_BLK_DEV_INITRD=y | 7 | CONFIG_BLK_DEV_INITRD=y |
10 | # CONFIG_SYSCTL_SYSCALL is not set | 8 | # CONFIG_SYSCTL_SYSCALL is not set |
11 | # CONFIG_BASE_FULL is not set | 9 | # CONFIG_BASE_FULL is not set |
12 | # CONFIG_COMPAT_BRK is not set | 10 | # CONFIG_COMPAT_BRK is not set |
13 | CONFIG_PROFILING=y | 11 | CONFIG_PROFILING=y |
14 | CONFIG_OPROFILE=m | 12 | CONFIG_OPROFILE=m |
15 | CONFIG_KPROBES=y | 13 | # CONFIG_KPROBES is not set |
16 | CONFIG_MODULES=y | 14 | CONFIG_MODULES=y |
17 | CONFIG_MODULE_UNLOAD=y | 15 | CONFIG_MODULE_UNLOAD=y |
18 | CONFIG_MODULE_FORCE_UNLOAD=y | ||
19 | # CONFIG_BLK_DEV_BSG is not set | 16 | # CONFIG_BLK_DEV_BSG is not set |
20 | # CONFIG_IOSCHED_DEADLINE is not set | 17 | # CONFIG_IOSCHED_DEADLINE is not set |
21 | CONFIG_NO_HZ=y | 18 | CONFIG_NO_HZ=y |
@@ -30,6 +27,7 @@ CONFIG_CPU_FREQ=y | |||
30 | CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y | 27 | CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y |
31 | CONFIG_CPU_FREQ_GOV_USERSPACE=y | 28 | CONFIG_CPU_FREQ_GOV_USERSPACE=y |
32 | CONFIG_CPU_FREQ_AT32AP=y | 29 | CONFIG_CPU_FREQ_AT32AP=y |
30 | CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y | ||
33 | CONFIG_NET=y | 31 | CONFIG_NET=y |
34 | CONFIG_PACKET=y | 32 | CONFIG_PACKET=y |
35 | CONFIG_UNIX=y | 33 | CONFIG_UNIX=y |
@@ -73,8 +71,10 @@ CONFIG_MTD_UBI=y | |||
73 | CONFIG_BLK_DEV_LOOP=m | 71 | CONFIG_BLK_DEV_LOOP=m |
74 | CONFIG_BLK_DEV_NBD=m | 72 | CONFIG_BLK_DEV_NBD=m |
75 | CONFIG_BLK_DEV_RAM=m | 73 | CONFIG_BLK_DEV_RAM=m |
74 | CONFIG_MISC_DEVICES=y | ||
76 | CONFIG_ATMEL_TCLIB=y | 75 | CONFIG_ATMEL_TCLIB=y |
77 | CONFIG_NETDEVICES=y | 76 | CONFIG_NETDEVICES=y |
77 | CONFIG_TUN=m | ||
78 | CONFIG_NET_ETHERNET=y | 78 | CONFIG_NET_ETHERNET=y |
79 | CONFIG_MACB=y | 79 | CONFIG_MACB=y |
80 | # CONFIG_NETDEV_1000 is not set | 80 | # CONFIG_NETDEV_1000 is not set |
@@ -103,6 +103,7 @@ CONFIG_I2C_GPIO=m | |||
103 | CONFIG_SPI=y | 103 | CONFIG_SPI=y |
104 | CONFIG_SPI_ATMEL=y | 104 | CONFIG_SPI_ATMEL=y |
105 | CONFIG_SPI_SPIDEV=m | 105 | CONFIG_SPI_SPIDEV=m |
106 | CONFIG_GPIO_SYSFS=y | ||
106 | # CONFIG_HWMON is not set | 107 | # CONFIG_HWMON is not set |
107 | CONFIG_WATCHDOG=y | 108 | CONFIG_WATCHDOG=y |
108 | CONFIG_AT32AP700X_WDT=y | 109 | CONFIG_AT32AP700X_WDT=y |
@@ -126,6 +127,7 @@ CONFIG_USB_FILE_STORAGE=m | |||
126 | CONFIG_USB_G_SERIAL=m | 127 | CONFIG_USB_G_SERIAL=m |
127 | CONFIG_USB_CDC_COMPOSITE=m | 128 | CONFIG_USB_CDC_COMPOSITE=m |
128 | CONFIG_MMC=y | 129 | CONFIG_MMC=y |
130 | CONFIG_MMC_TEST=m | ||
129 | CONFIG_MMC_ATMELMCI=y | 131 | CONFIG_MMC_ATMELMCI=y |
130 | CONFIG_NEW_LEDS=y | 132 | CONFIG_NEW_LEDS=y |
131 | CONFIG_LEDS_CLASS=y | 133 | CONFIG_LEDS_CLASS=y |
@@ -140,11 +142,14 @@ CONFIG_EXT2_FS=y | |||
140 | CONFIG_EXT3_FS=y | 142 | CONFIG_EXT3_FS=y |
141 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | 143 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set |
142 | # CONFIG_EXT3_FS_XATTR is not set | 144 | # CONFIG_EXT3_FS_XATTR is not set |
145 | CONFIG_EXT4_FS=y | ||
146 | # CONFIG_EXT4_FS_XATTR is not set | ||
143 | # CONFIG_DNOTIFY is not set | 147 | # CONFIG_DNOTIFY is not set |
144 | CONFIG_FUSE_FS=m | 148 | CONFIG_FUSE_FS=m |
145 | CONFIG_MSDOS_FS=m | 149 | CONFIG_MSDOS_FS=m |
146 | CONFIG_VFAT_FS=m | 150 | CONFIG_VFAT_FS=m |
147 | CONFIG_FAT_DEFAULT_CODEPAGE=850 | 151 | CONFIG_FAT_DEFAULT_CODEPAGE=850 |
152 | CONFIG_PROC_KCORE=y | ||
148 | CONFIG_TMPFS=y | 153 | CONFIG_TMPFS=y |
149 | CONFIG_CONFIGFS_FS=y | 154 | CONFIG_CONFIGFS_FS=y |
150 | CONFIG_JFFS2_FS=y | 155 | CONFIG_JFFS2_FS=y |
@@ -154,7 +159,6 @@ CONFIG_NFS_V3=y | |||
154 | CONFIG_ROOT_NFS=y | 159 | CONFIG_ROOT_NFS=y |
155 | CONFIG_NFSD=m | 160 | CONFIG_NFSD=m |
156 | CONFIG_NFSD_V3=y | 161 | CONFIG_NFSD_V3=y |
157 | CONFIG_SMB_FS=m | ||
158 | CONFIG_CIFS=m | 162 | CONFIG_CIFS=m |
159 | CONFIG_NLS_CODEPAGE_437=m | 163 | CONFIG_NLS_CODEPAGE_437=m |
160 | CONFIG_NLS_CODEPAGE_850=m | 164 | CONFIG_NLS_CODEPAGE_850=m |
@@ -165,4 +169,3 @@ CONFIG_DEBUG_FS=y | |||
165 | CONFIG_DEBUG_KERNEL=y | 169 | CONFIG_DEBUG_KERNEL=y |
166 | CONFIG_DETECT_HUNG_TASK=y | 170 | CONFIG_DETECT_HUNG_TASK=y |
167 | CONFIG_FRAME_POINTER=y | 171 | CONFIG_FRAME_POINTER=y |
168 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
diff --git a/arch/avr32/configs/atngw100mkii_defconfig b/arch/avr32/configs/atngw100mkii_defconfig index 4bd36821d4a2..f0fe237133a9 100644 --- a/arch/avr32/configs/atngw100mkii_defconfig +++ b/arch/avr32/configs/atngw100mkii_defconfig | |||
@@ -2,20 +2,17 @@ CONFIG_EXPERIMENTAL=y | |||
2 | # CONFIG_LOCALVERSION_AUTO is not set | 2 | # CONFIG_LOCALVERSION_AUTO is not set |
3 | CONFIG_SYSVIPC=y | 3 | CONFIG_SYSVIPC=y |
4 | CONFIG_POSIX_MQUEUE=y | 4 | CONFIG_POSIX_MQUEUE=y |
5 | CONFIG_BSD_PROCESS_ACCT=y | ||
6 | CONFIG_BSD_PROCESS_ACCT_V3=y | ||
7 | CONFIG_LOG_BUF_SHIFT=14 | 5 | CONFIG_LOG_BUF_SHIFT=14 |
8 | CONFIG_SYSFS_DEPRECATED_V2=y | 6 | CONFIG_RELAY=y |
9 | CONFIG_BLK_DEV_INITRD=y | 7 | CONFIG_BLK_DEV_INITRD=y |
10 | # CONFIG_SYSCTL_SYSCALL is not set | 8 | # CONFIG_SYSCTL_SYSCALL is not set |
11 | # CONFIG_BASE_FULL is not set | 9 | # CONFIG_BASE_FULL is not set |
12 | # CONFIG_COMPAT_BRK is not set | 10 | # CONFIG_COMPAT_BRK is not set |
13 | CONFIG_PROFILING=y | 11 | CONFIG_PROFILING=y |
14 | CONFIG_OPROFILE=m | 12 | CONFIG_OPROFILE=m |
15 | CONFIG_KPROBES=y | 13 | # CONFIG_KPROBES is not set |
16 | CONFIG_MODULES=y | 14 | CONFIG_MODULES=y |
17 | CONFIG_MODULE_UNLOAD=y | 15 | CONFIG_MODULE_UNLOAD=y |
18 | CONFIG_MODULE_FORCE_UNLOAD=y | ||
19 | # CONFIG_BLK_DEV_BSG is not set | 16 | # CONFIG_BLK_DEV_BSG is not set |
20 | # CONFIG_IOSCHED_DEADLINE is not set | 17 | # CONFIG_IOSCHED_DEADLINE is not set |
21 | CONFIG_NO_HZ=y | 18 | CONFIG_NO_HZ=y |
@@ -29,6 +26,7 @@ CONFIG_CPU_FREQ=y | |||
29 | CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y | 26 | CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y |
30 | CONFIG_CPU_FREQ_GOV_USERSPACE=y | 27 | CONFIG_CPU_FREQ_GOV_USERSPACE=y |
31 | CONFIG_CPU_FREQ_AT32AP=y | 28 | CONFIG_CPU_FREQ_AT32AP=y |
29 | CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y | ||
32 | CONFIG_NET=y | 30 | CONFIG_NET=y |
33 | CONFIG_PACKET=y | 31 | CONFIG_PACKET=y |
34 | CONFIG_UNIX=y | 32 | CONFIG_UNIX=y |
@@ -74,6 +72,7 @@ CONFIG_MTD_UBI=y | |||
74 | CONFIG_BLK_DEV_LOOP=m | 72 | CONFIG_BLK_DEV_LOOP=m |
75 | CONFIG_BLK_DEV_NBD=m | 73 | CONFIG_BLK_DEV_NBD=m |
76 | CONFIG_BLK_DEV_RAM=m | 74 | CONFIG_BLK_DEV_RAM=m |
75 | CONFIG_MISC_DEVICES=y | ||
77 | CONFIG_ATMEL_TCLIB=y | 76 | CONFIG_ATMEL_TCLIB=y |
78 | CONFIG_NETDEVICES=y | 77 | CONFIG_NETDEVICES=y |
79 | CONFIG_TUN=m | 78 | CONFIG_TUN=m |
@@ -107,6 +106,7 @@ CONFIG_GPIO_SYSFS=y | |||
107 | CONFIG_WATCHDOG=y | 106 | CONFIG_WATCHDOG=y |
108 | CONFIG_AT32AP700X_WDT=y | 107 | CONFIG_AT32AP700X_WDT=y |
109 | CONFIG_USB_GADGET=y | 108 | CONFIG_USB_GADGET=y |
109 | CONFIG_USB_GADGET_VBUS_DRAW=350 | ||
110 | CONFIG_USB_ZERO=m | 110 | CONFIG_USB_ZERO=m |
111 | CONFIG_USB_ETH=m | 111 | CONFIG_USB_ETH=m |
112 | CONFIG_USB_GADGETFS=m | 112 | CONFIG_USB_GADGETFS=m |
@@ -116,14 +116,12 @@ CONFIG_USB_CDC_COMPOSITE=m | |||
116 | CONFIG_MMC=y | 116 | CONFIG_MMC=y |
117 | CONFIG_MMC_TEST=m | 117 | CONFIG_MMC_TEST=m |
118 | CONFIG_MMC_ATMELMCI=y | 118 | CONFIG_MMC_ATMELMCI=y |
119 | CONFIG_MMC_SPI=m | ||
120 | CONFIG_NEW_LEDS=y | 119 | CONFIG_NEW_LEDS=y |
121 | CONFIG_LEDS_CLASS=y | 120 | CONFIG_LEDS_CLASS=y |
122 | CONFIG_LEDS_GPIO=y | 121 | CONFIG_LEDS_GPIO=y |
123 | CONFIG_LEDS_TRIGGERS=y | 122 | CONFIG_LEDS_TRIGGERS=y |
124 | CONFIG_LEDS_TRIGGER_TIMER=y | 123 | CONFIG_LEDS_TRIGGER_TIMER=y |
125 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y | 124 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y |
126 | CONFIG_LEDS_TRIGGER_DEFAULT_ON=y | ||
127 | CONFIG_RTC_CLASS=y | 125 | CONFIG_RTC_CLASS=y |
128 | CONFIG_RTC_DRV_AT32AP700X=y | 126 | CONFIG_RTC_DRV_AT32AP700X=y |
129 | CONFIG_DMADEVICES=y | 127 | CONFIG_DMADEVICES=y |
@@ -131,21 +129,23 @@ CONFIG_EXT2_FS=y | |||
131 | CONFIG_EXT3_FS=y | 129 | CONFIG_EXT3_FS=y |
132 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | 130 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set |
133 | # CONFIG_EXT3_FS_XATTR is not set | 131 | # CONFIG_EXT3_FS_XATTR is not set |
132 | CONFIG_EXT4_FS=y | ||
133 | # CONFIG_EXT4_FS_XATTR is not set | ||
134 | # CONFIG_DNOTIFY is not set | 134 | # CONFIG_DNOTIFY is not set |
135 | CONFIG_FUSE_FS=m | 135 | CONFIG_FUSE_FS=m |
136 | CONFIG_MSDOS_FS=m | 136 | CONFIG_MSDOS_FS=m |
137 | CONFIG_VFAT_FS=m | 137 | CONFIG_VFAT_FS=m |
138 | CONFIG_FAT_DEFAULT_CODEPAGE=850 | 138 | CONFIG_FAT_DEFAULT_CODEPAGE=850 |
139 | CONFIG_PROC_KCORE=y | ||
139 | CONFIG_TMPFS=y | 140 | CONFIG_TMPFS=y |
140 | CONFIG_CONFIGFS_FS=m | 141 | CONFIG_CONFIGFS_FS=y |
141 | CONFIG_JFFS2_FS=y | 142 | CONFIG_JFFS2_FS=y |
142 | CONFIG_UFS_FS=y | 143 | CONFIG_UBIFS_FS=y |
143 | CONFIG_NFS_FS=y | 144 | CONFIG_NFS_FS=y |
144 | CONFIG_NFS_V3=y | 145 | CONFIG_NFS_V3=y |
145 | CONFIG_ROOT_NFS=y | 146 | CONFIG_ROOT_NFS=y |
146 | CONFIG_NFSD=m | 147 | CONFIG_NFSD=m |
147 | CONFIG_NFSD_V3=y | 148 | CONFIG_NFSD_V3=y |
148 | CONFIG_SMB_FS=m | ||
149 | CONFIG_CIFS=m | 149 | CONFIG_CIFS=m |
150 | CONFIG_NLS_CODEPAGE_437=m | 150 | CONFIG_NLS_CODEPAGE_437=m |
151 | CONFIG_NLS_CODEPAGE_850=m | 151 | CONFIG_NLS_CODEPAGE_850=m |
@@ -156,5 +156,3 @@ CONFIG_DEBUG_FS=y | |||
156 | CONFIG_DEBUG_KERNEL=y | 156 | CONFIG_DEBUG_KERNEL=y |
157 | CONFIG_DETECT_HUNG_TASK=y | 157 | CONFIG_DETECT_HUNG_TASK=y |
158 | CONFIG_FRAME_POINTER=y | 158 | CONFIG_FRAME_POINTER=y |
159 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
160 | CONFIG_CRYPTO_PCBC=m | ||
diff --git a/arch/avr32/configs/atngw100mkii_evklcd100_defconfig b/arch/avr32/configs/atngw100mkii_evklcd100_defconfig index f8437ef3237f..e4a7c1dc8380 100644 --- a/arch/avr32/configs/atngw100mkii_evklcd100_defconfig +++ b/arch/avr32/configs/atngw100mkii_evklcd100_defconfig | |||
@@ -2,20 +2,17 @@ CONFIG_EXPERIMENTAL=y | |||
2 | # CONFIG_LOCALVERSION_AUTO is not set | 2 | # CONFIG_LOCALVERSION_AUTO is not set |
3 | CONFIG_SYSVIPC=y | 3 | CONFIG_SYSVIPC=y |
4 | CONFIG_POSIX_MQUEUE=y | 4 | CONFIG_POSIX_MQUEUE=y |
5 | CONFIG_BSD_PROCESS_ACCT=y | ||
6 | CONFIG_BSD_PROCESS_ACCT_V3=y | ||
7 | CONFIG_LOG_BUF_SHIFT=14 | 5 | CONFIG_LOG_BUF_SHIFT=14 |
8 | CONFIG_SYSFS_DEPRECATED_V2=y | 6 | CONFIG_RELAY=y |
9 | CONFIG_BLK_DEV_INITRD=y | 7 | CONFIG_BLK_DEV_INITRD=y |
10 | # CONFIG_SYSCTL_SYSCALL is not set | 8 | # CONFIG_SYSCTL_SYSCALL is not set |
11 | # CONFIG_BASE_FULL is not set | 9 | # CONFIG_BASE_FULL is not set |
12 | # CONFIG_COMPAT_BRK is not set | 10 | # CONFIG_COMPAT_BRK is not set |
13 | CONFIG_PROFILING=y | 11 | CONFIG_PROFILING=y |
14 | CONFIG_OPROFILE=m | 12 | CONFIG_OPROFILE=m |
15 | CONFIG_KPROBES=y | 13 | # CONFIG_KPROBES is not set |
16 | CONFIG_MODULES=y | 14 | CONFIG_MODULES=y |
17 | CONFIG_MODULE_UNLOAD=y | 15 | CONFIG_MODULE_UNLOAD=y |
18 | CONFIG_MODULE_FORCE_UNLOAD=y | ||
19 | # CONFIG_BLK_DEV_BSG is not set | 16 | # CONFIG_BLK_DEV_BSG is not set |
20 | # CONFIG_IOSCHED_DEADLINE is not set | 17 | # CONFIG_IOSCHED_DEADLINE is not set |
21 | CONFIG_NO_HZ=y | 18 | CONFIG_NO_HZ=y |
@@ -32,6 +29,7 @@ CONFIG_CPU_FREQ=y | |||
32 | CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y | 29 | CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y |
33 | CONFIG_CPU_FREQ_GOV_USERSPACE=y | 30 | CONFIG_CPU_FREQ_GOV_USERSPACE=y |
34 | CONFIG_CPU_FREQ_AT32AP=y | 31 | CONFIG_CPU_FREQ_AT32AP=y |
32 | CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y | ||
35 | CONFIG_NET=y | 33 | CONFIG_NET=y |
36 | CONFIG_PACKET=y | 34 | CONFIG_PACKET=y |
37 | CONFIG_UNIX=y | 35 | CONFIG_UNIX=y |
@@ -77,8 +75,10 @@ CONFIG_MTD_UBI=y | |||
77 | CONFIG_BLK_DEV_LOOP=m | 75 | CONFIG_BLK_DEV_LOOP=m |
78 | CONFIG_BLK_DEV_NBD=m | 76 | CONFIG_BLK_DEV_NBD=m |
79 | CONFIG_BLK_DEV_RAM=m | 77 | CONFIG_BLK_DEV_RAM=m |
78 | CONFIG_MISC_DEVICES=y | ||
80 | CONFIG_ATMEL_TCLIB=y | 79 | CONFIG_ATMEL_TCLIB=y |
81 | CONFIG_NETDEVICES=y | 80 | CONFIG_NETDEVICES=y |
81 | CONFIG_TUN=m | ||
82 | CONFIG_NET_ETHERNET=y | 82 | CONFIG_NET_ETHERNET=y |
83 | CONFIG_MACB=y | 83 | CONFIG_MACB=y |
84 | # CONFIG_NETDEV_1000 is not set | 84 | # CONFIG_NETDEV_1000 is not set |
@@ -107,6 +107,7 @@ CONFIG_I2C_GPIO=m | |||
107 | CONFIG_SPI=y | 107 | CONFIG_SPI=y |
108 | CONFIG_SPI_ATMEL=y | 108 | CONFIG_SPI_ATMEL=y |
109 | CONFIG_SPI_SPIDEV=m | 109 | CONFIG_SPI_SPIDEV=m |
110 | CONFIG_GPIO_SYSFS=y | ||
110 | # CONFIG_HWMON is not set | 111 | # CONFIG_HWMON is not set |
111 | CONFIG_WATCHDOG=y | 112 | CONFIG_WATCHDOG=y |
112 | CONFIG_AT32AP700X_WDT=y | 113 | CONFIG_AT32AP700X_WDT=y |
@@ -130,6 +131,7 @@ CONFIG_USB_FILE_STORAGE=m | |||
130 | CONFIG_USB_G_SERIAL=m | 131 | CONFIG_USB_G_SERIAL=m |
131 | CONFIG_USB_CDC_COMPOSITE=m | 132 | CONFIG_USB_CDC_COMPOSITE=m |
132 | CONFIG_MMC=y | 133 | CONFIG_MMC=y |
134 | CONFIG_MMC_TEST=m | ||
133 | CONFIG_MMC_ATMELMCI=y | 135 | CONFIG_MMC_ATMELMCI=y |
134 | CONFIG_NEW_LEDS=y | 136 | CONFIG_NEW_LEDS=y |
135 | CONFIG_LEDS_CLASS=y | 137 | CONFIG_LEDS_CLASS=y |
@@ -144,11 +146,14 @@ CONFIG_EXT2_FS=y | |||
144 | CONFIG_EXT3_FS=y | 146 | CONFIG_EXT3_FS=y |
145 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | 147 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set |
146 | # CONFIG_EXT3_FS_XATTR is not set | 148 | # CONFIG_EXT3_FS_XATTR is not set |
149 | CONFIG_EXT4_FS=y | ||
150 | # CONFIG_EXT4_FS_XATTR is not set | ||
147 | # CONFIG_DNOTIFY is not set | 151 | # CONFIG_DNOTIFY is not set |
148 | CONFIG_FUSE_FS=m | 152 | CONFIG_FUSE_FS=m |
149 | CONFIG_MSDOS_FS=m | 153 | CONFIG_MSDOS_FS=m |
150 | CONFIG_VFAT_FS=m | 154 | CONFIG_VFAT_FS=m |
151 | CONFIG_FAT_DEFAULT_CODEPAGE=850 | 155 | CONFIG_FAT_DEFAULT_CODEPAGE=850 |
156 | CONFIG_PROC_KCORE=y | ||
152 | CONFIG_TMPFS=y | 157 | CONFIG_TMPFS=y |
153 | CONFIG_CONFIGFS_FS=y | 158 | CONFIG_CONFIGFS_FS=y |
154 | CONFIG_JFFS2_FS=y | 159 | CONFIG_JFFS2_FS=y |
@@ -158,7 +163,6 @@ CONFIG_NFS_V3=y | |||
158 | CONFIG_ROOT_NFS=y | 163 | CONFIG_ROOT_NFS=y |
159 | CONFIG_NFSD=m | 164 | CONFIG_NFSD=m |
160 | CONFIG_NFSD_V3=y | 165 | CONFIG_NFSD_V3=y |
161 | CONFIG_SMB_FS=m | ||
162 | CONFIG_CIFS=m | 166 | CONFIG_CIFS=m |
163 | CONFIG_NLS_CODEPAGE_437=m | 167 | CONFIG_NLS_CODEPAGE_437=m |
164 | CONFIG_NLS_CODEPAGE_850=m | 168 | CONFIG_NLS_CODEPAGE_850=m |
@@ -169,4 +173,3 @@ CONFIG_DEBUG_FS=y | |||
169 | CONFIG_DEBUG_KERNEL=y | 173 | CONFIG_DEBUG_KERNEL=y |
170 | CONFIG_DETECT_HUNG_TASK=y | 174 | CONFIG_DETECT_HUNG_TASK=y |
171 | CONFIG_FRAME_POINTER=y | 175 | CONFIG_FRAME_POINTER=y |
172 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
diff --git a/arch/avr32/configs/atngw100mkii_evklcd101_defconfig b/arch/avr32/configs/atngw100mkii_evklcd101_defconfig index 7f58f996d945..6f37f70c2c37 100644 --- a/arch/avr32/configs/atngw100mkii_evklcd101_defconfig +++ b/arch/avr32/configs/atngw100mkii_evklcd101_defconfig | |||
@@ -2,20 +2,17 @@ CONFIG_EXPERIMENTAL=y | |||
2 | # CONFIG_LOCALVERSION_AUTO is not set | 2 | # CONFIG_LOCALVERSION_AUTO is not set |
3 | CONFIG_SYSVIPC=y | 3 | CONFIG_SYSVIPC=y |
4 | CONFIG_POSIX_MQUEUE=y | 4 | CONFIG_POSIX_MQUEUE=y |
5 | CONFIG_BSD_PROCESS_ACCT=y | ||
6 | CONFIG_BSD_PROCESS_ACCT_V3=y | ||
7 | CONFIG_LOG_BUF_SHIFT=14 | 5 | CONFIG_LOG_BUF_SHIFT=14 |
8 | CONFIG_SYSFS_DEPRECATED_V2=y | 6 | CONFIG_RELAY=y |
9 | CONFIG_BLK_DEV_INITRD=y | 7 | CONFIG_BLK_DEV_INITRD=y |
10 | # CONFIG_SYSCTL_SYSCALL is not set | 8 | # CONFIG_SYSCTL_SYSCALL is not set |
11 | # CONFIG_BASE_FULL is not set | 9 | # CONFIG_BASE_FULL is not set |
12 | # CONFIG_COMPAT_BRK is not set | 10 | # CONFIG_COMPAT_BRK is not set |
13 | CONFIG_PROFILING=y | 11 | CONFIG_PROFILING=y |
14 | CONFIG_OPROFILE=m | 12 | CONFIG_OPROFILE=m |
15 | CONFIG_KPROBES=y | 13 | # CONFIG_KPROBES is not set |
16 | CONFIG_MODULES=y | 14 | CONFIG_MODULES=y |
17 | CONFIG_MODULE_UNLOAD=y | 15 | CONFIG_MODULE_UNLOAD=y |
18 | CONFIG_MODULE_FORCE_UNLOAD=y | ||
19 | # CONFIG_BLK_DEV_BSG is not set | 16 | # CONFIG_BLK_DEV_BSG is not set |
20 | # CONFIG_IOSCHED_DEADLINE is not set | 17 | # CONFIG_IOSCHED_DEADLINE is not set |
21 | CONFIG_NO_HZ=y | 18 | CONFIG_NO_HZ=y |
@@ -31,6 +28,7 @@ CONFIG_CPU_FREQ=y | |||
31 | CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y | 28 | CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y |
32 | CONFIG_CPU_FREQ_GOV_USERSPACE=y | 29 | CONFIG_CPU_FREQ_GOV_USERSPACE=y |
33 | CONFIG_CPU_FREQ_AT32AP=y | 30 | CONFIG_CPU_FREQ_AT32AP=y |
31 | CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y | ||
34 | CONFIG_NET=y | 32 | CONFIG_NET=y |
35 | CONFIG_PACKET=y | 33 | CONFIG_PACKET=y |
36 | CONFIG_UNIX=y | 34 | CONFIG_UNIX=y |
@@ -76,8 +74,10 @@ CONFIG_MTD_UBI=y | |||
76 | CONFIG_BLK_DEV_LOOP=m | 74 | CONFIG_BLK_DEV_LOOP=m |
77 | CONFIG_BLK_DEV_NBD=m | 75 | CONFIG_BLK_DEV_NBD=m |
78 | CONFIG_BLK_DEV_RAM=m | 76 | CONFIG_BLK_DEV_RAM=m |
77 | CONFIG_MISC_DEVICES=y | ||
79 | CONFIG_ATMEL_TCLIB=y | 78 | CONFIG_ATMEL_TCLIB=y |
80 | CONFIG_NETDEVICES=y | 79 | CONFIG_NETDEVICES=y |
80 | CONFIG_TUN=m | ||
81 | CONFIG_NET_ETHERNET=y | 81 | CONFIG_NET_ETHERNET=y |
82 | CONFIG_MACB=y | 82 | CONFIG_MACB=y |
83 | # CONFIG_NETDEV_1000 is not set | 83 | # CONFIG_NETDEV_1000 is not set |
@@ -106,6 +106,7 @@ CONFIG_I2C_GPIO=m | |||
106 | CONFIG_SPI=y | 106 | CONFIG_SPI=y |
107 | CONFIG_SPI_ATMEL=y | 107 | CONFIG_SPI_ATMEL=y |
108 | CONFIG_SPI_SPIDEV=m | 108 | CONFIG_SPI_SPIDEV=m |
109 | CONFIG_GPIO_SYSFS=y | ||
109 | # CONFIG_HWMON is not set | 110 | # CONFIG_HWMON is not set |
110 | CONFIG_WATCHDOG=y | 111 | CONFIG_WATCHDOG=y |
111 | CONFIG_AT32AP700X_WDT=y | 112 | CONFIG_AT32AP700X_WDT=y |
@@ -129,6 +130,7 @@ CONFIG_USB_FILE_STORAGE=m | |||
129 | CONFIG_USB_G_SERIAL=m | 130 | CONFIG_USB_G_SERIAL=m |
130 | CONFIG_USB_CDC_COMPOSITE=m | 131 | CONFIG_USB_CDC_COMPOSITE=m |
131 | CONFIG_MMC=y | 132 | CONFIG_MMC=y |
133 | CONFIG_MMC_TEST=m | ||
132 | CONFIG_MMC_ATMELMCI=y | 134 | CONFIG_MMC_ATMELMCI=y |
133 | CONFIG_NEW_LEDS=y | 135 | CONFIG_NEW_LEDS=y |
134 | CONFIG_LEDS_CLASS=y | 136 | CONFIG_LEDS_CLASS=y |
@@ -143,11 +145,14 @@ CONFIG_EXT2_FS=y | |||
143 | CONFIG_EXT3_FS=y | 145 | CONFIG_EXT3_FS=y |
144 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | 146 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set |
145 | # CONFIG_EXT3_FS_XATTR is not set | 147 | # CONFIG_EXT3_FS_XATTR is not set |
148 | CONFIG_EXT4_FS=y | ||
149 | # CONFIG_EXT4_FS_XATTR is not set | ||
146 | # CONFIG_DNOTIFY is not set | 150 | # CONFIG_DNOTIFY is not set |
147 | CONFIG_FUSE_FS=m | 151 | CONFIG_FUSE_FS=m |
148 | CONFIG_MSDOS_FS=m | 152 | CONFIG_MSDOS_FS=m |
149 | CONFIG_VFAT_FS=m | 153 | CONFIG_VFAT_FS=m |
150 | CONFIG_FAT_DEFAULT_CODEPAGE=850 | 154 | CONFIG_FAT_DEFAULT_CODEPAGE=850 |
155 | CONFIG_PROC_KCORE=y | ||
151 | CONFIG_TMPFS=y | 156 | CONFIG_TMPFS=y |
152 | CONFIG_CONFIGFS_FS=y | 157 | CONFIG_CONFIGFS_FS=y |
153 | CONFIG_JFFS2_FS=y | 158 | CONFIG_JFFS2_FS=y |
@@ -157,7 +162,6 @@ CONFIG_NFS_V3=y | |||
157 | CONFIG_ROOT_NFS=y | 162 | CONFIG_ROOT_NFS=y |
158 | CONFIG_NFSD=m | 163 | CONFIG_NFSD=m |
159 | CONFIG_NFSD_V3=y | 164 | CONFIG_NFSD_V3=y |
160 | CONFIG_SMB_FS=m | ||
161 | CONFIG_CIFS=m | 165 | CONFIG_CIFS=m |
162 | CONFIG_NLS_CODEPAGE_437=m | 166 | CONFIG_NLS_CODEPAGE_437=m |
163 | CONFIG_NLS_CODEPAGE_850=m | 167 | CONFIG_NLS_CODEPAGE_850=m |
@@ -168,4 +172,3 @@ CONFIG_DEBUG_FS=y | |||
168 | CONFIG_DEBUG_KERNEL=y | 172 | CONFIG_DEBUG_KERNEL=y |
169 | CONFIG_DETECT_HUNG_TASK=y | 173 | CONFIG_DETECT_HUNG_TASK=y |
170 | CONFIG_FRAME_POINTER=y | 174 | CONFIG_FRAME_POINTER=y |
171 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
diff --git a/arch/avr32/configs/atstk1002_defconfig b/arch/avr32/configs/atstk1002_defconfig index aec4c43a75da..4fb01f5ab42f 100644 --- a/arch/avr32/configs/atstk1002_defconfig +++ b/arch/avr32/configs/atstk1002_defconfig | |||
@@ -3,7 +3,6 @@ CONFIG_EXPERIMENTAL=y | |||
3 | CONFIG_SYSVIPC=y | 3 | CONFIG_SYSVIPC=y |
4 | CONFIG_POSIX_MQUEUE=y | 4 | CONFIG_POSIX_MQUEUE=y |
5 | CONFIG_LOG_BUF_SHIFT=14 | 5 | CONFIG_LOG_BUF_SHIFT=14 |
6 | CONFIG_SYSFS_DEPRECATED_V2=y | ||
7 | CONFIG_RELAY=y | 6 | CONFIG_RELAY=y |
8 | CONFIG_BLK_DEV_INITRD=y | 7 | CONFIG_BLK_DEV_INITRD=y |
9 | # CONFIG_SYSCTL_SYSCALL is not set | 8 | # CONFIG_SYSCTL_SYSCALL is not set |
@@ -11,7 +10,7 @@ CONFIG_BLK_DEV_INITRD=y | |||
11 | # CONFIG_COMPAT_BRK is not set | 10 | # CONFIG_COMPAT_BRK is not set |
12 | CONFIG_PROFILING=y | 11 | CONFIG_PROFILING=y |
13 | CONFIG_OPROFILE=m | 12 | CONFIG_OPROFILE=m |
14 | CONFIG_KPROBES=y | 13 | # CONFIG_KPROBES is not set |
15 | CONFIG_MODULES=y | 14 | CONFIG_MODULES=y |
16 | CONFIG_MODULE_UNLOAD=y | 15 | CONFIG_MODULE_UNLOAD=y |
17 | # CONFIG_BLK_DEV_BSG is not set | 16 | # CONFIG_BLK_DEV_BSG is not set |
@@ -26,6 +25,7 @@ CONFIG_CPU_FREQ=y | |||
26 | CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y | 25 | CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y |
27 | CONFIG_CPU_FREQ_GOV_USERSPACE=y | 26 | CONFIG_CPU_FREQ_GOV_USERSPACE=y |
28 | CONFIG_CPU_FREQ_AT32AP=y | 27 | CONFIG_CPU_FREQ_AT32AP=y |
28 | CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y | ||
29 | CONFIG_NET=y | 29 | CONFIG_NET=y |
30 | CONFIG_PACKET=y | 30 | CONFIG_PACKET=y |
31 | CONFIG_UNIX=y | 31 | CONFIG_UNIX=y |
@@ -35,6 +35,7 @@ CONFIG_INET=y | |||
35 | CONFIG_IP_PNP=y | 35 | CONFIG_IP_PNP=y |
36 | CONFIG_IP_PNP_DHCP=y | 36 | CONFIG_IP_PNP_DHCP=y |
37 | CONFIG_NET_IPIP=m | 37 | CONFIG_NET_IPIP=m |
38 | CONFIG_NET_IPGRE_DEMUX=m | ||
38 | CONFIG_NET_IPGRE=m | 39 | CONFIG_NET_IPGRE=m |
39 | CONFIG_INET_AH=m | 40 | CONFIG_INET_AH=m |
40 | CONFIG_INET_ESP=m | 41 | CONFIG_INET_ESP=m |
@@ -58,16 +59,14 @@ CONFIG_MTD_BLOCK=y | |||
58 | CONFIG_MTD_CFI=y | 59 | CONFIG_MTD_CFI=y |
59 | CONFIG_MTD_CFI_AMDSTD=y | 60 | CONFIG_MTD_CFI_AMDSTD=y |
60 | CONFIG_MTD_PHYSMAP=y | 61 | CONFIG_MTD_PHYSMAP=y |
61 | CONFIG_MTD_DATAFLASH=m | ||
62 | CONFIG_MTD_M25P80=m | ||
63 | CONFIG_MTD_UBI=y | 62 | CONFIG_MTD_UBI=y |
64 | CONFIG_BLK_DEV_LOOP=m | 63 | CONFIG_BLK_DEV_LOOP=m |
65 | CONFIG_BLK_DEV_NBD=m | 64 | CONFIG_BLK_DEV_NBD=m |
66 | CONFIG_BLK_DEV_RAM=m | 65 | CONFIG_BLK_DEV_RAM=m |
66 | CONFIG_MISC_DEVICES=y | ||
67 | CONFIG_ATMEL_PWM=m | 67 | CONFIG_ATMEL_PWM=m |
68 | CONFIG_ATMEL_TCLIB=y | 68 | CONFIG_ATMEL_TCLIB=y |
69 | CONFIG_ATMEL_SSC=m | 69 | CONFIG_ATMEL_SSC=m |
70 | CONFIG_EEPROM_AT24=m | ||
71 | # CONFIG_SCSI_PROC_FS is not set | 70 | # CONFIG_SCSI_PROC_FS is not set |
72 | CONFIG_BLK_DEV_SD=m | 71 | CONFIG_BLK_DEV_SD=m |
73 | CONFIG_BLK_DEV_SR=m | 72 | CONFIG_BLK_DEV_SR=m |
@@ -120,7 +119,6 @@ CONFIG_SND_MIXER_OSS=m | |||
120 | CONFIG_SND_PCM_OSS=m | 119 | CONFIG_SND_PCM_OSS=m |
121 | # CONFIG_SND_SUPPORT_OLD_API is not set | 120 | # CONFIG_SND_SUPPORT_OLD_API is not set |
122 | # CONFIG_SND_VERBOSE_PROCFS is not set | 121 | # CONFIG_SND_VERBOSE_PROCFS is not set |
123 | # CONFIG_SND_DRIVERS is not set | ||
124 | CONFIG_SND_AT73C213=m | 122 | CONFIG_SND_AT73C213=m |
125 | # CONFIG_HID_SUPPORT is not set | 123 | # CONFIG_HID_SUPPORT is not set |
126 | CONFIG_USB_GADGET=y | 124 | CONFIG_USB_GADGET=y |
@@ -131,16 +129,15 @@ CONFIG_USB_FILE_STORAGE=m | |||
131 | CONFIG_USB_G_SERIAL=m | 129 | CONFIG_USB_G_SERIAL=m |
132 | CONFIG_USB_CDC_COMPOSITE=m | 130 | CONFIG_USB_CDC_COMPOSITE=m |
133 | CONFIG_MMC=y | 131 | CONFIG_MMC=y |
132 | CONFIG_MMC_TEST=m | ||
134 | CONFIG_MMC_ATMELMCI=y | 133 | CONFIG_MMC_ATMELMCI=y |
135 | CONFIG_MMC_SPI=m | ||
136 | CONFIG_NEW_LEDS=y | 134 | CONFIG_NEW_LEDS=y |
137 | CONFIG_LEDS_CLASS=m | 135 | CONFIG_LEDS_CLASS=y |
138 | CONFIG_LEDS_ATMEL_PWM=m | 136 | CONFIG_LEDS_ATMEL_PWM=m |
139 | CONFIG_LEDS_GPIO=m | 137 | CONFIG_LEDS_GPIO=m |
140 | CONFIG_LEDS_TRIGGERS=y | 138 | CONFIG_LEDS_TRIGGERS=y |
141 | CONFIG_LEDS_TRIGGER_TIMER=m | 139 | CONFIG_LEDS_TRIGGER_TIMER=m |
142 | CONFIG_LEDS_TRIGGER_HEARTBEAT=m | 140 | CONFIG_LEDS_TRIGGER_HEARTBEAT=m |
143 | CONFIG_LEDS_TRIGGER_DEFAULT_ON=m | ||
144 | CONFIG_RTC_CLASS=y | 141 | CONFIG_RTC_CLASS=y |
145 | CONFIG_RTC_DRV_AT32AP700X=y | 142 | CONFIG_RTC_DRV_AT32AP700X=y |
146 | CONFIG_DMADEVICES=y | 143 | CONFIG_DMADEVICES=y |
@@ -149,20 +146,23 @@ CONFIG_EXT3_FS=y | |||
149 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | 146 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set |
150 | # CONFIG_EXT3_FS_XATTR is not set | 147 | # CONFIG_EXT3_FS_XATTR is not set |
151 | CONFIG_EXT4_FS=y | 148 | CONFIG_EXT4_FS=y |
149 | # CONFIG_EXT4_FS_XATTR is not set | ||
152 | # CONFIG_DNOTIFY is not set | 150 | # CONFIG_DNOTIFY is not set |
153 | CONFIG_FUSE_FS=m | 151 | CONFIG_FUSE_FS=m |
154 | CONFIG_MSDOS_FS=m | 152 | CONFIG_MSDOS_FS=m |
155 | CONFIG_VFAT_FS=m | 153 | CONFIG_VFAT_FS=m |
154 | CONFIG_FAT_DEFAULT_CODEPAGE=850 | ||
156 | CONFIG_PROC_KCORE=y | 155 | CONFIG_PROC_KCORE=y |
157 | CONFIG_TMPFS=y | 156 | CONFIG_TMPFS=y |
157 | CONFIG_CONFIGFS_FS=y | ||
158 | CONFIG_JFFS2_FS=y | 158 | CONFIG_JFFS2_FS=y |
159 | # CONFIG_JFFS2_FS_WRITEBUFFER is not set | ||
160 | CONFIG_UBIFS_FS=y | 159 | CONFIG_UBIFS_FS=y |
161 | CONFIG_MINIX_FS=m | ||
162 | CONFIG_NFS_FS=y | 160 | CONFIG_NFS_FS=y |
163 | CONFIG_NFS_V3=y | 161 | CONFIG_NFS_V3=y |
164 | CONFIG_ROOT_NFS=y | 162 | CONFIG_ROOT_NFS=y |
163 | CONFIG_CIFS=m | ||
165 | CONFIG_NLS_CODEPAGE_437=m | 164 | CONFIG_NLS_CODEPAGE_437=m |
165 | CONFIG_NLS_CODEPAGE_850=m | ||
166 | CONFIG_NLS_ISO8859_1=m | 166 | CONFIG_NLS_ISO8859_1=m |
167 | CONFIG_NLS_UTF8=m | 167 | CONFIG_NLS_UTF8=m |
168 | CONFIG_MAGIC_SYSRQ=y | 168 | CONFIG_MAGIC_SYSRQ=y |
@@ -170,6 +170,3 @@ CONFIG_DEBUG_FS=y | |||
170 | CONFIG_DEBUG_KERNEL=y | 170 | CONFIG_DEBUG_KERNEL=y |
171 | CONFIG_DETECT_HUNG_TASK=y | 171 | CONFIG_DETECT_HUNG_TASK=y |
172 | CONFIG_FRAME_POINTER=y | 172 | CONFIG_FRAME_POINTER=y |
173 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
174 | # CONFIG_CRYPTO_HW is not set | ||
175 | CONFIG_CRC_T10DIF=m | ||
diff --git a/arch/avr32/configs/atstk1003_defconfig b/arch/avr32/configs/atstk1003_defconfig index 50ba3db682ca..9faaf9b900f2 100644 --- a/arch/avr32/configs/atstk1003_defconfig +++ b/arch/avr32/configs/atstk1003_defconfig | |||
@@ -2,22 +2,15 @@ CONFIG_EXPERIMENTAL=y | |||
2 | # CONFIG_LOCALVERSION_AUTO is not set | 2 | # CONFIG_LOCALVERSION_AUTO is not set |
3 | CONFIG_SYSVIPC=y | 3 | CONFIG_SYSVIPC=y |
4 | CONFIG_POSIX_MQUEUE=y | 4 | CONFIG_POSIX_MQUEUE=y |
5 | CONFIG_BSD_PROCESS_ACCT=y | ||
6 | CONFIG_BSD_PROCESS_ACCT_V3=y | ||
7 | CONFIG_TASKSTATS=y | ||
8 | CONFIG_TASK_DELAY_ACCT=y | ||
9 | CONFIG_AUDIT=y | ||
10 | CONFIG_LOG_BUF_SHIFT=14 | 5 | CONFIG_LOG_BUF_SHIFT=14 |
11 | CONFIG_SYSFS_DEPRECATED_V2=y | ||
12 | CONFIG_RELAY=y | 6 | CONFIG_RELAY=y |
13 | CONFIG_BLK_DEV_INITRD=y | 7 | CONFIG_BLK_DEV_INITRD=y |
14 | # CONFIG_SYSCTL_SYSCALL is not set | 8 | # CONFIG_SYSCTL_SYSCALL is not set |
15 | # CONFIG_BASE_FULL is not set | 9 | # CONFIG_BASE_FULL is not set |
16 | # CONFIG_SLUB_DEBUG is not set | ||
17 | # CONFIG_COMPAT_BRK is not set | 10 | # CONFIG_COMPAT_BRK is not set |
18 | CONFIG_PROFILING=y | 11 | CONFIG_PROFILING=y |
19 | CONFIG_OPROFILE=m | 12 | CONFIG_OPROFILE=m |
20 | CONFIG_KPROBES=y | 13 | # CONFIG_KPROBES is not set |
21 | CONFIG_MODULES=y | 14 | CONFIG_MODULES=y |
22 | CONFIG_MODULE_UNLOAD=y | 15 | CONFIG_MODULE_UNLOAD=y |
23 | # CONFIG_BLK_DEV_BSG is not set | 16 | # CONFIG_BLK_DEV_BSG is not set |
@@ -33,6 +26,7 @@ CONFIG_CPU_FREQ=y | |||
33 | CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y | 26 | CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y |
34 | CONFIG_CPU_FREQ_GOV_USERSPACE=y | 27 | CONFIG_CPU_FREQ_GOV_USERSPACE=y |
35 | CONFIG_CPU_FREQ_AT32AP=y | 28 | CONFIG_CPU_FREQ_AT32AP=y |
29 | CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y | ||
36 | CONFIG_NET=y | 30 | CONFIG_NET=y |
37 | CONFIG_PACKET=y | 31 | CONFIG_PACKET=y |
38 | CONFIG_UNIX=y | 32 | CONFIG_UNIX=y |
@@ -54,18 +48,18 @@ CONFIG_MTD_BLOCK=y | |||
54 | CONFIG_MTD_CFI=y | 48 | CONFIG_MTD_CFI=y |
55 | CONFIG_MTD_CFI_AMDSTD=y | 49 | CONFIG_MTD_CFI_AMDSTD=y |
56 | CONFIG_MTD_PHYSMAP=y | 50 | CONFIG_MTD_PHYSMAP=y |
57 | CONFIG_MTD_DATAFLASH=m | 51 | CONFIG_MTD_UBI=y |
58 | CONFIG_MTD_M25P80=m | ||
59 | CONFIG_BLK_DEV_LOOP=m | 52 | CONFIG_BLK_DEV_LOOP=m |
60 | CONFIG_BLK_DEV_NBD=m | 53 | CONFIG_BLK_DEV_NBD=m |
61 | CONFIG_BLK_DEV_RAM=m | 54 | CONFIG_BLK_DEV_RAM=m |
55 | CONFIG_MISC_DEVICES=y | ||
62 | CONFIG_ATMEL_PWM=m | 56 | CONFIG_ATMEL_PWM=m |
63 | CONFIG_ATMEL_TCLIB=y | 57 | CONFIG_ATMEL_TCLIB=y |
64 | CONFIG_ATMEL_SSC=m | 58 | CONFIG_ATMEL_SSC=m |
65 | CONFIG_EEPROM_AT24=m | ||
66 | # CONFIG_SCSI_PROC_FS is not set | 59 | # CONFIG_SCSI_PROC_FS is not set |
67 | CONFIG_BLK_DEV_SD=m | 60 | CONFIG_BLK_DEV_SD=m |
68 | CONFIG_BLK_DEV_SR=m | 61 | CONFIG_BLK_DEV_SR=m |
62 | # CONFIG_SCSI_LOWLEVEL is not set | ||
69 | CONFIG_ATA=m | 63 | CONFIG_ATA=m |
70 | # CONFIG_SATA_PMP is not set | 64 | # CONFIG_SATA_PMP is not set |
71 | CONFIG_PATA_AT32=m | 65 | CONFIG_PATA_AT32=m |
@@ -77,6 +71,7 @@ CONFIG_PPP_ASYNC=m | |||
77 | CONFIG_PPP_DEFLATE=m | 71 | CONFIG_PPP_DEFLATE=m |
78 | CONFIG_PPP_BSDCOMP=m | 72 | CONFIG_PPP_BSDCOMP=m |
79 | CONFIG_INPUT=m | 73 | CONFIG_INPUT=m |
74 | CONFIG_INPUT_EVDEV=m | ||
80 | # CONFIG_KEYBOARD_ATKBD is not set | 75 | # CONFIG_KEYBOARD_ATKBD is not set |
81 | CONFIG_KEYBOARD_GPIO=m | 76 | CONFIG_KEYBOARD_GPIO=m |
82 | # CONFIG_MOUSE_PS2 is not set | 77 | # CONFIG_MOUSE_PS2 is not set |
@@ -106,7 +101,6 @@ CONFIG_SND_PCM_OSS=m | |||
106 | CONFIG_SND_AT73C213=m | 101 | CONFIG_SND_AT73C213=m |
107 | # CONFIG_HID_SUPPORT is not set | 102 | # CONFIG_HID_SUPPORT is not set |
108 | CONFIG_USB_GADGET=y | 103 | CONFIG_USB_GADGET=y |
109 | CONFIG_USB_GADGET_DEBUG_FS=y | ||
110 | CONFIG_USB_ZERO=m | 104 | CONFIG_USB_ZERO=m |
111 | CONFIG_USB_ETH=m | 105 | CONFIG_USB_ETH=m |
112 | CONFIG_USB_GADGETFS=m | 106 | CONFIG_USB_GADGETFS=m |
@@ -116,36 +110,39 @@ CONFIG_USB_CDC_COMPOSITE=m | |||
116 | CONFIG_MMC=y | 110 | CONFIG_MMC=y |
117 | CONFIG_MMC_TEST=m | 111 | CONFIG_MMC_TEST=m |
118 | CONFIG_MMC_ATMELMCI=y | 112 | CONFIG_MMC_ATMELMCI=y |
119 | CONFIG_MMC_SPI=m | ||
120 | CONFIG_NEW_LEDS=y | 113 | CONFIG_NEW_LEDS=y |
121 | CONFIG_LEDS_CLASS=y | 114 | CONFIG_LEDS_CLASS=y |
122 | CONFIG_LEDS_ATMEL_PWM=m | 115 | CONFIG_LEDS_ATMEL_PWM=m |
123 | CONFIG_LEDS_GPIO=y | 116 | CONFIG_LEDS_GPIO=m |
124 | CONFIG_LEDS_TRIGGERS=y | 117 | CONFIG_LEDS_TRIGGERS=y |
125 | CONFIG_LEDS_TRIGGER_TIMER=y | 118 | CONFIG_LEDS_TRIGGER_TIMER=m |
126 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y | 119 | CONFIG_LEDS_TRIGGER_HEARTBEAT=m |
127 | CONFIG_LEDS_TRIGGER_DEFAULT_ON=y | ||
128 | CONFIG_RTC_CLASS=y | 120 | CONFIG_RTC_CLASS=y |
129 | CONFIG_RTC_DRV_AT32AP700X=y | 121 | CONFIG_RTC_DRV_AT32AP700X=y |
130 | CONFIG_DMADEVICES=y | 122 | CONFIG_DMADEVICES=y |
131 | CONFIG_DW_DMAC=y | 123 | CONFIG_EXT2_FS=y |
132 | CONFIG_EXT2_FS=m | 124 | CONFIG_EXT3_FS=y |
133 | CONFIG_EXT3_FS=m | 125 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set |
134 | # CONFIG_EXT3_FS_XATTR is not set | 126 | # CONFIG_EXT3_FS_XATTR is not set |
127 | CONFIG_EXT4_FS=y | ||
128 | # CONFIG_EXT4_FS_XATTR is not set | ||
135 | # CONFIG_DNOTIFY is not set | 129 | # CONFIG_DNOTIFY is not set |
136 | CONFIG_FUSE_FS=m | 130 | CONFIG_FUSE_FS=m |
137 | CONFIG_MSDOS_FS=m | 131 | CONFIG_MSDOS_FS=m |
138 | CONFIG_VFAT_FS=m | 132 | CONFIG_VFAT_FS=m |
133 | CONFIG_FAT_DEFAULT_CODEPAGE=850 | ||
139 | CONFIG_PROC_KCORE=y | 134 | CONFIG_PROC_KCORE=y |
140 | CONFIG_TMPFS=y | 135 | CONFIG_TMPFS=y |
141 | CONFIG_CONFIGFS_FS=m | 136 | CONFIG_CONFIGFS_FS=y |
142 | CONFIG_JFFS2_FS=y | 137 | CONFIG_JFFS2_FS=y |
138 | CONFIG_UBIFS_FS=y | ||
143 | # CONFIG_NETWORK_FILESYSTEMS is not set | 139 | # CONFIG_NETWORK_FILESYSTEMS is not set |
144 | CONFIG_NLS_CODEPAGE_437=m | 140 | CONFIG_NLS_CODEPAGE_437=m |
141 | CONFIG_NLS_CODEPAGE_850=m | ||
145 | CONFIG_NLS_ISO8859_1=m | 142 | CONFIG_NLS_ISO8859_1=m |
146 | CONFIG_NLS_UTF8=m | 143 | CONFIG_NLS_UTF8=m |
147 | CONFIG_MAGIC_SYSRQ=y | 144 | CONFIG_MAGIC_SYSRQ=y |
148 | CONFIG_DEBUG_FS=y | 145 | CONFIG_DEBUG_FS=y |
149 | CONFIG_DEBUG_KERNEL=y | 146 | CONFIG_DEBUG_KERNEL=y |
147 | CONFIG_DETECT_HUNG_TASK=y | ||
150 | CONFIG_FRAME_POINTER=y | 148 | CONFIG_FRAME_POINTER=y |
151 | CONFIG_CRC_T10DIF=m | ||
diff --git a/arch/avr32/configs/atstk1004_defconfig b/arch/avr32/configs/atstk1004_defconfig index 329e10ba3b54..3d2a5d85f970 100644 --- a/arch/avr32/configs/atstk1004_defconfig +++ b/arch/avr32/configs/atstk1004_defconfig | |||
@@ -1,19 +1,32 @@ | |||
1 | CONFIG_EXPERIMENTAL=y | 1 | CONFIG_EXPERIMENTAL=y |
2 | # CONFIG_LOCALVERSION_AUTO is not set | 2 | # CONFIG_LOCALVERSION_AUTO is not set |
3 | CONFIG_SYSVIPC=y | ||
4 | CONFIG_POSIX_MQUEUE=y | ||
3 | CONFIG_LOG_BUF_SHIFT=14 | 5 | CONFIG_LOG_BUF_SHIFT=14 |
4 | CONFIG_SYSFS_DEPRECATED_V2=y | 6 | CONFIG_RELAY=y |
7 | CONFIG_BLK_DEV_INITRD=y | ||
5 | # CONFIG_SYSCTL_SYSCALL is not set | 8 | # CONFIG_SYSCTL_SYSCALL is not set |
6 | # CONFIG_BASE_FULL is not set | 9 | # CONFIG_BASE_FULL is not set |
7 | # CONFIG_FUTEX is not set | ||
8 | # CONFIG_EPOLL is not set | ||
9 | # CONFIG_SIGNALFD is not set | ||
10 | # CONFIG_TIMERFD is not set | ||
11 | # CONFIG_EVENTFD is not set | ||
12 | # CONFIG_COMPAT_BRK is not set | 10 | # CONFIG_COMPAT_BRK is not set |
13 | CONFIG_SLOB=y | 11 | CONFIG_PROFILING=y |
14 | # CONFIG_BLOCK is not set | 12 | CONFIG_OPROFILE=m |
13 | # CONFIG_KPROBES is not set | ||
14 | CONFIG_MODULES=y | ||
15 | CONFIG_MODULE_UNLOAD=y | ||
16 | # CONFIG_BLK_DEV_BSG is not set | ||
17 | # CONFIG_IOSCHED_DEADLINE is not set | ||
18 | CONFIG_NO_HZ=y | ||
19 | CONFIG_HIGH_RES_TIMERS=y | ||
15 | CONFIG_BOARD_ATSTK1004=y | 20 | CONFIG_BOARD_ATSTK1004=y |
16 | # CONFIG_OWNERSHIP_TRACE is not set | 21 | # CONFIG_OWNERSHIP_TRACE is not set |
22 | CONFIG_NMI_DEBUGGING=y | ||
23 | CONFIG_PM=y | ||
24 | CONFIG_CPU_FREQ=y | ||
25 | # CONFIG_CPU_FREQ_STAT is not set | ||
26 | CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y | ||
27 | CONFIG_CPU_FREQ_GOV_USERSPACE=y | ||
28 | CONFIG_CPU_FREQ_AT32AP=y | ||
29 | CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y | ||
17 | CONFIG_NET=y | 30 | CONFIG_NET=y |
18 | CONFIG_PACKET=y | 31 | CONFIG_PACKET=y |
19 | CONFIG_UNIX=y | 32 | CONFIG_UNIX=y |
@@ -31,40 +44,104 @@ CONFIG_MTD=y | |||
31 | CONFIG_MTD_PARTITIONS=y | 44 | CONFIG_MTD_PARTITIONS=y |
32 | CONFIG_MTD_CMDLINE_PARTS=y | 45 | CONFIG_MTD_CMDLINE_PARTS=y |
33 | CONFIG_MTD_CHAR=y | 46 | CONFIG_MTD_CHAR=y |
47 | CONFIG_MTD_BLOCK=y | ||
34 | CONFIG_MTD_CFI=y | 48 | CONFIG_MTD_CFI=y |
35 | CONFIG_MTD_CFI_AMDSTD=y | 49 | CONFIG_MTD_CFI_AMDSTD=y |
36 | CONFIG_MTD_PHYSMAP=y | 50 | CONFIG_MTD_PHYSMAP=y |
37 | # CONFIG_MISC_DEVICES is not set | 51 | CONFIG_MTD_UBI=y |
38 | # CONFIG_INPUT is not set | 52 | CONFIG_BLK_DEV_LOOP=m |
53 | CONFIG_BLK_DEV_NBD=m | ||
54 | CONFIG_BLK_DEV_RAM=m | ||
55 | CONFIG_MISC_DEVICES=y | ||
56 | CONFIG_ATMEL_PWM=m | ||
57 | CONFIG_ATMEL_TCLIB=y | ||
58 | CONFIG_ATMEL_SSC=m | ||
59 | # CONFIG_SCSI_PROC_FS is not set | ||
60 | CONFIG_BLK_DEV_SD=m | ||
61 | CONFIG_BLK_DEV_SR=m | ||
62 | # CONFIG_SCSI_LOWLEVEL is not set | ||
63 | CONFIG_ATA=m | ||
64 | # CONFIG_SATA_PMP is not set | ||
65 | CONFIG_PATA_AT32=m | ||
66 | CONFIG_NETDEVICES=y | ||
67 | # CONFIG_NETDEV_1000 is not set | ||
68 | # CONFIG_NETDEV_10000 is not set | ||
69 | CONFIG_PPP=m | ||
70 | CONFIG_PPP_ASYNC=m | ||
71 | CONFIG_PPP_DEFLATE=m | ||
72 | CONFIG_PPP_BSDCOMP=m | ||
73 | CONFIG_INPUT=m | ||
74 | CONFIG_INPUT_EVDEV=m | ||
75 | # CONFIG_KEYBOARD_ATKBD is not set | ||
76 | CONFIG_KEYBOARD_GPIO=m | ||
77 | # CONFIG_MOUSE_PS2 is not set | ||
78 | CONFIG_MOUSE_GPIO=m | ||
39 | # CONFIG_SERIO is not set | 79 | # CONFIG_SERIO is not set |
40 | # CONFIG_VT is not set | 80 | # CONFIG_VT is not set |
41 | # CONFIG_DEVKMEM is not set | 81 | # CONFIG_DEVKMEM is not set |
42 | CONFIG_SERIAL_ATMEL=y | 82 | CONFIG_SERIAL_ATMEL=y |
43 | CONFIG_SERIAL_ATMEL_CONSOLE=y | 83 | CONFIG_SERIAL_ATMEL_CONSOLE=y |
44 | # CONFIG_SERIAL_ATMEL_PDC is not set | ||
45 | # CONFIG_LEGACY_PTYS is not set | 84 | # CONFIG_LEGACY_PTYS is not set |
46 | # CONFIG_HW_RANDOM is not set | 85 | # CONFIG_HW_RANDOM is not set |
86 | CONFIG_I2C=m | ||
87 | CONFIG_I2C_CHARDEV=m | ||
88 | CONFIG_I2C_GPIO=m | ||
47 | CONFIG_SPI=y | 89 | CONFIG_SPI=y |
48 | CONFIG_SPI_ATMEL=y | 90 | CONFIG_SPI_ATMEL=y |
91 | CONFIG_SPI_SPIDEV=m | ||
92 | CONFIG_GPIO_SYSFS=y | ||
49 | # CONFIG_HWMON is not set | 93 | # CONFIG_HWMON is not set |
50 | CONFIG_WATCHDOG=y | 94 | CONFIG_WATCHDOG=y |
51 | CONFIG_AT32AP700X_WDT=y | 95 | CONFIG_AT32AP700X_WDT=y |
52 | CONFIG_FB=y | 96 | CONFIG_FB=y |
53 | CONFIG_FB_ATMEL=y | 97 | CONFIG_FB_ATMEL=y |
54 | CONFIG_BACKLIGHT_LCD_SUPPORT=y | 98 | CONFIG_BACKLIGHT_LCD_SUPPORT=y |
99 | CONFIG_LCD_CLASS_DEVICE=y | ||
55 | CONFIG_LCD_LTV350QV=y | 100 | CONFIG_LCD_LTV350QV=y |
56 | # CONFIG_BACKLIGHT_CLASS_DEVICE is not set | 101 | # CONFIG_BACKLIGHT_CLASS_DEVICE is not set |
57 | CONFIG_USB_GADGET=y | 102 | CONFIG_USB_GADGET=y |
58 | CONFIG_USB_ETH=y | 103 | CONFIG_USB_ZERO=m |
59 | # CONFIG_USB_ETH_RNDIS is not set | 104 | CONFIG_USB_ETH=m |
105 | CONFIG_USB_GADGETFS=m | ||
106 | CONFIG_USB_FILE_STORAGE=m | ||
107 | CONFIG_USB_G_SERIAL=m | ||
108 | CONFIG_USB_CDC_COMPOSITE=m | ||
109 | CONFIG_MMC=y | ||
110 | CONFIG_MMC_TEST=m | ||
111 | CONFIG_MMC_ATMELMCI=y | ||
112 | CONFIG_NEW_LEDS=y | ||
113 | CONFIG_LEDS_CLASS=y | ||
114 | CONFIG_LEDS_ATMEL_PWM=m | ||
115 | CONFIG_LEDS_GPIO=m | ||
116 | CONFIG_LEDS_TRIGGERS=y | ||
117 | CONFIG_LEDS_TRIGGER_TIMER=m | ||
118 | CONFIG_LEDS_TRIGGER_HEARTBEAT=m | ||
60 | CONFIG_RTC_CLASS=y | 119 | CONFIG_RTC_CLASS=y |
61 | # CONFIG_RTC_INTF_PROC is not set | ||
62 | CONFIG_RTC_DRV_AT32AP700X=y | 120 | CONFIG_RTC_DRV_AT32AP700X=y |
121 | CONFIG_DMADEVICES=y | ||
122 | CONFIG_EXT2_FS=y | ||
123 | CONFIG_EXT3_FS=y | ||
124 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | ||
125 | # CONFIG_EXT3_FS_XATTR is not set | ||
126 | CONFIG_EXT4_FS=y | ||
127 | # CONFIG_EXT4_FS_XATTR is not set | ||
63 | # CONFIG_DNOTIFY is not set | 128 | # CONFIG_DNOTIFY is not set |
129 | CONFIG_FUSE_FS=m | ||
130 | CONFIG_MSDOS_FS=m | ||
131 | CONFIG_VFAT_FS=m | ||
132 | CONFIG_FAT_DEFAULT_CODEPAGE=850 | ||
64 | CONFIG_PROC_KCORE=y | 133 | CONFIG_PROC_KCORE=y |
65 | # CONFIG_PROC_PAGE_MONITOR is not set | ||
66 | CONFIG_TMPFS=y | 134 | CONFIG_TMPFS=y |
135 | CONFIG_CONFIGFS_FS=y | ||
67 | CONFIG_JFFS2_FS=y | 136 | CONFIG_JFFS2_FS=y |
68 | # CONFIG_JFFS2_FS_WRITEBUFFER is not set | 137 | CONFIG_UBIFS_FS=y |
69 | # CONFIG_NETWORK_FILESYSTEMS is not set | 138 | # CONFIG_NETWORK_FILESYSTEMS is not set |
139 | CONFIG_NLS_CODEPAGE_437=m | ||
140 | CONFIG_NLS_CODEPAGE_850=m | ||
141 | CONFIG_NLS_ISO8859_1=m | ||
142 | CONFIG_NLS_UTF8=m | ||
70 | CONFIG_MAGIC_SYSRQ=y | 143 | CONFIG_MAGIC_SYSRQ=y |
144 | CONFIG_DEBUG_FS=y | ||
145 | CONFIG_DEBUG_KERNEL=y | ||
146 | CONFIG_DETECT_HUNG_TASK=y | ||
147 | CONFIG_FRAME_POINTER=y | ||
diff --git a/arch/avr32/configs/atstk1006_defconfig b/arch/avr32/configs/atstk1006_defconfig index dbcc1b51e506..1ed8f22d4fe2 100644 --- a/arch/avr32/configs/atstk1006_defconfig +++ b/arch/avr32/configs/atstk1006_defconfig | |||
@@ -3,7 +3,6 @@ CONFIG_EXPERIMENTAL=y | |||
3 | CONFIG_SYSVIPC=y | 3 | CONFIG_SYSVIPC=y |
4 | CONFIG_POSIX_MQUEUE=y | 4 | CONFIG_POSIX_MQUEUE=y |
5 | CONFIG_LOG_BUF_SHIFT=14 | 5 | CONFIG_LOG_BUF_SHIFT=14 |
6 | CONFIG_SYSFS_DEPRECATED_V2=y | ||
7 | CONFIG_RELAY=y | 6 | CONFIG_RELAY=y |
8 | CONFIG_BLK_DEV_INITRD=y | 7 | CONFIG_BLK_DEV_INITRD=y |
9 | # CONFIG_SYSCTL_SYSCALL is not set | 8 | # CONFIG_SYSCTL_SYSCALL is not set |
@@ -11,7 +10,7 @@ CONFIG_BLK_DEV_INITRD=y | |||
11 | # CONFIG_COMPAT_BRK is not set | 10 | # CONFIG_COMPAT_BRK is not set |
12 | CONFIG_PROFILING=y | 11 | CONFIG_PROFILING=y |
13 | CONFIG_OPROFILE=m | 12 | CONFIG_OPROFILE=m |
14 | CONFIG_KPROBES=y | 13 | # CONFIG_KPROBES is not set |
15 | CONFIG_MODULES=y | 14 | CONFIG_MODULES=y |
16 | CONFIG_MODULE_UNLOAD=y | 15 | CONFIG_MODULE_UNLOAD=y |
17 | # CONFIG_BLK_DEV_BSG is not set | 16 | # CONFIG_BLK_DEV_BSG is not set |
@@ -37,6 +36,7 @@ CONFIG_INET=y | |||
37 | CONFIG_IP_PNP=y | 36 | CONFIG_IP_PNP=y |
38 | CONFIG_IP_PNP_DHCP=y | 37 | CONFIG_IP_PNP_DHCP=y |
39 | CONFIG_NET_IPIP=m | 38 | CONFIG_NET_IPIP=m |
39 | CONFIG_NET_IPGRE_DEMUX=m | ||
40 | CONFIG_NET_IPGRE=m | 40 | CONFIG_NET_IPGRE=m |
41 | CONFIG_INET_AH=m | 41 | CONFIG_INET_AH=m |
42 | CONFIG_INET_ESP=m | 42 | CONFIG_INET_ESP=m |
@@ -60,15 +60,13 @@ CONFIG_MTD_BLOCK=y | |||
60 | CONFIG_MTD_CFI=y | 60 | CONFIG_MTD_CFI=y |
61 | CONFIG_MTD_CFI_AMDSTD=y | 61 | CONFIG_MTD_CFI_AMDSTD=y |
62 | CONFIG_MTD_PHYSMAP=y | 62 | CONFIG_MTD_PHYSMAP=y |
63 | CONFIG_MTD_DATAFLASH=m | ||
64 | CONFIG_MTD_DATAFLASH_OTP=y | ||
65 | CONFIG_MTD_M25P80=m | ||
66 | CONFIG_MTD_NAND=y | 63 | CONFIG_MTD_NAND=y |
67 | CONFIG_MTD_NAND_ATMEL=y | 64 | CONFIG_MTD_NAND_ATMEL=y |
68 | CONFIG_MTD_UBI=y | 65 | CONFIG_MTD_UBI=y |
69 | CONFIG_BLK_DEV_LOOP=m | 66 | CONFIG_BLK_DEV_LOOP=m |
70 | CONFIG_BLK_DEV_NBD=m | 67 | CONFIG_BLK_DEV_NBD=m |
71 | CONFIG_BLK_DEV_RAM=m | 68 | CONFIG_BLK_DEV_RAM=m |
69 | CONFIG_MISC_DEVICES=y | ||
72 | CONFIG_ATMEL_PWM=m | 70 | CONFIG_ATMEL_PWM=m |
73 | CONFIG_ATMEL_TCLIB=y | 71 | CONFIG_ATMEL_TCLIB=y |
74 | CONFIG_ATMEL_SSC=m | 72 | CONFIG_ATMEL_SSC=m |
@@ -132,17 +130,17 @@ CONFIG_USB_ETH=m | |||
132 | CONFIG_USB_GADGETFS=m | 130 | CONFIG_USB_GADGETFS=m |
133 | CONFIG_USB_FILE_STORAGE=m | 131 | CONFIG_USB_FILE_STORAGE=m |
134 | CONFIG_USB_G_SERIAL=m | 132 | CONFIG_USB_G_SERIAL=m |
133 | CONFIG_USB_CDC_COMPOSITE=m | ||
135 | CONFIG_MMC=y | 134 | CONFIG_MMC=y |
135 | CONFIG_MMC_TEST=m | ||
136 | CONFIG_MMC_ATMELMCI=y | 136 | CONFIG_MMC_ATMELMCI=y |
137 | CONFIG_MMC_SPI=m | ||
138 | CONFIG_NEW_LEDS=y | 137 | CONFIG_NEW_LEDS=y |
139 | CONFIG_LEDS_CLASS=m | 138 | CONFIG_LEDS_CLASS=y |
140 | CONFIG_LEDS_ATMEL_PWM=m | 139 | CONFIG_LEDS_ATMEL_PWM=m |
141 | CONFIG_LEDS_GPIO=m | 140 | CONFIG_LEDS_GPIO=m |
142 | CONFIG_LEDS_TRIGGERS=y | 141 | CONFIG_LEDS_TRIGGERS=y |
143 | CONFIG_LEDS_TRIGGER_TIMER=m | 142 | CONFIG_LEDS_TRIGGER_TIMER=m |
144 | CONFIG_LEDS_TRIGGER_HEARTBEAT=m | 143 | CONFIG_LEDS_TRIGGER_HEARTBEAT=m |
145 | CONFIG_LEDS_TRIGGER_DEFAULT_ON=m | ||
146 | CONFIG_RTC_CLASS=y | 144 | CONFIG_RTC_CLASS=y |
147 | CONFIG_RTC_DRV_AT32AP700X=y | 145 | CONFIG_RTC_DRV_AT32AP700X=y |
148 | CONFIG_DMADEVICES=y | 146 | CONFIG_DMADEVICES=y |
@@ -156,15 +154,18 @@ CONFIG_EXT4_FS=y | |||
156 | CONFIG_FUSE_FS=m | 154 | CONFIG_FUSE_FS=m |
157 | CONFIG_MSDOS_FS=m | 155 | CONFIG_MSDOS_FS=m |
158 | CONFIG_VFAT_FS=m | 156 | CONFIG_VFAT_FS=m |
157 | CONFIG_FAT_DEFAULT_CODEPAGE=850 | ||
159 | CONFIG_PROC_KCORE=y | 158 | CONFIG_PROC_KCORE=y |
160 | CONFIG_TMPFS=y | 159 | CONFIG_TMPFS=y |
160 | CONFIG_CONFIGFS_FS=y | ||
161 | CONFIG_JFFS2_FS=y | 161 | CONFIG_JFFS2_FS=y |
162 | CONFIG_UBIFS_FS=y | 162 | CONFIG_UBIFS_FS=y |
163 | CONFIG_MINIX_FS=m | ||
164 | CONFIG_NFS_FS=y | 163 | CONFIG_NFS_FS=y |
165 | CONFIG_NFS_V3=y | 164 | CONFIG_NFS_V3=y |
166 | CONFIG_ROOT_NFS=y | 165 | CONFIG_ROOT_NFS=y |
166 | CONFIG_CIFS=m | ||
167 | CONFIG_NLS_CODEPAGE_437=m | 167 | CONFIG_NLS_CODEPAGE_437=m |
168 | CONFIG_NLS_CODEPAGE_850=m | ||
168 | CONFIG_NLS_ISO8859_1=m | 169 | CONFIG_NLS_ISO8859_1=m |
169 | CONFIG_NLS_UTF8=m | 170 | CONFIG_NLS_UTF8=m |
170 | CONFIG_MAGIC_SYSRQ=y | 171 | CONFIG_MAGIC_SYSRQ=y |
@@ -172,7 +173,3 @@ CONFIG_DEBUG_FS=y | |||
172 | CONFIG_DEBUG_KERNEL=y | 173 | CONFIG_DEBUG_KERNEL=y |
173 | CONFIG_DETECT_HUNG_TASK=y | 174 | CONFIG_DETECT_HUNG_TASK=y |
174 | CONFIG_FRAME_POINTER=y | 175 | CONFIG_FRAME_POINTER=y |
175 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
176 | CONFIG_CRYPTO_FIPS=y | ||
177 | # CONFIG_CRYPTO_HW is not set | ||
178 | CONFIG_CRC_T10DIF=m | ||
diff --git a/arch/avr32/configs/favr-32_defconfig b/arch/avr32/configs/favr-32_defconfig index 0c813b661a0a..aeadc955db32 100644 --- a/arch/avr32/configs/favr-32_defconfig +++ b/arch/avr32/configs/favr-32_defconfig | |||
@@ -11,7 +11,7 @@ CONFIG_BLK_DEV_INITRD=y | |||
11 | # CONFIG_COMPAT_BRK is not set | 11 | # CONFIG_COMPAT_BRK is not set |
12 | CONFIG_PROFILING=y | 12 | CONFIG_PROFILING=y |
13 | CONFIG_OPROFILE=m | 13 | CONFIG_OPROFILE=m |
14 | CONFIG_KPROBES=y | 14 | # CONFIG_KPROBES is not set |
15 | CONFIG_MODULES=y | 15 | CONFIG_MODULES=y |
16 | CONFIG_MODULE_UNLOAD=y | 16 | CONFIG_MODULE_UNLOAD=y |
17 | # CONFIG_BLK_DEV_BSG is not set | 17 | # CONFIG_BLK_DEV_BSG is not set |
diff --git a/arch/avr32/configs/hammerhead_defconfig b/arch/avr32/configs/hammerhead_defconfig index dcc01f0eb294..1692beeb7ed3 100644 --- a/arch/avr32/configs/hammerhead_defconfig +++ b/arch/avr32/configs/hammerhead_defconfig | |||
@@ -12,7 +12,7 @@ CONFIG_BLK_DEV_INITRD=y | |||
12 | # CONFIG_COMPAT_BRK is not set | 12 | # CONFIG_COMPAT_BRK is not set |
13 | CONFIG_PROFILING=y | 13 | CONFIG_PROFILING=y |
14 | CONFIG_OPROFILE=m | 14 | CONFIG_OPROFILE=m |
15 | CONFIG_KPROBES=y | 15 | # CONFIG_KPROBES is not set |
16 | CONFIG_MODULES=y | 16 | CONFIG_MODULES=y |
17 | CONFIG_MODULE_UNLOAD=y | 17 | CONFIG_MODULE_UNLOAD=y |
18 | CONFIG_MODULE_FORCE_UNLOAD=y | 18 | CONFIG_MODULE_FORCE_UNLOAD=y |
diff --git a/arch/avr32/include/asm/syscalls.h b/arch/avr32/include/asm/syscalls.h index ab608b70b24d..244f2acab546 100644 --- a/arch/avr32/include/asm/syscalls.h +++ b/arch/avr32/include/asm/syscalls.h | |||
@@ -15,20 +15,6 @@ | |||
15 | #include <linux/types.h> | 15 | #include <linux/types.h> |
16 | #include <linux/signal.h> | 16 | #include <linux/signal.h> |
17 | 17 | ||
18 | /* kernel/process.c */ | ||
19 | asmlinkage int sys_fork(struct pt_regs *); | ||
20 | asmlinkage int sys_clone(unsigned long, unsigned long, | ||
21 | unsigned long, unsigned long, | ||
22 | struct pt_regs *); | ||
23 | asmlinkage int sys_vfork(struct pt_regs *); | ||
24 | asmlinkage int sys_execve(const char __user *, char __user *__user *, | ||
25 | char __user *__user *, struct pt_regs *); | ||
26 | |||
27 | /* kernel/signal.c */ | ||
28 | asmlinkage int sys_sigaltstack(const stack_t __user *, stack_t __user *, | ||
29 | struct pt_regs *); | ||
30 | asmlinkage int sys_rt_sigreturn(struct pt_regs *); | ||
31 | |||
32 | /* mm/cache.c */ | 18 | /* mm/cache.c */ |
33 | asmlinkage int sys_cacheflush(int, void __user *, size_t); | 19 | asmlinkage int sys_cacheflush(int, void __user *, size_t); |
34 | 20 | ||
diff --git a/arch/avr32/kernel/process.c b/arch/avr32/kernel/process.c index 9c46aaad11ce..ef5a2a08fcca 100644 --- a/arch/avr32/kernel/process.c +++ b/arch/avr32/kernel/process.c | |||
@@ -367,14 +367,13 @@ asmlinkage int sys_fork(struct pt_regs *regs) | |||
367 | } | 367 | } |
368 | 368 | ||
369 | asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, | 369 | asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, |
370 | unsigned long parent_tidptr, | 370 | void __user *parent_tidptr, void __user *child_tidptr, |
371 | unsigned long child_tidptr, struct pt_regs *regs) | 371 | struct pt_regs *regs) |
372 | { | 372 | { |
373 | if (!newsp) | 373 | if (!newsp) |
374 | newsp = regs->sp; | 374 | newsp = regs->sp; |
375 | return do_fork(clone_flags, newsp, regs, 0, | 375 | return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, |
376 | (int __user *)parent_tidptr, | 376 | child_tidptr); |
377 | (int __user *)child_tidptr); | ||
378 | } | 377 | } |
379 | 378 | ||
380 | asmlinkage int sys_vfork(struct pt_regs *regs) | 379 | asmlinkage int sys_vfork(struct pt_regs *regs) |
diff --git a/arch/avr32/kernel/time.c b/arch/avr32/kernel/time.c index 668ed2817e51..05ad29112ff4 100644 --- a/arch/avr32/kernel/time.c +++ b/arch/avr32/kernel/time.c | |||
@@ -35,7 +35,6 @@ static struct clocksource counter = { | |||
35 | .rating = 50, | 35 | .rating = 50, |
36 | .read = read_cycle_count, | 36 | .read = read_cycle_count, |
37 | .mask = CLOCKSOURCE_MASK(32), | 37 | .mask = CLOCKSOURCE_MASK(32), |
38 | .shift = 16, | ||
39 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 38 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
40 | }; | 39 | }; |
41 | 40 | ||
@@ -123,9 +122,7 @@ void __init time_init(void) | |||
123 | 122 | ||
124 | /* figure rate for counter */ | 123 | /* figure rate for counter */ |
125 | counter_hz = clk_get_rate(boot_cpu_data.clk); | 124 | counter_hz = clk_get_rate(boot_cpu_data.clk); |
126 | counter.mult = clocksource_hz2mult(counter_hz, counter.shift); | 125 | ret = clocksource_register_hz(&counter, counter_hz); |
127 | |||
128 | ret = clocksource_register(&counter); | ||
129 | if (ret) | 126 | if (ret) |
130 | pr_debug("timer: could not register clocksource: %d\n", ret); | 127 | pr_debug("timer: could not register clocksource: %d\n", ret); |
131 | 128 | ||
diff --git a/arch/avr32/mach-at32ap/pm.c b/arch/avr32/mach-at32ap/pm.c index f021edfeaab0..32d680eb6f48 100644 --- a/arch/avr32/mach-at32ap/pm.c +++ b/arch/avr32/mach-at32ap/pm.c | |||
@@ -176,7 +176,7 @@ out: | |||
176 | return 0; | 176 | return 0; |
177 | } | 177 | } |
178 | 178 | ||
179 | static struct platform_suspend_ops avr32_pm_ops = { | 179 | static const struct platform_suspend_ops avr32_pm_ops = { |
180 | .valid = avr32_pm_valid_state, | 180 | .valid = avr32_pm_valid_state, |
181 | .enter = avr32_pm_enter, | 181 | .enter = avr32_pm_enter, |
182 | }; | 182 | }; |
diff --git a/arch/blackfin/mach-bf537/include/mach/defBF534.h b/arch/blackfin/mach-bf537/include/mach/defBF534.h index 32529a03b266..725bb35f3aaa 100644 --- a/arch/blackfin/mach-bf537/include/mach/defBF534.h +++ b/arch/blackfin/mach-bf537/include/mach/defBF534.h | |||
@@ -1418,7 +1418,7 @@ | |||
1418 | #define SADD_LEN 0x0002 /* Slave Address Length */ | 1418 | #define SADD_LEN 0x0002 /* Slave Address Length */ |
1419 | #define STDVAL 0x0004 /* Slave Transmit Data Valid */ | 1419 | #define STDVAL 0x0004 /* Slave Transmit Data Valid */ |
1420 | #define NAK 0x0008 /* NAK/ACK* Generated At Conclusion Of Transfer */ | 1420 | #define NAK 0x0008 /* NAK/ACK* Generated At Conclusion Of Transfer */ |
1421 | #define GEN 0x0010 /* General Call Adrress Matching Enabled */ | 1421 | #define GEN 0x0010 /* General Call Address Matching Enabled */ |
1422 | 1422 | ||
1423 | /* TWI_SLAVE_STAT Masks */ | 1423 | /* TWI_SLAVE_STAT Masks */ |
1424 | #define SDIR 0x0001 /* Slave Transfer Direction (Transmit/Receive*) */ | 1424 | #define SDIR 0x0001 /* Slave Transfer Direction (Transmit/Receive*) */ |
diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c index 42fa87e8375c..3c648a077e75 100644 --- a/arch/blackfin/mach-common/pm.c +++ b/arch/blackfin/mach-common/pm.c | |||
@@ -223,7 +223,7 @@ static int bfin_pm_enter(suspend_state_t state) | |||
223 | return 0; | 223 | return 0; |
224 | } | 224 | } |
225 | 225 | ||
226 | struct platform_suspend_ops bfin_pm_ops = { | 226 | static const struct platform_suspend_ops bfin_pm_ops = { |
227 | .enter = bfin_pm_enter, | 227 | .enter = bfin_pm_enter, |
228 | .valid = bfin_pm_valid, | 228 | .valid = bfin_pm_valid, |
229 | }; | 229 | }; |
diff --git a/arch/cris/arch-v32/lib/nand_init.S b/arch/cris/arch-v32/lib/nand_init.S index e705f5cce969..d671fed451c9 100644 --- a/arch/cris/arch-v32/lib/nand_init.S +++ b/arch/cris/arch-v32/lib/nand_init.S | |||
@@ -139,7 +139,7 @@ copy_nand_to_ram: | |||
139 | lsrq 8, $r4 | 139 | lsrq 8, $r4 |
140 | move.b $r4, [$r1] ; Row address | 140 | move.b $r4, [$r1] ; Row address |
141 | lsrq 8, $r4 | 141 | lsrq 8, $r4 |
142 | move.b $r4, [$r1] ; Row adddress | 142 | move.b $r4, [$r1] ; Row address |
143 | moveq 20, $r4 | 143 | moveq 20, $r4 |
144 | 2: bne 2b | 144 | 2: bne 2b |
145 | subq 1, $r4 | 145 | subq 1, $r4 |
diff --git a/arch/cris/include/asm/etraxgpio.h b/arch/cris/include/asm/etraxgpio.h index d474818a537e..461c089db765 100644 --- a/arch/cris/include/asm/etraxgpio.h +++ b/arch/cris/include/asm/etraxgpio.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * The following devices are accessable using this driver using | 2 | * The following devices are accessible using this driver using |
3 | * GPIO_MAJOR (120) and a couple of minor numbers. | 3 | * GPIO_MAJOR (120) and a couple of minor numbers. |
4 | * | 4 | * |
5 | * For ETRAX 100LX (CONFIG_ETRAX_ARCH_V10): | 5 | * For ETRAX 100LX (CONFIG_ETRAX_ARCH_V10): |
diff --git a/arch/cris/kernel/time.c b/arch/cris/kernel/time.c index b5096430ce1c..4e73092e85c0 100644 --- a/arch/cris/kernel/time.c +++ b/arch/cris/kernel/time.c | |||
@@ -86,7 +86,7 @@ int set_rtc_mmss(unsigned long nowtime) | |||
86 | CMOS_WRITE(real_seconds,RTC_SECONDS); | 86 | CMOS_WRITE(real_seconds,RTC_SECONDS); |
87 | CMOS_WRITE(real_minutes,RTC_MINUTES); | 87 | CMOS_WRITE(real_minutes,RTC_MINUTES); |
88 | } else { | 88 | } else { |
89 | printk(KERN_WARNING | 89 | printk_once(KERN_NOTICE |
90 | "set_rtc_mmss: can't update from %d to %d\n", | 90 | "set_rtc_mmss: can't update from %d to %d\n", |
91 | cmos_minutes, real_minutes); | 91 | cmos_minutes, real_minutes); |
92 | retval = -1; | 92 | retval = -1; |
diff --git a/arch/h8300/Kconfig.debug b/arch/h8300/Kconfig.debug index ee671c3f2c74..e8d1b236ad8c 100644 --- a/arch/h8300/Kconfig.debug +++ b/arch/h8300/Kconfig.debug | |||
@@ -48,7 +48,7 @@ config DEFAULT_CMDLINE | |||
48 | builtin kernel commandline enabled. | 48 | builtin kernel commandline enabled. |
49 | 49 | ||
50 | config KERNEL_COMMAND | 50 | config KERNEL_COMMAND |
51 | string "Buildin commmand string" | 51 | string "Buildin command string" |
52 | depends on DEFAULT_CMDLINE | 52 | depends on DEFAULT_CMDLINE |
53 | help | 53 | help |
54 | builtin kernel commandline strings. | 54 | builtin kernel commandline strings. |
diff --git a/arch/ia64/include/asm/io.h b/arch/ia64/include/asm/io.h index cc8335eb3110..e5a6c3530c6c 100644 --- a/arch/ia64/include/asm/io.h +++ b/arch/ia64/include/asm/io.h | |||
@@ -426,6 +426,11 @@ extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size) | |||
426 | extern void iounmap (volatile void __iomem *addr); | 426 | extern void iounmap (volatile void __iomem *addr); |
427 | extern void __iomem * early_ioremap (unsigned long phys_addr, unsigned long size); | 427 | extern void __iomem * early_ioremap (unsigned long phys_addr, unsigned long size); |
428 | extern void early_iounmap (volatile void __iomem *addr, unsigned long size); | 428 | extern void early_iounmap (volatile void __iomem *addr, unsigned long size); |
429 | static inline void __iomem * ioremap_cache (unsigned long phys_addr, unsigned long size) | ||
430 | { | ||
431 | return ioremap(phys_addr, size); | ||
432 | } | ||
433 | |||
429 | 434 | ||
430 | /* | 435 | /* |
431 | * String version of IO memory access ops: | 436 | * String version of IO memory access ops: |
diff --git a/arch/ia64/include/asm/kvm_host.h b/arch/ia64/include/asm/kvm_host.h index 2f229e5de498..2689ee54a1c9 100644 --- a/arch/ia64/include/asm/kvm_host.h +++ b/arch/ia64/include/asm/kvm_host.h | |||
@@ -590,6 +590,10 @@ int kvm_emulate_halt(struct kvm_vcpu *vcpu); | |||
590 | int kvm_pal_emul(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run); | 590 | int kvm_pal_emul(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run); |
591 | void kvm_sal_emul(struct kvm_vcpu *vcpu); | 591 | void kvm_sal_emul(struct kvm_vcpu *vcpu); |
592 | 592 | ||
593 | #define __KVM_HAVE_ARCH_VM_ALLOC 1 | ||
594 | struct kvm *kvm_arch_alloc_vm(void); | ||
595 | void kvm_arch_free_vm(struct kvm *kvm); | ||
596 | |||
593 | #endif /* __ASSEMBLY__*/ | 597 | #endif /* __ASSEMBLY__*/ |
594 | 598 | ||
595 | #endif | 599 | #endif |
diff --git a/arch/ia64/include/asm/processor.h b/arch/ia64/include/asm/processor.h index 348e44d08ce3..03afe7970748 100644 --- a/arch/ia64/include/asm/processor.h +++ b/arch/ia64/include/asm/processor.h | |||
@@ -717,8 +717,9 @@ prefetchw (const void *x) | |||
717 | #define spin_lock_prefetch(x) prefetchw(x) | 717 | #define spin_lock_prefetch(x) prefetchw(x) |
718 | 718 | ||
719 | extern unsigned long boot_option_idle_override; | 719 | extern unsigned long boot_option_idle_override; |
720 | extern unsigned long idle_halt; | 720 | |
721 | extern unsigned long idle_nomwait; | 721 | enum idle_boot_override {IDLE_NO_OVERRIDE=0, IDLE_HALT, IDLE_FORCE_MWAIT, |
722 | IDLE_NOMWAIT, IDLE_POLL}; | ||
722 | 723 | ||
723 | #endif /* !__ASSEMBLY__ */ | 724 | #endif /* !__ASSEMBLY__ */ |
724 | 725 | ||
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 7b897b7b0ae6..90ebceb899a0 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c | |||
@@ -479,7 +479,7 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa) | |||
479 | 479 | ||
480 | if (srat_num_cpus >= ARRAY_SIZE(node_cpuid)) { | 480 | if (srat_num_cpus >= ARRAY_SIZE(node_cpuid)) { |
481 | printk_once(KERN_WARNING | 481 | printk_once(KERN_WARNING |
482 | "node_cpuid[%d] is too small, may not be able to use all cpus\n", | 482 | "node_cpuid[%ld] is too small, may not be able to use all cpus\n", |
483 | ARRAY_SIZE(node_cpuid)); | 483 | ARRAY_SIZE(node_cpuid)); |
484 | return; | 484 | return; |
485 | } | 485 | } |
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index d92d5b5161fc..89accc626b86 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c | |||
@@ -617,11 +617,14 @@ pfm_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, | |||
617 | return get_unmapped_area(file, addr, len, pgoff, flags); | 617 | return get_unmapped_area(file, addr, len, pgoff, flags); |
618 | } | 618 | } |
619 | 619 | ||
620 | /* forward declaration */ | ||
621 | static const struct dentry_operations pfmfs_dentry_operations; | ||
620 | 622 | ||
621 | static struct dentry * | 623 | static struct dentry * |
622 | pfmfs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) | 624 | pfmfs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) |
623 | { | 625 | { |
624 | return mount_pseudo(fs_type, "pfm:", NULL, PFMFS_MAGIC); | 626 | return mount_pseudo(fs_type, "pfm:", NULL, &pfmfs_dentry_operations, |
627 | PFMFS_MAGIC); | ||
625 | } | 628 | } |
626 | 629 | ||
627 | static struct file_system_type pfm_fs_type = { | 630 | static struct file_system_type pfm_fs_type = { |
@@ -2232,7 +2235,6 @@ pfm_alloc_file(pfm_context_t *ctx) | |||
2232 | } | 2235 | } |
2233 | path.mnt = mntget(pfmfs_mnt); | 2236 | path.mnt = mntget(pfmfs_mnt); |
2234 | 2237 | ||
2235 | d_set_d_op(path.dentry, &pfmfs_dentry_operations); | ||
2236 | d_add(path.dentry, inode); | 2238 | d_add(path.dentry, inode); |
2237 | 2239 | ||
2238 | file = alloc_file(&path, FMODE_READ, &pfm_file_ops); | 2240 | file = alloc_file(&path, FMODE_READ, &pfm_file_ops); |
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index 16f1c7b04c69..6d33c5cc94f0 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c | |||
@@ -53,12 +53,8 @@ | |||
53 | 53 | ||
54 | void (*ia64_mark_idle)(int); | 54 | void (*ia64_mark_idle)(int); |
55 | 55 | ||
56 | unsigned long boot_option_idle_override = 0; | 56 | unsigned long boot_option_idle_override = IDLE_NO_OVERRIDE; |
57 | EXPORT_SYMBOL(boot_option_idle_override); | 57 | EXPORT_SYMBOL(boot_option_idle_override); |
58 | unsigned long idle_halt; | ||
59 | EXPORT_SYMBOL(idle_halt); | ||
60 | unsigned long idle_nomwait; | ||
61 | EXPORT_SYMBOL(idle_nomwait); | ||
62 | void (*pm_idle) (void); | 58 | void (*pm_idle) (void); |
63 | EXPORT_SYMBOL(pm_idle); | 59 | EXPORT_SYMBOL(pm_idle); |
64 | void (*pm_power_off) (void); | 60 | void (*pm_power_off) (void); |
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index f56a6316e134..70d224d4264c 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c | |||
@@ -749,7 +749,7 @@ out: | |||
749 | return r; | 749 | return r; |
750 | } | 750 | } |
751 | 751 | ||
752 | static struct kvm *kvm_alloc_kvm(void) | 752 | struct kvm *kvm_arch_alloc_vm(void) |
753 | { | 753 | { |
754 | 754 | ||
755 | struct kvm *kvm; | 755 | struct kvm *kvm; |
@@ -760,7 +760,7 @@ static struct kvm *kvm_alloc_kvm(void) | |||
760 | vm_base = __get_free_pages(GFP_KERNEL, get_order(KVM_VM_DATA_SIZE)); | 760 | vm_base = __get_free_pages(GFP_KERNEL, get_order(KVM_VM_DATA_SIZE)); |
761 | 761 | ||
762 | if (!vm_base) | 762 | if (!vm_base) |
763 | return ERR_PTR(-ENOMEM); | 763 | return NULL; |
764 | 764 | ||
765 | memset((void *)vm_base, 0, KVM_VM_DATA_SIZE); | 765 | memset((void *)vm_base, 0, KVM_VM_DATA_SIZE); |
766 | kvm = (struct kvm *)(vm_base + | 766 | kvm = (struct kvm *)(vm_base + |
@@ -806,10 +806,12 @@ static void kvm_build_io_pmt(struct kvm *kvm) | |||
806 | #define GUEST_PHYSICAL_RR4 0x2739 | 806 | #define GUEST_PHYSICAL_RR4 0x2739 |
807 | #define VMM_INIT_RR 0x1660 | 807 | #define VMM_INIT_RR 0x1660 |
808 | 808 | ||
809 | static void kvm_init_vm(struct kvm *kvm) | 809 | int kvm_arch_init_vm(struct kvm *kvm) |
810 | { | 810 | { |
811 | BUG_ON(!kvm); | 811 | BUG_ON(!kvm); |
812 | 812 | ||
813 | kvm->arch.is_sn2 = ia64_platform_is("sn2"); | ||
814 | |||
813 | kvm->arch.metaphysical_rr0 = GUEST_PHYSICAL_RR0; | 815 | kvm->arch.metaphysical_rr0 = GUEST_PHYSICAL_RR0; |
814 | kvm->arch.metaphysical_rr4 = GUEST_PHYSICAL_RR4; | 816 | kvm->arch.metaphysical_rr4 = GUEST_PHYSICAL_RR4; |
815 | kvm->arch.vmm_init_rr = VMM_INIT_RR; | 817 | kvm->arch.vmm_init_rr = VMM_INIT_RR; |
@@ -823,21 +825,8 @@ static void kvm_init_vm(struct kvm *kvm) | |||
823 | 825 | ||
824 | /* Reserve bit 0 of irq_sources_bitmap for userspace irq source */ | 826 | /* Reserve bit 0 of irq_sources_bitmap for userspace irq source */ |
825 | set_bit(KVM_USERSPACE_IRQ_SOURCE_ID, &kvm->arch.irq_sources_bitmap); | 827 | set_bit(KVM_USERSPACE_IRQ_SOURCE_ID, &kvm->arch.irq_sources_bitmap); |
826 | } | ||
827 | |||
828 | struct kvm *kvm_arch_create_vm(void) | ||
829 | { | ||
830 | struct kvm *kvm = kvm_alloc_kvm(); | ||
831 | |||
832 | if (IS_ERR(kvm)) | ||
833 | return ERR_PTR(-ENOMEM); | ||
834 | |||
835 | kvm->arch.is_sn2 = ia64_platform_is("sn2"); | ||
836 | |||
837 | kvm_init_vm(kvm); | ||
838 | |||
839 | return kvm; | ||
840 | 828 | ||
829 | return 0; | ||
841 | } | 830 | } |
842 | 831 | ||
843 | static int kvm_vm_ioctl_get_irqchip(struct kvm *kvm, | 832 | static int kvm_vm_ioctl_get_irqchip(struct kvm *kvm, |
@@ -962,7 +951,9 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
962 | goto out; | 951 | goto out; |
963 | r = kvm_setup_default_irq_routing(kvm); | 952 | r = kvm_setup_default_irq_routing(kvm); |
964 | if (r) { | 953 | if (r) { |
954 | mutex_lock(&kvm->slots_lock); | ||
965 | kvm_ioapic_destroy(kvm); | 955 | kvm_ioapic_destroy(kvm); |
956 | mutex_unlock(&kvm->slots_lock); | ||
966 | goto out; | 957 | goto out; |
967 | } | 958 | } |
968 | break; | 959 | break; |
@@ -1357,7 +1348,7 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, | |||
1357 | return -EINVAL; | 1348 | return -EINVAL; |
1358 | } | 1349 | } |
1359 | 1350 | ||
1360 | static void free_kvm(struct kvm *kvm) | 1351 | void kvm_arch_free_vm(struct kvm *kvm) |
1361 | { | 1352 | { |
1362 | unsigned long vm_base = kvm->arch.vm_base; | 1353 | unsigned long vm_base = kvm->arch.vm_base; |
1363 | 1354 | ||
@@ -1399,9 +1390,6 @@ void kvm_arch_destroy_vm(struct kvm *kvm) | |||
1399 | #endif | 1390 | #endif |
1400 | kfree(kvm->arch.vioapic); | 1391 | kfree(kvm->arch.vioapic); |
1401 | kvm_release_vm_pages(kvm); | 1392 | kvm_release_vm_pages(kvm); |
1402 | kvm_free_physmem(kvm); | ||
1403 | cleanup_srcu_struct(&kvm->srcu); | ||
1404 | free_kvm(kvm); | ||
1405 | } | 1393 | } |
1406 | 1394 | ||
1407 | void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) | 1395 | void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) |
diff --git a/arch/ia64/kvm/mmio.c b/arch/ia64/kvm/mmio.c index fb8f9f59a1ed..f1e17d3d6cd9 100644 --- a/arch/ia64/kvm/mmio.c +++ b/arch/ia64/kvm/mmio.c | |||
@@ -130,7 +130,7 @@ static void mmio_access(struct kvm_vcpu *vcpu, u64 src_pa, u64 *dest, | |||
130 | 130 | ||
131 | local_irq_save(psr); | 131 | local_irq_save(psr); |
132 | 132 | ||
133 | /*Intercept the acces for PIB range*/ | 133 | /*Intercept the access for PIB range*/ |
134 | if (iot == GPFN_PIB) { | 134 | if (iot == GPFN_PIB) { |
135 | if (!dir) | 135 | if (!dir) |
136 | lsapic_write(vcpu, src_pa, s, *dest); | 136 | lsapic_write(vcpu, src_pa, s, *dest); |
diff --git a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c index 1841ee7e65f9..5ca674b74737 100644 --- a/arch/ia64/mm/hugetlbpage.c +++ b/arch/ia64/mm/hugetlbpage.c | |||
@@ -38,7 +38,7 @@ huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz) | |||
38 | if (pud) { | 38 | if (pud) { |
39 | pmd = pmd_alloc(mm, pud, taddr); | 39 | pmd = pmd_alloc(mm, pud, taddr); |
40 | if (pmd) | 40 | if (pmd) |
41 | pte = pte_alloc_map(mm, pmd, taddr); | 41 | pte = pte_alloc_map(mm, NULL, pmd, taddr); |
42 | } | 42 | } |
43 | return pte; | 43 | return pte; |
44 | } | 44 | } |
diff --git a/arch/m68k/ifpsp060/src/fpsp.S b/arch/m68k/ifpsp060/src/fpsp.S index 73613b5f1ee5..26e85e2b7a5e 100644 --- a/arch/m68k/ifpsp060/src/fpsp.S +++ b/arch/m68k/ifpsp060/src/fpsp.S | |||
@@ -3881,7 +3881,7 @@ _fpsp_fline: | |||
3881 | # FP Unimplemented Instruction stack frame and jump to that entry | 3881 | # FP Unimplemented Instruction stack frame and jump to that entry |
3882 | # point. | 3882 | # point. |
3883 | # | 3883 | # |
3884 | # but, if the FPU is disabled, then we need to jump to the FPU diabled | 3884 | # but, if the FPU is disabled, then we need to jump to the FPU disabled |
3885 | # entry point. | 3885 | # entry point. |
3886 | movc %pcr,%d0 | 3886 | movc %pcr,%d0 |
3887 | btst &0x1,%d0 | 3887 | btst &0x1,%d0 |
diff --git a/arch/m68k/include/asm/m548xgpt.h b/arch/m68k/include/asm/m548xgpt.h index c8ef158a1c4e..33b2eef90f0a 100644 --- a/arch/m68k/include/asm/m548xgpt.h +++ b/arch/m68k/include/asm/m548xgpt.h | |||
@@ -59,11 +59,13 @@ | |||
59 | #define MCF_GPT_GMS_GPIO_INPUT (0x00000000) | 59 | #define MCF_GPT_GMS_GPIO_INPUT (0x00000000) |
60 | #define MCF_GPT_GMS_GPIO_OUTLO (0x00000020) | 60 | #define MCF_GPT_GMS_GPIO_OUTLO (0x00000020) |
61 | #define MCF_GPT_GMS_GPIO_OUTHI (0x00000030) | 61 | #define MCF_GPT_GMS_GPIO_OUTHI (0x00000030) |
62 | #define MCF_GPT_GMS_GPIO_MASK (0x00000030) | ||
62 | #define MCF_GPT_GMS_TMS_DISABLE (0x00000000) | 63 | #define MCF_GPT_GMS_TMS_DISABLE (0x00000000) |
63 | #define MCF_GPT_GMS_TMS_INCAPT (0x00000001) | 64 | #define MCF_GPT_GMS_TMS_INCAPT (0x00000001) |
64 | #define MCF_GPT_GMS_TMS_OUTCAPT (0x00000002) | 65 | #define MCF_GPT_GMS_TMS_OUTCAPT (0x00000002) |
65 | #define MCF_GPT_GMS_TMS_PWM (0x00000003) | 66 | #define MCF_GPT_GMS_TMS_PWM (0x00000003) |
66 | #define MCF_GPT_GMS_TMS_GPIO (0x00000004) | 67 | #define MCF_GPT_GMS_TMS_GPIO (0x00000004) |
68 | #define MCF_GPT_GMS_TMS_MASK (0x00000007) | ||
67 | 69 | ||
68 | /* Bit definitions and macros for MCF_GPT_GCIR */ | 70 | /* Bit definitions and macros for MCF_GPT_GCIR */ |
69 | #define MCF_GPT_GCIR_CNT(x) (((x)&0x0000FFFF)<<0) | 71 | #define MCF_GPT_GCIR_CNT(x) (((x)&0x0000FFFF)<<0) |
diff --git a/arch/m68k/mac/psc.c b/arch/m68k/mac/psc.c index ba6ccab64018..a4c3eb60706e 100644 --- a/arch/m68k/mac/psc.c +++ b/arch/m68k/mac/psc.c | |||
@@ -88,7 +88,7 @@ void __init psc_init(void) | |||
88 | 88 | ||
89 | /* | 89 | /* |
90 | * The PSC is always at the same spot, but using psc | 90 | * The PSC is always at the same spot, but using psc |
91 | * keeps things consisant with the psc_xxxx functions. | 91 | * keeps things consistent with the psc_xxxx functions. |
92 | */ | 92 | */ |
93 | 93 | ||
94 | psc = (void *) PSC_BASE; | 94 | psc = (void *) PSC_BASE; |
diff --git a/arch/mips/alchemy/common/power.c b/arch/mips/alchemy/common/power.c index e5916a516e58..647e518c90bc 100644 --- a/arch/mips/alchemy/common/power.c +++ b/arch/mips/alchemy/common/power.c | |||
@@ -130,7 +130,7 @@ static void restore_core_regs(void) | |||
130 | au_writel(sleep_usb[1], USBD_ENABLE); | 130 | au_writel(sleep_usb[1], USBD_ENABLE); |
131 | au_sync(); | 131 | au_sync(); |
132 | #else | 132 | #else |
133 | /* enable accces to OTG memory */ | 133 | /* enable access to OTG memory */ |
134 | au_writel(au_readl(USB_MSR_BASE + 4) | (1 << 6), USB_MSR_BASE + 4); | 134 | au_writel(au_readl(USB_MSR_BASE + 4) | (1 << 6), USB_MSR_BASE + 4); |
135 | au_sync(); | 135 | au_sync(); |
136 | 136 | ||
diff --git a/arch/mips/alchemy/devboards/pm.c b/arch/mips/alchemy/devboards/pm.c index 4bbd3133e451..acaf91b5e461 100644 --- a/arch/mips/alchemy/devboards/pm.c +++ b/arch/mips/alchemy/devboards/pm.c | |||
@@ -110,7 +110,7 @@ static void db1x_pm_end(void) | |||
110 | 110 | ||
111 | } | 111 | } |
112 | 112 | ||
113 | static struct platform_suspend_ops db1x_pm_ops = { | 113 | static const struct platform_suspend_ops db1x_pm_ops = { |
114 | .valid = suspend_valid_only_mem, | 114 | .valid = suspend_valid_only_mem, |
115 | .begin = db1x_pm_begin, | 115 | .begin = db1x_pm_begin, |
116 | .enter = db1x_pm_enter, | 116 | .enter = db1x_pm_enter, |
diff --git a/arch/mips/dec/time.c b/arch/mips/dec/time.c index 02f505f23c32..ea57f39e6736 100644 --- a/arch/mips/dec/time.c +++ b/arch/mips/dec/time.c | |||
@@ -104,7 +104,7 @@ int rtc_mips_set_mmss(unsigned long nowtime) | |||
104 | CMOS_WRITE(real_seconds, RTC_SECONDS); | 104 | CMOS_WRITE(real_seconds, RTC_SECONDS); |
105 | CMOS_WRITE(real_minutes, RTC_MINUTES); | 105 | CMOS_WRITE(real_minutes, RTC_MINUTES); |
106 | } else { | 106 | } else { |
107 | printk(KERN_WARNING | 107 | printk_once(KERN_NOTICE |
108 | "set_rtc_mmss: can't update from %d to %d\n", | 108 | "set_rtc_mmss: can't update from %d to %d\n", |
109 | cmos_minutes, real_minutes); | 109 | cmos_minutes, real_minutes); |
110 | retval = -1; | 110 | retval = -1; |
diff --git a/arch/mips/include/asm/mach-powertv/ioremap.h b/arch/mips/include/asm/mach-powertv/ioremap.h index 076f2eeaa575..c86ef094ec37 100644 --- a/arch/mips/include/asm/mach-powertv/ioremap.h +++ b/arch/mips/include/asm/mach-powertv/ioremap.h | |||
@@ -88,7 +88,7 @@ static inline dma_addr_t _dma_to_phys_offset_raw(dma_addr_t dma) | |||
88 | } | 88 | } |
89 | 89 | ||
90 | /* These are not portable and should not be used in drivers. Drivers should | 90 | /* These are not portable and should not be used in drivers. Drivers should |
91 | * be using ioremap() and friends to map physical addreses to virtual | 91 | * be using ioremap() and friends to map physical addresses to virtual |
92 | * addresses and dma_map*() and friends to map virtual addresses into DMA | 92 | * addresses and dma_map*() and friends to map virtual addresses into DMA |
93 | * addresses and back. | 93 | * addresses and back. |
94 | */ | 94 | */ |
diff --git a/arch/mips/include/asm/mc146818-time.h b/arch/mips/include/asm/mc146818-time.h index 199b45733a95..4a08dbe37db8 100644 --- a/arch/mips/include/asm/mc146818-time.h +++ b/arch/mips/include/asm/mc146818-time.h | |||
@@ -66,7 +66,7 @@ static inline int mc146818_set_rtc_mmss(unsigned long nowtime) | |||
66 | CMOS_WRITE(real_seconds, RTC_SECONDS); | 66 | CMOS_WRITE(real_seconds, RTC_SECONDS); |
67 | CMOS_WRITE(real_minutes, RTC_MINUTES); | 67 | CMOS_WRITE(real_minutes, RTC_MINUTES); |
68 | } else { | 68 | } else { |
69 | printk(KERN_WARNING | 69 | printk_once(KERN_NOTICE |
70 | "set_rtc_mmss: can't update from %d to %d\n", | 70 | "set_rtc_mmss: can't update from %d to %d\n", |
71 | cmos_minutes, real_minutes); | 71 | cmos_minutes, real_minutes); |
72 | retval = -1; | 72 | retval = -1; |
diff --git a/arch/mips/include/asm/mman.h b/arch/mips/include/asm/mman.h index c892bfb3e2c1..785b4ea4ec3f 100644 --- a/arch/mips/include/asm/mman.h +++ b/arch/mips/include/asm/mman.h | |||
@@ -77,6 +77,9 @@ | |||
77 | #define MADV_UNMERGEABLE 13 /* KSM may not merge identical pages */ | 77 | #define MADV_UNMERGEABLE 13 /* KSM may not merge identical pages */ |
78 | #define MADV_HWPOISON 100 /* poison a page for testing */ | 78 | #define MADV_HWPOISON 100 /* poison a page for testing */ |
79 | 79 | ||
80 | #define MADV_HUGEPAGE 14 /* Worth backing with hugepages */ | ||
81 | #define MADV_NOHUGEPAGE 15 /* Not worth backing with hugepages */ | ||
82 | |||
80 | /* compatibility flags */ | 83 | /* compatibility flags */ |
81 | #define MAP_FILE 0 | 84 | #define MAP_FILE 0 |
82 | 85 | ||
diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c index 5c0a3575877c..2c0e107966ad 100644 --- a/arch/mips/jz4740/board-qi_lb60.c +++ b/arch/mips/jz4740/board-qi_lb60.c | |||
@@ -65,7 +65,7 @@ static struct nand_ecclayout qi_lb60_ecclayout_1gb = { | |||
65 | 65 | ||
66 | /* Early prototypes of the QI LB60 had only 1GB of NAND. | 66 | /* Early prototypes of the QI LB60 had only 1GB of NAND. |
67 | * In order to support these devices aswell the partition and ecc layout is | 67 | * In order to support these devices aswell the partition and ecc layout is |
68 | * initalized depending on the NAND size */ | 68 | * initialized depending on the NAND size */ |
69 | static struct mtd_partition qi_lb60_partitions_1gb[] = { | 69 | static struct mtd_partition qi_lb60_partitions_1gb[] = { |
70 | { | 70 | { |
71 | .name = "NAND BOOT partition", | 71 | .name = "NAND BOOT partition", |
@@ -464,7 +464,7 @@ static int __init qi_lb60_board_setup(void) | |||
464 | board_gpio_setup(); | 464 | board_gpio_setup(); |
465 | 465 | ||
466 | if (qi_lb60_init_platform_devices()) | 466 | if (qi_lb60_init_platform_devices()) |
467 | panic("Failed to initalize platform devices\n"); | 467 | panic("Failed to initialize platform devices\n"); |
468 | 468 | ||
469 | return 0; | 469 | return 0; |
470 | } | 470 | } |
diff --git a/arch/mips/jz4740/gpio.c b/arch/mips/jz4740/gpio.c index 38f60f35156c..88e6aeda5bf1 100644 --- a/arch/mips/jz4740/gpio.c +++ b/arch/mips/jz4740/gpio.c | |||
@@ -546,7 +546,7 @@ static int __init jz4740_gpio_init(void) | |||
546 | for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i) | 546 | for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i) |
547 | jz4740_gpio_chip_init(&jz4740_gpio_chips[i], i); | 547 | jz4740_gpio_chip_init(&jz4740_gpio_chips[i], i); |
548 | 548 | ||
549 | printk(KERN_INFO "JZ4740 GPIO initalized\n"); | 549 | printk(KERN_INFO "JZ4740 GPIO initialized\n"); |
550 | 550 | ||
551 | return 0; | 551 | return 0; |
552 | } | 552 | } |
diff --git a/arch/mips/jz4740/pm.c b/arch/mips/jz4740/pm.c index a9994585424d..902d5b50124c 100644 --- a/arch/mips/jz4740/pm.c +++ b/arch/mips/jz4740/pm.c | |||
@@ -42,7 +42,7 @@ static int jz4740_pm_enter(suspend_state_t state) | |||
42 | return 0; | 42 | return 0; |
43 | } | 43 | } |
44 | 44 | ||
45 | static struct platform_suspend_ops jz4740_pm_ops = { | 45 | static const struct platform_suspend_ops jz4740_pm_ops = { |
46 | .valid = suspend_valid_only_mem, | 46 | .valid = suspend_valid_only_mem, |
47 | .enter = jz4740_pm_enter, | 47 | .enter = jz4740_pm_enter, |
48 | }; | 48 | }; |
diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c index 6f51dda87fce..d87a72e9fac7 100644 --- a/arch/mips/kernel/module.c +++ b/arch/mips/kernel/module.c | |||
@@ -46,17 +46,9 @@ static DEFINE_SPINLOCK(dbe_lock); | |||
46 | void *module_alloc(unsigned long size) | 46 | void *module_alloc(unsigned long size) |
47 | { | 47 | { |
48 | #ifdef MODULE_START | 48 | #ifdef MODULE_START |
49 | struct vm_struct *area; | 49 | return __vmalloc_node_range(size, 1, MODULE_START, MODULE_END, |
50 | 50 | GFP_KERNEL, PAGE_KERNEL, -1, | |
51 | size = PAGE_ALIGN(size); | 51 | __builtin_return_address(0)); |
52 | if (!size) | ||
53 | return NULL; | ||
54 | |||
55 | area = __get_vm_area(size, VM_ALLOC, MODULE_START, MODULE_END); | ||
56 | if (!area) | ||
57 | return NULL; | ||
58 | |||
59 | return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL); | ||
60 | #else | 52 | #else |
61 | if (size == 0) | 53 | if (size == 0) |
62 | return NULL; | 54 | return NULL; |
diff --git a/arch/mips/loongson/common/pm.c b/arch/mips/loongson/common/pm.c index 6c1fd9001712..f55e07aee071 100644 --- a/arch/mips/loongson/common/pm.c +++ b/arch/mips/loongson/common/pm.c | |||
@@ -147,7 +147,7 @@ static int loongson_pm_valid_state(suspend_state_t state) | |||
147 | } | 147 | } |
148 | } | 148 | } |
149 | 149 | ||
150 | static struct platform_suspend_ops loongson_pm_ops = { | 150 | static const struct platform_suspend_ops loongson_pm_ops = { |
151 | .valid = loongson_pm_valid_state, | 151 | .valid = loongson_pm_valid_state, |
152 | .enter = loongson_pm_enter, | 152 | .enter = loongson_pm_enter, |
153 | }; | 153 | }; |
diff --git a/arch/mips/mti-malta/malta-memory.c b/arch/mips/mti-malta/malta-memory.c index b27419c84919..a96d281f9221 100644 --- a/arch/mips/mti-malta/malta-memory.c +++ b/arch/mips/mti-malta/malta-memory.c | |||
@@ -43,7 +43,7 @@ static struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS]; | |||
43 | static char *mtypes[3] = { | 43 | static char *mtypes[3] = { |
44 | "Dont use memory", | 44 | "Dont use memory", |
45 | "YAMON PROM memory", | 45 | "YAMON PROM memory", |
46 | "Free memmory", | 46 | "Free memory", |
47 | }; | 47 | }; |
48 | #endif | 48 | #endif |
49 | 49 | ||
diff --git a/arch/mips/pci/pcie-octeon.c b/arch/mips/pci/pcie-octeon.c index 385f035b24e4..0583c463e5f1 100644 --- a/arch/mips/pci/pcie-octeon.c +++ b/arch/mips/pci/pcie-octeon.c | |||
@@ -900,7 +900,7 @@ static int cvmx_pcie_rc_initialize(int pcie_port) | |||
900 | mem_access_subid.s.ror = 0; | 900 | mem_access_subid.s.ror = 0; |
901 | /* Disable Relaxed Ordering for Writes. */ | 901 | /* Disable Relaxed Ordering for Writes. */ |
902 | mem_access_subid.s.row = 0; | 902 | mem_access_subid.s.row = 0; |
903 | /* PCIe Adddress Bits <63:34>. */ | 903 | /* PCIe Address Bits <63:34>. */ |
904 | mem_access_subid.s.ba = 0; | 904 | mem_access_subid.s.ba = 0; |
905 | 905 | ||
906 | /* | 906 | /* |
diff --git a/arch/mips/powertv/memory.c b/arch/mips/powertv/memory.c index 73880ad29bc2..fb3d29660c42 100644 --- a/arch/mips/powertv/memory.c +++ b/arch/mips/powertv/memory.c | |||
@@ -57,7 +57,7 @@ | |||
57 | unsigned long ptv_memsize; | 57 | unsigned long ptv_memsize; |
58 | 58 | ||
59 | /* | 59 | /* |
60 | * struct low_mem_reserved - Items in low memmory that are reserved | 60 | * struct low_mem_reserved - Items in low memory that are reserved |
61 | * @start: Physical address of item | 61 | * @start: Physical address of item |
62 | * @size: Size, in bytes, of this item | 62 | * @size: Size, in bytes, of this item |
63 | * @is_aliased: True if this is RAM aliased from another location. If false, | 63 | * @is_aliased: True if this is RAM aliased from another location. If false, |
diff --git a/arch/mips/txx9/generic/pci.c b/arch/mips/txx9/generic/pci.c index 9a0be810cafa..96e69a00ffc8 100644 --- a/arch/mips/txx9/generic/pci.c +++ b/arch/mips/txx9/generic/pci.c | |||
@@ -107,7 +107,7 @@ int txx9_pci_mem_high __initdata; | |||
107 | 107 | ||
108 | /* | 108 | /* |
109 | * allocate pci_controller and resources. | 109 | * allocate pci_controller and resources. |
110 | * mem_base, io_base: physical addresss. 0 for auto assignment. | 110 | * mem_base, io_base: physical address. 0 for auto assignment. |
111 | * mem_size and io_size means max size on auto assignment. | 111 | * mem_size and io_size means max size on auto assignment. |
112 | * pcic must be &txx9_primary_pcic or NULL. | 112 | * pcic must be &txx9_primary_pcic or NULL. |
113 | */ | 113 | */ |
diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig index 41ba38513c89..8ed41cf2b08d 100644 --- a/arch/mn10300/Kconfig +++ b/arch/mn10300/Kconfig | |||
@@ -203,6 +203,7 @@ endmenu | |||
203 | config SMP | 203 | config SMP |
204 | bool "Symmetric multi-processing support" | 204 | bool "Symmetric multi-processing support" |
205 | default y | 205 | default y |
206 | select USE_GENERIC_SMP_HELPERS | ||
206 | depends on MN10300_PROC_MN2WS0038 || MN10300_PROC_MN2WS0050 | 207 | depends on MN10300_PROC_MN2WS0038 || MN10300_PROC_MN2WS0050 |
207 | ---help--- | 208 | ---help--- |
208 | This enables support for systems with more than one CPU. If you have | 209 | This enables support for systems with more than one CPU. If you have |
@@ -226,11 +227,6 @@ config NR_CPUS | |||
226 | depends on SMP | 227 | depends on SMP |
227 | default "2" | 228 | default "2" |
228 | 229 | ||
229 | config USE_GENERIC_SMP_HELPERS | ||
230 | bool | ||
231 | depends on SMP | ||
232 | default y | ||
233 | |||
234 | source "kernel/Kconfig.preempt" | 230 | source "kernel/Kconfig.preempt" |
235 | 231 | ||
236 | config MN10300_CURRENT_IN_E2 | 232 | config MN10300_CURRENT_IN_E2 |
diff --git a/arch/mn10300/kernel/rtc.c b/arch/mn10300/kernel/rtc.c index e9e20f9a4dd3..48d7058b3295 100644 --- a/arch/mn10300/kernel/rtc.c +++ b/arch/mn10300/kernel/rtc.c | |||
@@ -89,7 +89,7 @@ static int set_rtc_mmss(unsigned long nowtime) | |||
89 | CMOS_WRITE(real_seconds, RTC_SECONDS); | 89 | CMOS_WRITE(real_seconds, RTC_SECONDS); |
90 | CMOS_WRITE(real_minutes, RTC_MINUTES); | 90 | CMOS_WRITE(real_minutes, RTC_MINUTES); |
91 | } else { | 91 | } else { |
92 | printk(KERN_WARNING | 92 | printk_once(KERN_NOTICE |
93 | "set_rtc_mmss: can't update from %d to %d\n", | 93 | "set_rtc_mmss: can't update from %d to %d\n", |
94 | cmos_minutes, real_minutes); | 94 | cmos_minutes, real_minutes); |
95 | retval = -1; | 95 | retval = -1; |
diff --git a/arch/parisc/include/asm/mman.h b/arch/parisc/include/asm/mman.h index 9749c8afe83a..f5b7bf5fba68 100644 --- a/arch/parisc/include/asm/mman.h +++ b/arch/parisc/include/asm/mman.h | |||
@@ -59,6 +59,9 @@ | |||
59 | #define MADV_MERGEABLE 65 /* KSM may merge identical pages */ | 59 | #define MADV_MERGEABLE 65 /* KSM may merge identical pages */ |
60 | #define MADV_UNMERGEABLE 66 /* KSM may not merge identical pages */ | 60 | #define MADV_UNMERGEABLE 66 /* KSM may not merge identical pages */ |
61 | 61 | ||
62 | #define MADV_HUGEPAGE 67 /* Worth backing with hugepages */ | ||
63 | #define MADV_NOHUGEPAGE 68 /* Not worth backing with hugepages */ | ||
64 | |||
62 | /* compatibility flags */ | 65 | /* compatibility flags */ |
63 | #define MAP_FILE 0 | 66 | #define MAP_FILE 0 |
64 | #define MAP_VARIABLE 0 | 67 | #define MAP_VARIABLE 0 |
diff --git a/arch/powerpc/include/asm/8xx_immap.h b/arch/powerpc/include/asm/8xx_immap.h index 4b0e15206006..6b6dc20b0beb 100644 --- a/arch/powerpc/include/asm/8xx_immap.h +++ b/arch/powerpc/include/asm/8xx_immap.h | |||
@@ -93,7 +93,7 @@ typedef struct mem_ctlr { | |||
93 | } memctl8xx_t; | 93 | } memctl8xx_t; |
94 | 94 | ||
95 | /*----------------------------------------------------------------------- | 95 | /*----------------------------------------------------------------------- |
96 | * BR - Memory Controler: Base Register 16-9 | 96 | * BR - Memory Controller: Base Register 16-9 |
97 | */ | 97 | */ |
98 | #define BR_BA_MSK 0xffff8000 /* Base Address Mask */ | 98 | #define BR_BA_MSK 0xffff8000 /* Base Address Mask */ |
99 | #define BR_AT_MSK 0x00007000 /* Address Type Mask */ | 99 | #define BR_AT_MSK 0x00007000 /* Address Type Mask */ |
@@ -110,7 +110,7 @@ typedef struct mem_ctlr { | |||
110 | #define BR_V 0x00000001 /* Bank Valid */ | 110 | #define BR_V 0x00000001 /* Bank Valid */ |
111 | 111 | ||
112 | /*----------------------------------------------------------------------- | 112 | /*----------------------------------------------------------------------- |
113 | * OR - Memory Controler: Option Register 16-11 | 113 | * OR - Memory Controller: Option Register 16-11 |
114 | */ | 114 | */ |
115 | #define OR_AM_MSK 0xffff8000 /* Address Mask Mask */ | 115 | #define OR_AM_MSK 0xffff8000 /* Address Mask Mask */ |
116 | #define OR_ATM_MSK 0x00007000 /* Address Type Mask Mask */ | 116 | #define OR_ATM_MSK 0x00007000 /* Address Type Mask Mask */ |
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index e316847c08c0..badc983031b3 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c | |||
@@ -1307,12 +1307,10 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) | |||
1307 | int err = -ENOMEM; | 1307 | int err = -ENOMEM; |
1308 | unsigned long p; | 1308 | unsigned long p; |
1309 | 1309 | ||
1310 | vcpu_book3s = vmalloc(sizeof(struct kvmppc_vcpu_book3s)); | 1310 | vcpu_book3s = vzalloc(sizeof(struct kvmppc_vcpu_book3s)); |
1311 | if (!vcpu_book3s) | 1311 | if (!vcpu_book3s) |
1312 | goto out; | 1312 | goto out; |
1313 | 1313 | ||
1314 | memset(vcpu_book3s, 0, sizeof(struct kvmppc_vcpu_book3s)); | ||
1315 | |||
1316 | vcpu_book3s->shadow_vcpu = (struct kvmppc_book3s_shadow_vcpu *) | 1314 | vcpu_book3s->shadow_vcpu = (struct kvmppc_book3s_shadow_vcpu *) |
1317 | kzalloc(sizeof(*vcpu_book3s->shadow_vcpu), GFP_KERNEL); | 1315 | kzalloc(sizeof(*vcpu_book3s->shadow_vcpu), GFP_KERNEL); |
1318 | if (!vcpu_book3s->shadow_vcpu) | 1316 | if (!vcpu_book3s->shadow_vcpu) |
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 38f756f25053..99758460efde 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c | |||
@@ -145,18 +145,12 @@ void kvm_arch_check_processor_compat(void *rtn) | |||
145 | *(int *)rtn = kvmppc_core_check_processor_compat(); | 145 | *(int *)rtn = kvmppc_core_check_processor_compat(); |
146 | } | 146 | } |
147 | 147 | ||
148 | struct kvm *kvm_arch_create_vm(void) | 148 | int kvm_arch_init_vm(struct kvm *kvm) |
149 | { | 149 | { |
150 | struct kvm *kvm; | 150 | return 0; |
151 | |||
152 | kvm = kzalloc(sizeof(struct kvm), GFP_KERNEL); | ||
153 | if (!kvm) | ||
154 | return ERR_PTR(-ENOMEM); | ||
155 | |||
156 | return kvm; | ||
157 | } | 151 | } |
158 | 152 | ||
159 | static void kvmppc_free_vcpus(struct kvm *kvm) | 153 | void kvm_arch_destroy_vm(struct kvm *kvm) |
160 | { | 154 | { |
161 | unsigned int i; | 155 | unsigned int i; |
162 | struct kvm_vcpu *vcpu; | 156 | struct kvm_vcpu *vcpu; |
@@ -176,14 +170,6 @@ void kvm_arch_sync_events(struct kvm *kvm) | |||
176 | { | 170 | { |
177 | } | 171 | } |
178 | 172 | ||
179 | void kvm_arch_destroy_vm(struct kvm *kvm) | ||
180 | { | ||
181 | kvmppc_free_vcpus(kvm); | ||
182 | kvm_free_physmem(kvm); | ||
183 | cleanup_srcu_struct(&kvm->srcu); | ||
184 | kfree(kvm); | ||
185 | } | ||
186 | |||
187 | int kvm_dev_ioctl_check_extension(long ext) | 173 | int kvm_dev_ioctl_check_extension(long ext) |
188 | { | 174 | { |
189 | int r; | 175 | int r; |
diff --git a/arch/powerpc/mm/gup.c b/arch/powerpc/mm/gup.c index d7efdbf640c7..fec13200868f 100644 --- a/arch/powerpc/mm/gup.c +++ b/arch/powerpc/mm/gup.c | |||
@@ -16,6 +16,16 @@ | |||
16 | 16 | ||
17 | #ifdef __HAVE_ARCH_PTE_SPECIAL | 17 | #ifdef __HAVE_ARCH_PTE_SPECIAL |
18 | 18 | ||
19 | static inline void get_huge_page_tail(struct page *page) | ||
20 | { | ||
21 | /* | ||
22 | * __split_huge_page_refcount() cannot run | ||
23 | * from under us. | ||
24 | */ | ||
25 | VM_BUG_ON(atomic_read(&page->_count) < 0); | ||
26 | atomic_inc(&page->_count); | ||
27 | } | ||
28 | |||
19 | /* | 29 | /* |
20 | * The performance critical leaf functions are made noinline otherwise gcc | 30 | * The performance critical leaf functions are made noinline otherwise gcc |
21 | * inlines everything into a single function which results in too much | 31 | * inlines everything into a single function which results in too much |
@@ -47,6 +57,8 @@ static noinline int gup_pte_range(pmd_t pmd, unsigned long addr, | |||
47 | put_page(page); | 57 | put_page(page); |
48 | return 0; | 58 | return 0; |
49 | } | 59 | } |
60 | if (PageTail(page)) | ||
61 | get_huge_page_tail(page); | ||
50 | pages[*nr] = page; | 62 | pages[*nr] = page; |
51 | (*nr)++; | 63 | (*nr)++; |
52 | 64 | ||
diff --git a/arch/powerpc/oprofile/op_model_cell.c b/arch/powerpc/oprofile/op_model_cell.c index 7fd90d02d8c6..c4d2b7167568 100644 --- a/arch/powerpc/oprofile/op_model_cell.c +++ b/arch/powerpc/oprofile/op_model_cell.c | |||
@@ -1469,7 +1469,7 @@ static int cell_global_start(struct op_counter_config *ctr) | |||
1469 | * The pm_interval register is setup to write the SPU PC value into the | 1469 | * The pm_interval register is setup to write the SPU PC value into the |
1470 | * trace buffer at the maximum rate possible. The trace buffer is configured | 1470 | * trace buffer at the maximum rate possible. The trace buffer is configured |
1471 | * to store the PCs, wrapping when it is full. The performance counter is | 1471 | * to store the PCs, wrapping when it is full. The performance counter is |
1472 | * intialized to the max hardware count minus the number of events, N, between | 1472 | * initialized to the max hardware count minus the number of events, N, between |
1473 | * samples. Once the N events have occured, a HW counter overflow occurs | 1473 | * samples. Once the N events have occured, a HW counter overflow occurs |
1474 | * causing the generation of a HW counter interrupt which also stops the | 1474 | * causing the generation of a HW counter interrupt which also stops the |
1475 | * writing of the SPU PC values to the trace buffer. Hence the last PC | 1475 | * writing of the SPU PC values to the trace buffer. Hence the last PC |
diff --git a/arch/powerpc/platforms/52xx/lite5200_pm.c b/arch/powerpc/platforms/52xx/lite5200_pm.c index 80234e5921f5..eda0fc2a3914 100644 --- a/arch/powerpc/platforms/52xx/lite5200_pm.c +++ b/arch/powerpc/platforms/52xx/lite5200_pm.c | |||
@@ -232,7 +232,7 @@ static void lite5200_pm_end(void) | |||
232 | lite5200_pm_target_state = PM_SUSPEND_ON; | 232 | lite5200_pm_target_state = PM_SUSPEND_ON; |
233 | } | 233 | } |
234 | 234 | ||
235 | static struct platform_suspend_ops lite5200_pm_ops = { | 235 | static const struct platform_suspend_ops lite5200_pm_ops = { |
236 | .valid = lite5200_pm_valid, | 236 | .valid = lite5200_pm_valid, |
237 | .begin = lite5200_pm_begin, | 237 | .begin = lite5200_pm_begin, |
238 | .prepare = lite5200_pm_prepare, | 238 | .prepare = lite5200_pm_prepare, |
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pm.c b/arch/powerpc/platforms/52xx/mpc52xx_pm.c index 568cef636275..8310e8b5b57f 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_pm.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_pm.c | |||
@@ -186,7 +186,7 @@ void mpc52xx_pm_finish(void) | |||
186 | iounmap(mbar); | 186 | iounmap(mbar); |
187 | } | 187 | } |
188 | 188 | ||
189 | static struct platform_suspend_ops mpc52xx_pm_ops = { | 189 | static const struct platform_suspend_ops mpc52xx_pm_ops = { |
190 | .valid = mpc52xx_pm_valid, | 190 | .valid = mpc52xx_pm_valid, |
191 | .prepare = mpc52xx_pm_prepare, | 191 | .prepare = mpc52xx_pm_prepare, |
192 | .enter = mpc52xx_pm_enter, | 192 | .enter = mpc52xx_pm_enter, |
diff --git a/arch/powerpc/platforms/83xx/suspend-asm.S b/arch/powerpc/platforms/83xx/suspend-asm.S index 1930543c98d3..3d1ecd211776 100644 --- a/arch/powerpc/platforms/83xx/suspend-asm.S +++ b/arch/powerpc/platforms/83xx/suspend-asm.S | |||
@@ -231,7 +231,7 @@ _GLOBAL(mpc83xx_enter_deep_sleep) | |||
231 | ori r4, r4, 0x002a | 231 | ori r4, r4, 0x002a |
232 | mtspr SPRN_DBAT0L, r4 | 232 | mtspr SPRN_DBAT0L, r4 |
233 | lis r8, TMP_VIRT_IMMR@h | 233 | lis r8, TMP_VIRT_IMMR@h |
234 | ori r4, r8, 0x001e /* 1 MByte accessable from Kernel Space only */ | 234 | ori r4, r8, 0x001e /* 1 MByte accessible from Kernel Space only */ |
235 | mtspr SPRN_DBAT0U, r4 | 235 | mtspr SPRN_DBAT0U, r4 |
236 | isync | 236 | isync |
237 | 237 | ||
@@ -241,7 +241,7 @@ _GLOBAL(mpc83xx_enter_deep_sleep) | |||
241 | ori r4, r4, 0x002a | 241 | ori r4, r4, 0x002a |
242 | mtspr SPRN_DBAT1L, r4 | 242 | mtspr SPRN_DBAT1L, r4 |
243 | lis r9, (TMP_VIRT_IMMR + 0x01000000)@h | 243 | lis r9, (TMP_VIRT_IMMR + 0x01000000)@h |
244 | ori r4, r9, 0x001e /* 1 MByte accessable from Kernel Space only */ | 244 | ori r4, r9, 0x001e /* 1 MByte accessible from Kernel Space only */ |
245 | mtspr SPRN_DBAT1U, r4 | 245 | mtspr SPRN_DBAT1U, r4 |
246 | isync | 246 | isync |
247 | 247 | ||
@@ -253,7 +253,7 @@ _GLOBAL(mpc83xx_enter_deep_sleep) | |||
253 | li r4, 0x0002 | 253 | li r4, 0x0002 |
254 | mtspr SPRN_DBAT2L, r4 | 254 | mtspr SPRN_DBAT2L, r4 |
255 | lis r4, KERNELBASE@h | 255 | lis r4, KERNELBASE@h |
256 | ori r4, r4, 0x001e /* 1 MByte accessable from Kernel Space only */ | 256 | ori r4, r4, 0x001e /* 1 MByte accessible from Kernel Space only */ |
257 | mtspr SPRN_DBAT2U, r4 | 257 | mtspr SPRN_DBAT2U, r4 |
258 | isync | 258 | isync |
259 | 259 | ||
diff --git a/arch/powerpc/platforms/83xx/suspend.c b/arch/powerpc/platforms/83xx/suspend.c index 75ae77f1af6a..fd4f2f2f19e6 100644 --- a/arch/powerpc/platforms/83xx/suspend.c +++ b/arch/powerpc/platforms/83xx/suspend.c | |||
@@ -311,7 +311,7 @@ static int mpc83xx_is_pci_agent(void) | |||
311 | return ret; | 311 | return ret; |
312 | } | 312 | } |
313 | 313 | ||
314 | static struct platform_suspend_ops mpc83xx_suspend_ops = { | 314 | static const struct platform_suspend_ops mpc83xx_suspend_ops = { |
315 | .valid = mpc83xx_suspend_valid, | 315 | .valid = mpc83xx_suspend_valid, |
316 | .begin = mpc83xx_suspend_begin, | 316 | .begin = mpc83xx_suspend_begin, |
317 | .enter = mpc83xx_suspend_enter, | 317 | .enter = mpc83xx_suspend_enter, |
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c index aa34cac4eb5c..747d1ee661fd 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c | |||
@@ -309,7 +309,7 @@ static void __init mpc85xx_mds_qe_init(void) | |||
309 | /* P1021 has pins muxed for QE and other functions. To | 309 | /* P1021 has pins muxed for QE and other functions. To |
310 | * enable QE UEC mode, we need to set bit QE0 for UCC1 | 310 | * enable QE UEC mode, we need to set bit QE0 for UCC1 |
311 | * in Eth mode, QE0 and QE3 for UCC5 in Eth mode, QE9 | 311 | * in Eth mode, QE0 and QE3 for UCC5 in Eth mode, QE9 |
312 | * and QE12 for QE MII management singals in PMUXCR | 312 | * and QE12 for QE MII management signals in PMUXCR |
313 | * register. | 313 | * register. |
314 | */ | 314 | */ |
315 | setbits32(pmuxcr, MPC85xx_PMUXCR_QE0 | | 315 | setbits32(pmuxcr, MPC85xx_PMUXCR_QE0 | |
diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c index b341018326df..6c4b5837fc8a 100644 --- a/arch/powerpc/platforms/ps3/device-init.c +++ b/arch/powerpc/platforms/ps3/device-init.c | |||
@@ -566,10 +566,10 @@ static int ps3_setup_dynamic_device(const struct ps3_repository_device *repo) | |||
566 | case PS3_DEV_TYPE_STOR_DISK: | 566 | case PS3_DEV_TYPE_STOR_DISK: |
567 | result = ps3_setup_storage_dev(repo, PS3_MATCH_ID_STOR_DISK); | 567 | result = ps3_setup_storage_dev(repo, PS3_MATCH_ID_STOR_DISK); |
568 | 568 | ||
569 | /* Some devices are not accessable from the Other OS lpar. */ | 569 | /* Some devices are not accessible from the Other OS lpar. */ |
570 | if (result == -ENODEV) { | 570 | if (result == -ENODEV) { |
571 | result = 0; | 571 | result = 0; |
572 | pr_debug("%s:%u: not accessable\n", __func__, | 572 | pr_debug("%s:%u: not accessible\n", __func__, |
573 | __LINE__); | 573 | __LINE__); |
574 | } | 574 | } |
575 | 575 | ||
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c index 59d9712d7364..92290ff4761a 100644 --- a/arch/powerpc/platforms/ps3/interrupt.c +++ b/arch/powerpc/platforms/ps3/interrupt.c | |||
@@ -44,7 +44,7 @@ | |||
44 | * @lock: | 44 | * @lock: |
45 | * @ipi_debug_brk_mask: | 45 | * @ipi_debug_brk_mask: |
46 | * | 46 | * |
47 | * The HV mantains per SMT thread mappings of HV outlet to HV plug on | 47 | * The HV maintains per SMT thread mappings of HV outlet to HV plug on |
48 | * behalf of the guest. These mappings are implemented as 256 bit guest | 48 | * behalf of the guest. These mappings are implemented as 256 bit guest |
49 | * supplied bitmaps indexed by plug number. The addresses of the bitmaps | 49 | * supplied bitmaps indexed by plug number. The addresses of the bitmaps |
50 | * are registered with the HV through lv1_configure_irq_state_bitmap(). | 50 | * are registered with the HV through lv1_configure_irq_state_bitmap(). |
diff --git a/arch/powerpc/platforms/pseries/hvCall_inst.c b/arch/powerpc/platforms/pseries/hvCall_inst.c index e19ff021e711..f106662f4381 100644 --- a/arch/powerpc/platforms/pseries/hvCall_inst.c +++ b/arch/powerpc/platforms/pseries/hvCall_inst.c | |||
@@ -55,7 +55,7 @@ static void hc_stop(struct seq_file *m, void *p) | |||
55 | static int hc_show(struct seq_file *m, void *p) | 55 | static int hc_show(struct seq_file *m, void *p) |
56 | { | 56 | { |
57 | unsigned long h_num = (unsigned long)p; | 57 | unsigned long h_num = (unsigned long)p; |
58 | struct hcall_stats *hs = (struct hcall_stats *)m->private; | 58 | struct hcall_stats *hs = m->private; |
59 | 59 | ||
60 | if (hs[h_num].num_calls) { | 60 | if (hs[h_num].num_calls) { |
61 | if (cpu_has_feature(CPU_FTR_PURR)) | 61 | if (cpu_has_feature(CPU_FTR_PURR)) |
diff --git a/arch/powerpc/platforms/pseries/suspend.c b/arch/powerpc/platforms/pseries/suspend.c index ed72098bb4e3..a8ca289ff267 100644 --- a/arch/powerpc/platforms/pseries/suspend.c +++ b/arch/powerpc/platforms/pseries/suspend.c | |||
@@ -153,7 +153,7 @@ static struct sysdev_class suspend_sysdev_class = { | |||
153 | .name = "power", | 153 | .name = "power", |
154 | }; | 154 | }; |
155 | 155 | ||
156 | static struct platform_suspend_ops pseries_suspend_ops = { | 156 | static const struct platform_suspend_ops pseries_suspend_ops = { |
157 | .valid = suspend_valid_only_mem, | 157 | .valid = suspend_valid_only_mem, |
158 | .begin = pseries_suspend_begin, | 158 | .begin = pseries_suspend_begin, |
159 | .prepare_late = pseries_prepare_late, | 159 | .prepare_late = pseries_prepare_late, |
diff --git a/arch/powerpc/sysdev/fsl_pmc.c b/arch/powerpc/sysdev/fsl_pmc.c index 44de8559c975..e9381bfefb21 100644 --- a/arch/powerpc/sysdev/fsl_pmc.c +++ b/arch/powerpc/sysdev/fsl_pmc.c | |||
@@ -53,7 +53,7 @@ static int pmc_suspend_valid(suspend_state_t state) | |||
53 | return 1; | 53 | return 1; |
54 | } | 54 | } |
55 | 55 | ||
56 | static struct platform_suspend_ops pmc_suspend_ops = { | 56 | static const struct platform_suspend_ops pmc_suspend_ops = { |
57 | .valid = pmc_suspend_valid, | 57 | .valid = pmc_suspend_valid, |
58 | .enter = pmc_suspend_enter, | 58 | .enter = pmc_suspend_enter, |
59 | }; | 59 | }; |
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index 9725369d432a..9f99bef2adec 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c | |||
@@ -973,7 +973,6 @@ fsl_rio_dbell_handler(int irq, void *dev_instance) | |||
973 | if (dsr & DOORBELL_DSR_QFI) { | 973 | if (dsr & DOORBELL_DSR_QFI) { |
974 | pr_info("RIO: doorbell queue full\n"); | 974 | pr_info("RIO: doorbell queue full\n"); |
975 | out_be32(&priv->msg_regs->dsr, DOORBELL_DSR_QFI); | 975 | out_be32(&priv->msg_regs->dsr, DOORBELL_DSR_QFI); |
976 | goto out; | ||
977 | } | 976 | } |
978 | 977 | ||
979 | /* XXX Need to check/dispatch until queue empty */ | 978 | /* XXX Need to check/dispatch until queue empty */ |
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 985d825494f1..bade533ba288 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
@@ -164,24 +164,18 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
164 | return r; | 164 | return r; |
165 | } | 165 | } |
166 | 166 | ||
167 | struct kvm *kvm_arch_create_vm(void) | 167 | int kvm_arch_init_vm(struct kvm *kvm) |
168 | { | 168 | { |
169 | struct kvm *kvm; | ||
170 | int rc; | 169 | int rc; |
171 | char debug_name[16]; | 170 | char debug_name[16]; |
172 | 171 | ||
173 | rc = s390_enable_sie(); | 172 | rc = s390_enable_sie(); |
174 | if (rc) | 173 | if (rc) |
175 | goto out_nokvm; | 174 | goto out_err; |
176 | |||
177 | rc = -ENOMEM; | ||
178 | kvm = kzalloc(sizeof(struct kvm), GFP_KERNEL); | ||
179 | if (!kvm) | ||
180 | goto out_nokvm; | ||
181 | 175 | ||
182 | kvm->arch.sca = (struct sca_block *) get_zeroed_page(GFP_KERNEL); | 176 | kvm->arch.sca = (struct sca_block *) get_zeroed_page(GFP_KERNEL); |
183 | if (!kvm->arch.sca) | 177 | if (!kvm->arch.sca) |
184 | goto out_nosca; | 178 | goto out_err; |
185 | 179 | ||
186 | sprintf(debug_name, "kvm-%u", current->pid); | 180 | sprintf(debug_name, "kvm-%u", current->pid); |
187 | 181 | ||
@@ -195,13 +189,11 @@ struct kvm *kvm_arch_create_vm(void) | |||
195 | debug_register_view(kvm->arch.dbf, &debug_sprintf_view); | 189 | debug_register_view(kvm->arch.dbf, &debug_sprintf_view); |
196 | VM_EVENT(kvm, 3, "%s", "vm created"); | 190 | VM_EVENT(kvm, 3, "%s", "vm created"); |
197 | 191 | ||
198 | return kvm; | 192 | return 0; |
199 | out_nodbf: | 193 | out_nodbf: |
200 | free_page((unsigned long)(kvm->arch.sca)); | 194 | free_page((unsigned long)(kvm->arch.sca)); |
201 | out_nosca: | 195 | out_err: |
202 | kfree(kvm); | 196 | return rc; |
203 | out_nokvm: | ||
204 | return ERR_PTR(rc); | ||
205 | } | 197 | } |
206 | 198 | ||
207 | void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) | 199 | void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) |
@@ -240,11 +232,8 @@ void kvm_arch_sync_events(struct kvm *kvm) | |||
240 | void kvm_arch_destroy_vm(struct kvm *kvm) | 232 | void kvm_arch_destroy_vm(struct kvm *kvm) |
241 | { | 233 | { |
242 | kvm_free_vcpus(kvm); | 234 | kvm_free_vcpus(kvm); |
243 | kvm_free_physmem(kvm); | ||
244 | free_page((unsigned long)(kvm->arch.sca)); | 235 | free_page((unsigned long)(kvm->arch.sca)); |
245 | debug_unregister(kvm->arch.dbf); | 236 | debug_unregister(kvm->arch.dbf); |
246 | cleanup_srcu_struct(&kvm->srcu); | ||
247 | kfree(kvm); | ||
248 | } | 237 | } |
249 | 238 | ||
250 | /* Section: vcpu related */ | 239 | /* Section: vcpu related */ |
diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig index 2018c7ea4c93..d893411022d5 100644 --- a/arch/sh/boards/Kconfig +++ b/arch/sh/boards/Kconfig | |||
@@ -3,6 +3,9 @@ menu "Board support" | |||
3 | config SOLUTION_ENGINE | 3 | config SOLUTION_ENGINE |
4 | bool | 4 | bool |
5 | 5 | ||
6 | config SH_ALPHA_BOARD | ||
7 | bool | ||
8 | |||
6 | config SH_SOLUTION_ENGINE | 9 | config SH_SOLUTION_ENGINE |
7 | bool "SolutionEngine" | 10 | bool "SolutionEngine" |
8 | select SOLUTION_ENGINE | 11 | select SOLUTION_ENGINE |
@@ -320,6 +323,21 @@ config SH_SH2007 | |||
320 | Compact Flash socket, two serial ports and PC-104 bus. | 323 | Compact Flash socket, two serial ports and PC-104 bus. |
321 | More information at <http://sh2000.sh-linux.org>. | 324 | More information at <http://sh2000.sh-linux.org>. |
322 | 325 | ||
326 | config SH_APSH4A3A | ||
327 | bool "AP-SH4A-3A" | ||
328 | select SH_ALPHA_BOARD | ||
329 | depends on CPU_SUBTYPE_SH7785 | ||
330 | help | ||
331 | Select AP-SH4A-3A if configuring for an ALPHAPROJECT AP-SH4A-3A. | ||
332 | |||
333 | config SH_APSH4AD0A | ||
334 | bool "AP-SH4AD-0A" | ||
335 | select SH_ALPHA_BOARD | ||
336 | select SYS_SUPPORTS_PCI | ||
337 | depends on CPU_SUBTYPE_SH7786 | ||
338 | help | ||
339 | Select AP-SH4AD-0A if configuring for an ALPHAPROJECT AP-SH4AD-0A. | ||
340 | |||
323 | endmenu | 341 | endmenu |
324 | 342 | ||
325 | source "arch/sh/boards/mach-r2d/Kconfig" | 343 | source "arch/sh/boards/mach-r2d/Kconfig" |
diff --git a/arch/sh/boards/Makefile b/arch/sh/boards/Makefile index be7d11d04b26..975a0f64ff20 100644 --- a/arch/sh/boards/Makefile +++ b/arch/sh/boards/Makefile | |||
@@ -13,3 +13,5 @@ obj-$(CONFIG_SH_ESPT) += board-espt.o | |||
13 | obj-$(CONFIG_SH_POLARIS) += board-polaris.o | 13 | obj-$(CONFIG_SH_POLARIS) += board-polaris.o |
14 | obj-$(CONFIG_SH_TITAN) += board-titan.o | 14 | obj-$(CONFIG_SH_TITAN) += board-titan.o |
15 | obj-$(CONFIG_SH_SH7757LCR) += board-sh7757lcr.o | 15 | obj-$(CONFIG_SH_SH7757LCR) += board-sh7757lcr.o |
16 | obj-$(CONFIG_SH_APSH4A3A) += board-apsh4a3a.o | ||
17 | obj-$(CONFIG_SH_APSH4AD0A) += board-apsh4ad0a.o | ||
diff --git a/arch/sh/boards/board-apsh4a3a.c b/arch/sh/boards/board-apsh4a3a.c new file mode 100644 index 000000000000..8e2a27057bc9 --- /dev/null +++ b/arch/sh/boards/board-apsh4a3a.c | |||
@@ -0,0 +1,175 @@ | |||
1 | /* | ||
2 | * ALPHAPROJECT AP-SH4A-3A Support. | ||
3 | * | ||
4 | * Copyright (C) 2010 ALPHAPROJECT Co.,Ltd. | ||
5 | * Copyright (C) 2008 Yoshihiro Shimoda | ||
6 | * Copyright (C) 2009 Paul Mundt | ||
7 | * | ||
8 | * This file is subject to the terms and conditions of the GNU General Public | ||
9 | * License. See the file "COPYING" in the main directory of this archive | ||
10 | * for more details. | ||
11 | */ | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <linux/mtd/physmap.h> | ||
16 | #include <linux/smsc911x.h> | ||
17 | #include <linux/irq.h> | ||
18 | #include <linux/clk.h> | ||
19 | #include <asm/machvec.h> | ||
20 | #include <asm/sizes.h> | ||
21 | #include <asm/clock.h> | ||
22 | |||
23 | static struct mtd_partition nor_flash_partitions[] = { | ||
24 | { | ||
25 | .name = "loader", | ||
26 | .offset = 0x00000000, | ||
27 | .size = 512 * 1024, | ||
28 | }, | ||
29 | { | ||
30 | .name = "bootenv", | ||
31 | .offset = MTDPART_OFS_APPEND, | ||
32 | .size = 512 * 1024, | ||
33 | }, | ||
34 | { | ||
35 | .name = "kernel", | ||
36 | .offset = MTDPART_OFS_APPEND, | ||
37 | .size = 4 * 1024 * 1024, | ||
38 | }, | ||
39 | { | ||
40 | .name = "data", | ||
41 | .offset = MTDPART_OFS_APPEND, | ||
42 | .size = MTDPART_SIZ_FULL, | ||
43 | }, | ||
44 | }; | ||
45 | |||
46 | static struct physmap_flash_data nor_flash_data = { | ||
47 | .width = 4, | ||
48 | .parts = nor_flash_partitions, | ||
49 | .nr_parts = ARRAY_SIZE(nor_flash_partitions), | ||
50 | }; | ||
51 | |||
52 | static struct resource nor_flash_resources[] = { | ||
53 | [0] = { | ||
54 | .start = 0x00000000, | ||
55 | .end = 0x01000000 - 1, | ||
56 | .flags = IORESOURCE_MEM, | ||
57 | } | ||
58 | }; | ||
59 | |||
60 | static struct platform_device nor_flash_device = { | ||
61 | .name = "physmap-flash", | ||
62 | .dev = { | ||
63 | .platform_data = &nor_flash_data, | ||
64 | }, | ||
65 | .num_resources = ARRAY_SIZE(nor_flash_resources), | ||
66 | .resource = nor_flash_resources, | ||
67 | }; | ||
68 | |||
69 | static struct resource smsc911x_resources[] = { | ||
70 | [0] = { | ||
71 | .name = "smsc911x-memory", | ||
72 | .start = 0xA4000000, | ||
73 | .end = 0xA4000000 + SZ_256 - 1, | ||
74 | .flags = IORESOURCE_MEM, | ||
75 | }, | ||
76 | [1] = { | ||
77 | .name = "smsc911x-irq", | ||
78 | .start = evt2irq(0x200), | ||
79 | .end = evt2irq(0x200), | ||
80 | .flags = IORESOURCE_IRQ, | ||
81 | }, | ||
82 | }; | ||
83 | |||
84 | static struct smsc911x_platform_config smsc911x_config = { | ||
85 | .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, | ||
86 | .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, | ||
87 | .flags = SMSC911X_USE_16BIT, | ||
88 | .phy_interface = PHY_INTERFACE_MODE_MII, | ||
89 | }; | ||
90 | |||
91 | static struct platform_device smsc911x_device = { | ||
92 | .name = "smsc911x", | ||
93 | .id = -1, | ||
94 | .num_resources = ARRAY_SIZE(smsc911x_resources), | ||
95 | .resource = smsc911x_resources, | ||
96 | .dev = { | ||
97 | .platform_data = &smsc911x_config, | ||
98 | }, | ||
99 | }; | ||
100 | |||
101 | static struct platform_device *apsh4a3a_devices[] __initdata = { | ||
102 | &nor_flash_device, | ||
103 | &smsc911x_device, | ||
104 | }; | ||
105 | |||
106 | static int __init apsh4a3a_devices_setup(void) | ||
107 | { | ||
108 | return platform_add_devices(apsh4a3a_devices, | ||
109 | ARRAY_SIZE(apsh4a3a_devices)); | ||
110 | } | ||
111 | device_initcall(apsh4a3a_devices_setup); | ||
112 | |||
113 | static int apsh4a3a_clk_init(void) | ||
114 | { | ||
115 | struct clk *clk; | ||
116 | int ret; | ||
117 | |||
118 | clk = clk_get(NULL, "extal"); | ||
119 | if (!clk || IS_ERR(clk)) | ||
120 | return PTR_ERR(clk); | ||
121 | ret = clk_set_rate(clk, 33333000); | ||
122 | clk_put(clk); | ||
123 | |||
124 | return ret; | ||
125 | } | ||
126 | |||
127 | /* Initialize the board */ | ||
128 | static void __init apsh4a3a_setup(char **cmdline_p) | ||
129 | { | ||
130 | printk(KERN_INFO "Alpha Project AP-SH4A-3A support:\n"); | ||
131 | } | ||
132 | |||
133 | static void __init apsh4a3a_init_irq(void) | ||
134 | { | ||
135 | plat_irq_setup_pins(IRQ_MODE_IRQ7654); | ||
136 | } | ||
137 | |||
138 | /* Return the board specific boot mode pin configuration */ | ||
139 | static int apsh4a3a_mode_pins(void) | ||
140 | { | ||
141 | int value = 0; | ||
142 | |||
143 | /* These are the factory default settings of SW1 and SW2. | ||
144 | * If you change these dip switches then you will need to | ||
145 | * adjust the values below as well. | ||
146 | */ | ||
147 | value &= ~MODE_PIN0; /* Clock Mode 16 */ | ||
148 | value &= ~MODE_PIN1; | ||
149 | value &= ~MODE_PIN2; | ||
150 | value &= ~MODE_PIN3; | ||
151 | value |= MODE_PIN4; | ||
152 | value &= ~MODE_PIN5; /* 16-bit Area0 bus width */ | ||
153 | value |= MODE_PIN6; /* Area 0 SRAM interface */ | ||
154 | value |= MODE_PIN7; | ||
155 | value |= MODE_PIN8; /* Little Endian */ | ||
156 | value |= MODE_PIN9; /* Master Mode */ | ||
157 | value |= MODE_PIN10; /* Crystal resonator */ | ||
158 | value |= MODE_PIN11; /* Display Unit */ | ||
159 | value |= MODE_PIN12; | ||
160 | value &= ~MODE_PIN13; /* 29-bit address mode */ | ||
161 | value |= MODE_PIN14; /* No PLL step-up */ | ||
162 | |||
163 | return value; | ||
164 | } | ||
165 | |||
166 | /* | ||
167 | * The Machine Vector | ||
168 | */ | ||
169 | static struct sh_machine_vector mv_apsh4a3a __initmv = { | ||
170 | .mv_name = "AP-SH4A-3A", | ||
171 | .mv_setup = apsh4a3a_setup, | ||
172 | .mv_clk_init = apsh4a3a_clk_init, | ||
173 | .mv_init_irq = apsh4a3a_init_irq, | ||
174 | .mv_mode_pins = apsh4a3a_mode_pins, | ||
175 | }; | ||
diff --git a/arch/sh/boards/board-apsh4ad0a.c b/arch/sh/boards/board-apsh4ad0a.c new file mode 100644 index 000000000000..e2bd218a054e --- /dev/null +++ b/arch/sh/boards/board-apsh4ad0a.c | |||
@@ -0,0 +1,125 @@ | |||
1 | /* | ||
2 | * ALPHAPROJECT AP-SH4AD-0A Support. | ||
3 | * | ||
4 | * Copyright (C) 2010 ALPHAPROJECT Co.,Ltd. | ||
5 | * Copyright (C) 2010 Matt Fleming | ||
6 | * Copyright (C) 2010 Paul Mundt | ||
7 | * | ||
8 | * This file is subject to the terms and conditions of the GNU General Public | ||
9 | * License. See the file "COPYING" in the main directory of this archive | ||
10 | * for more details. | ||
11 | */ | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <linux/smsc911x.h> | ||
16 | #include <linux/irq.h> | ||
17 | #include <linux/clk.h> | ||
18 | #include <asm/machvec.h> | ||
19 | #include <asm/sizes.h> | ||
20 | |||
21 | static struct resource smsc911x_resources[] = { | ||
22 | [0] = { | ||
23 | .name = "smsc911x-memory", | ||
24 | .start = 0xA4000000, | ||
25 | .end = 0xA4000000 + SZ_256 - 1, | ||
26 | .flags = IORESOURCE_MEM, | ||
27 | }, | ||
28 | [1] = { | ||
29 | .name = "smsc911x-irq", | ||
30 | .start = evt2irq(0x200), | ||
31 | .end = evt2irq(0x200), | ||
32 | .flags = IORESOURCE_IRQ, | ||
33 | }, | ||
34 | }; | ||
35 | |||
36 | static struct smsc911x_platform_config smsc911x_config = { | ||
37 | .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, | ||
38 | .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, | ||
39 | .flags = SMSC911X_USE_16BIT, | ||
40 | .phy_interface = PHY_INTERFACE_MODE_MII, | ||
41 | }; | ||
42 | |||
43 | static struct platform_device smsc911x_device = { | ||
44 | .name = "smsc911x", | ||
45 | .id = -1, | ||
46 | .num_resources = ARRAY_SIZE(smsc911x_resources), | ||
47 | .resource = smsc911x_resources, | ||
48 | .dev = { | ||
49 | .platform_data = &smsc911x_config, | ||
50 | }, | ||
51 | }; | ||
52 | |||
53 | static struct platform_device *apsh4ad0a_devices[] __initdata = { | ||
54 | &smsc911x_device, | ||
55 | }; | ||
56 | |||
57 | static int __init apsh4ad0a_devices_setup(void) | ||
58 | { | ||
59 | return platform_add_devices(apsh4ad0a_devices, | ||
60 | ARRAY_SIZE(apsh4ad0a_devices)); | ||
61 | } | ||
62 | device_initcall(apsh4ad0a_devices_setup); | ||
63 | |||
64 | static int apsh4ad0a_mode_pins(void) | ||
65 | { | ||
66 | int value = 0; | ||
67 | |||
68 | /* These are the factory default settings of SW1 and SW2. | ||
69 | * If you change these dip switches then you will need to | ||
70 | * adjust the values below as well. | ||
71 | */ | ||
72 | value |= MODE_PIN0; /* Clock Mode 3 */ | ||
73 | value |= MODE_PIN1; | ||
74 | value &= ~MODE_PIN2; | ||
75 | value &= ~MODE_PIN3; | ||
76 | value &= ~MODE_PIN4; /* 16-bit Area0 bus width */ | ||
77 | value |= MODE_PIN5; | ||
78 | value |= MODE_PIN6; | ||
79 | value |= MODE_PIN7; /* Normal mode */ | ||
80 | value |= MODE_PIN8; /* Little Endian */ | ||
81 | value |= MODE_PIN9; /* Crystal resonator */ | ||
82 | value &= ~MODE_PIN10; /* 29-bit address mode */ | ||
83 | value &= ~MODE_PIN11; /* PCI-E Root port */ | ||
84 | value &= ~MODE_PIN12; /* 4 lane + 1 lane */ | ||
85 | value |= MODE_PIN13; /* AUD Enable */ | ||
86 | value &= ~MODE_PIN14; /* Normal Operation */ | ||
87 | |||
88 | return value; | ||
89 | } | ||
90 | |||
91 | static int apsh4ad0a_clk_init(void) | ||
92 | { | ||
93 | struct clk *clk; | ||
94 | int ret; | ||
95 | |||
96 | clk = clk_get(NULL, "extal"); | ||
97 | if (!clk || IS_ERR(clk)) | ||
98 | return PTR_ERR(clk); | ||
99 | ret = clk_set_rate(clk, 33333000); | ||
100 | clk_put(clk); | ||
101 | |||
102 | return ret; | ||
103 | } | ||
104 | |||
105 | /* Initialize the board */ | ||
106 | static void __init apsh4ad0a_setup(char **cmdline_p) | ||
107 | { | ||
108 | pr_info("Alpha Project AP-SH4AD-0A support:\n"); | ||
109 | } | ||
110 | |||
111 | static void __init apsh4ad0a_init_irq(void) | ||
112 | { | ||
113 | plat_irq_setup_pins(IRQ_MODE_IRQ3210); | ||
114 | } | ||
115 | |||
116 | /* | ||
117 | * The Machine Vector | ||
118 | */ | ||
119 | static struct sh_machine_vector mv_apsh4ad0a __initmv = { | ||
120 | .mv_name = "AP-SH4AD-0A", | ||
121 | .mv_setup = apsh4ad0a_setup, | ||
122 | .mv_mode_pins = apsh4ad0a_mode_pins, | ||
123 | .mv_clk_init = apsh4ad0a_clk_init, | ||
124 | .mv_init_irq = apsh4ad0a_init_irq, | ||
125 | }; | ||
diff --git a/arch/sh/boards/board-edosk7705.c b/arch/sh/boards/board-edosk7705.c index 4cb3bb74c36f..541d8a281035 100644 --- a/arch/sh/boards/board-edosk7705.c +++ b/arch/sh/boards/board-edosk7705.c | |||
@@ -66,7 +66,7 @@ static int __init init_edosk7705_devices(void) | |||
66 | return platform_add_devices(edosk7705_devices, | 66 | return platform_add_devices(edosk7705_devices, |
67 | ARRAY_SIZE(edosk7705_devices)); | 67 | ARRAY_SIZE(edosk7705_devices)); |
68 | } | 68 | } |
69 | __initcall(init_edosk7705_devices); | 69 | device_initcall(init_edosk7705_devices); |
70 | 70 | ||
71 | /* | 71 | /* |
72 | * The Machine Vector | 72 | * The Machine Vector |
diff --git a/arch/sh/boards/board-edosk7760.c b/arch/sh/boards/board-edosk7760.c index 35dc0994875d..f47ac82da876 100644 --- a/arch/sh/boards/board-edosk7760.c +++ b/arch/sh/boards/board-edosk7760.c | |||
@@ -182,7 +182,7 @@ static int __init init_edosk7760_devices(void) | |||
182 | return platform_add_devices(edosk7760_devices, | 182 | return platform_add_devices(edosk7760_devices, |
183 | ARRAY_SIZE(edosk7760_devices)); | 183 | ARRAY_SIZE(edosk7760_devices)); |
184 | } | 184 | } |
185 | __initcall(init_edosk7760_devices); | 185 | device_initcall(init_edosk7760_devices); |
186 | 186 | ||
187 | /* | 187 | /* |
188 | * The Machine Vector | 188 | * The Machine Vector |
diff --git a/arch/sh/boards/board-sh7785lcr.c b/arch/sh/boards/board-sh7785lcr.c index fe7e686c94ac..ee65ff05c558 100644 --- a/arch/sh/boards/board-sh7785lcr.c +++ b/arch/sh/boards/board-sh7785lcr.c | |||
@@ -284,7 +284,7 @@ static int __init sh7785lcr_devices_setup(void) | |||
284 | return platform_add_devices(sh7785lcr_devices, | 284 | return platform_add_devices(sh7785lcr_devices, |
285 | ARRAY_SIZE(sh7785lcr_devices)); | 285 | ARRAY_SIZE(sh7785lcr_devices)); |
286 | } | 286 | } |
287 | __initcall(sh7785lcr_devices_setup); | 287 | device_initcall(sh7785lcr_devices_setup); |
288 | 288 | ||
289 | /* Initialize IRQ setting */ | 289 | /* Initialize IRQ setting */ |
290 | void __init init_sh7785lcr_IRQ(void) | 290 | void __init init_sh7785lcr_IRQ(void) |
diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c index 07ea908c510d..3e5fc3bbf3ed 100644 --- a/arch/sh/boards/mach-ap325rxa/setup.c +++ b/arch/sh/boards/mach-ap325rxa/setup.c | |||
@@ -14,6 +14,8 @@ | |||
14 | #include <linux/device.h> | 14 | #include <linux/device.h> |
15 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | #include <linux/mfd/sh_mobile_sdhi.h> | ||
18 | #include <linux/mmc/host.h> | ||
17 | #include <linux/mtd/physmap.h> | 19 | #include <linux/mtd/physmap.h> |
18 | #include <linux/mtd/sh_flctl.h> | 20 | #include <linux/mtd/sh_flctl.h> |
19 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
@@ -430,11 +432,18 @@ static struct resource sdhi0_cn3_resources[] = { | |||
430 | }, | 432 | }, |
431 | }; | 433 | }; |
432 | 434 | ||
435 | static struct sh_mobile_sdhi_info sdhi0_cn3_data = { | ||
436 | .tmio_caps = MMC_CAP_SDIO_IRQ, | ||
437 | }; | ||
438 | |||
433 | static struct platform_device sdhi0_cn3_device = { | 439 | static struct platform_device sdhi0_cn3_device = { |
434 | .name = "sh_mobile_sdhi", | 440 | .name = "sh_mobile_sdhi", |
435 | .id = 0, /* "sdhi0" clock */ | 441 | .id = 0, /* "sdhi0" clock */ |
436 | .num_resources = ARRAY_SIZE(sdhi0_cn3_resources), | 442 | .num_resources = ARRAY_SIZE(sdhi0_cn3_resources), |
437 | .resource = sdhi0_cn3_resources, | 443 | .resource = sdhi0_cn3_resources, |
444 | .dev = { | ||
445 | .platform_data = &sdhi0_cn3_data, | ||
446 | }, | ||
438 | .archdata = { | 447 | .archdata = { |
439 | .hwblk_id = HWBLK_SDHI0, | 448 | .hwblk_id = HWBLK_SDHI0, |
440 | }, | 449 | }, |
@@ -453,11 +462,18 @@ static struct resource sdhi1_cn7_resources[] = { | |||
453 | }, | 462 | }, |
454 | }; | 463 | }; |
455 | 464 | ||
465 | static struct sh_mobile_sdhi_info sdhi1_cn7_data = { | ||
466 | .tmio_caps = MMC_CAP_SDIO_IRQ, | ||
467 | }; | ||
468 | |||
456 | static struct platform_device sdhi1_cn7_device = { | 469 | static struct platform_device sdhi1_cn7_device = { |
457 | .name = "sh_mobile_sdhi", | 470 | .name = "sh_mobile_sdhi", |
458 | .id = 1, /* "sdhi1" clock */ | 471 | .id = 1, /* "sdhi1" clock */ |
459 | .num_resources = ARRAY_SIZE(sdhi1_cn7_resources), | 472 | .num_resources = ARRAY_SIZE(sdhi1_cn7_resources), |
460 | .resource = sdhi1_cn7_resources, | 473 | .resource = sdhi1_cn7_resources, |
474 | .dev = { | ||
475 | .platform_data = &sdhi1_cn7_data, | ||
476 | }, | ||
461 | .archdata = { | 477 | .archdata = { |
462 | .hwblk_id = HWBLK_SDHI1, | 478 | .hwblk_id = HWBLK_SDHI1, |
463 | }, | 479 | }, |
diff --git a/arch/sh/boards/mach-cayman/setup.c b/arch/sh/boards/mach-cayman/setup.c index 7e8216ac31bd..e89e8e122a26 100644 --- a/arch/sh/boards/mach-cayman/setup.c +++ b/arch/sh/boards/mach-cayman/setup.c | |||
@@ -165,7 +165,7 @@ static int __init smsc_superio_setup(void) | |||
165 | 165 | ||
166 | return 0; | 166 | return 0; |
167 | } | 167 | } |
168 | __initcall(smsc_superio_setup); | 168 | device_initcall(smsc_superio_setup); |
169 | 169 | ||
170 | static void __iomem *cayman_ioport_map(unsigned long port, unsigned int len) | 170 | static void __iomem *cayman_ioport_map(unsigned long port, unsigned int len) |
171 | { | 171 | { |
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index f48c492a68d3..33b662999fc6 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c | |||
@@ -473,6 +473,7 @@ static struct sh_mobile_sdhi_info sdhi0_info = { | |||
473 | .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, | 473 | .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, |
474 | .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, | 474 | .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, |
475 | .set_pwr = sdhi0_set_pwr, | 475 | .set_pwr = sdhi0_set_pwr, |
476 | .tmio_caps = MMC_CAP_SDIO_IRQ | MMC_CAP_POWER_OFF_CARD, | ||
476 | }; | 477 | }; |
477 | 478 | ||
478 | static struct resource sdhi0_resources[] = { | 479 | static struct resource sdhi0_resources[] = { |
@@ -511,6 +512,7 @@ static void sdhi1_set_pwr(struct platform_device *pdev, int state) | |||
511 | static struct sh_mobile_sdhi_info sdhi1_info = { | 512 | static struct sh_mobile_sdhi_info sdhi1_info = { |
512 | .dma_slave_tx = SHDMA_SLAVE_SDHI1_TX, | 513 | .dma_slave_tx = SHDMA_SLAVE_SDHI1_TX, |
513 | .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX, | 514 | .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX, |
515 | .tmio_caps = MMC_CAP_SDIO_IRQ | MMC_CAP_POWER_OFF_CARD, | ||
514 | .set_pwr = sdhi1_set_pwr, | 516 | .set_pwr = sdhi1_set_pwr, |
515 | }; | 517 | }; |
516 | 518 | ||
diff --git a/arch/sh/boards/mach-hp6xx/pm.c b/arch/sh/boards/mach-hp6xx/pm.c index 4499a3749d40..adc9b4bba828 100644 --- a/arch/sh/boards/mach-hp6xx/pm.c +++ b/arch/sh/boards/mach-hp6xx/pm.c | |||
@@ -143,7 +143,7 @@ static int hp6x0_pm_enter(suspend_state_t state) | |||
143 | return 0; | 143 | return 0; |
144 | } | 144 | } |
145 | 145 | ||
146 | static struct platform_suspend_ops hp6x0_pm_ops = { | 146 | static const struct platform_suspend_ops hp6x0_pm_ops = { |
147 | .enter = hp6x0_pm_enter, | 147 | .enter = hp6x0_pm_enter, |
148 | .valid = suspend_valid_only_mem, | 148 | .valid = suspend_valid_only_mem, |
149 | }; | 149 | }; |
diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c index 9b60eaabf8f3..7504daaa85da 100644 --- a/arch/sh/boards/mach-kfr2r09/setup.c +++ b/arch/sh/boards/mach-kfr2r09/setup.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/platform_device.h> | 11 | #include <linux/platform_device.h> |
12 | #include <linux/interrupt.h> | 12 | #include <linux/interrupt.h> |
13 | #include <linux/mfd/sh_mobile_sdhi.h> | 13 | #include <linux/mfd/sh_mobile_sdhi.h> |
14 | #include <linux/mmc/host.h> | ||
14 | #include <linux/mfd/tmio.h> | 15 | #include <linux/mfd/tmio.h> |
15 | #include <linux/mtd/physmap.h> | 16 | #include <linux/mtd/physmap.h> |
16 | #include <linux/mtd/onenand.h> | 17 | #include <linux/mtd/onenand.h> |
@@ -366,6 +367,7 @@ static struct sh_mobile_sdhi_info sh7724_sdhi0_data = { | |||
366 | .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, | 367 | .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, |
367 | .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, | 368 | .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, |
368 | .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE, | 369 | .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE, |
370 | .tmio_caps = MMC_CAP_SDIO_IRQ, | ||
369 | }; | 371 | }; |
370 | 372 | ||
371 | static struct platform_device kfr2r09_sh_sdhi0_device = { | 373 | static struct platform_device kfr2r09_sh_sdhi0_device = { |
diff --git a/arch/sh/boards/mach-landisk/irq.c b/arch/sh/boards/mach-landisk/irq.c index e79412a40490..c00ace38db3f 100644 --- a/arch/sh/boards/mach-landisk/irq.c +++ b/arch/sh/boards/mach-landisk/irq.c | |||
@@ -1,9 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | * arch/sh/boards/landisk/irq.c | 2 | * arch/sh/boards/mach-landisk/irq.c |
3 | * | 3 | * |
4 | * I-O DATA Device, Inc. LANDISK Support | 4 | * I-O DATA Device, Inc. LANDISK Support |
5 | * | 5 | * |
6 | * Copyright (C) 2005-2007 kogiidena | 6 | * Copyright (C) 2005-2007 kogiidena |
7 | * Copyright (C) 2011 Nobuhiro Iwamatsu | ||
7 | * | 8 | * |
8 | * Copyright (C) 2001 Ian da Silva, Jeremy Siegel | 9 | * Copyright (C) 2001 Ian da Silva, Jeremy Siegel |
9 | * Based largely on io_se.c. | 10 | * Based largely on io_se.c. |
@@ -12,44 +13,54 @@ | |||
12 | * License. See the file "COPYING" in the main directory of this archive | 13 | * License. See the file "COPYING" in the main directory of this archive |
13 | * for more details. | 14 | * for more details. |
14 | */ | 15 | */ |
16 | |||
15 | #include <linux/init.h> | 17 | #include <linux/init.h> |
16 | #include <linux/irq.h> | 18 | #include <linux/irq.h> |
17 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
18 | #include <linux/io.h> | 20 | #include <linux/io.h> |
19 | #include <mach-landisk/mach/iodata_landisk.h> | 21 | #include <mach-landisk/mach/iodata_landisk.h> |
20 | 22 | ||
21 | static void disable_landisk_irq(struct irq_data *data) | 23 | enum { |
22 | { | 24 | UNUSED = 0, |
23 | unsigned char mask = 0xff ^ (0x01 << (data->irq - 5)); | ||
24 | 25 | ||
25 | __raw_writeb(__raw_readb(PA_IMASK) & mask, PA_IMASK); | 26 | PCI_INTA, /* PCI int A */ |
26 | } | 27 | PCI_INTB, /* PCI int B */ |
27 | 28 | PCI_INTC, /* PCI int C */ | |
28 | static void enable_landisk_irq(struct irq_data *data) | 29 | PCI_INTD, /* PCI int D */ |
29 | { | 30 | ATA, /* ATA */ |
30 | unsigned char value = (0x01 << (data->irq - 5)); | 31 | FATA, /* CF */ |
32 | POWER, /* Power swtich */ | ||
33 | BUTTON, /* Button swtich */ | ||
34 | }; | ||
31 | 35 | ||
32 | __raw_writeb(__raw_readb(PA_IMASK) | value, PA_IMASK); | 36 | /* Vectors for LANDISK */ |
33 | } | 37 | static struct intc_vect vectors_landisk[] __initdata = { |
38 | INTC_IRQ(PCI_INTA, IRQ_PCIINTA), | ||
39 | INTC_IRQ(PCI_INTB, IRQ_PCIINTB), | ||
40 | INTC_IRQ(PCI_INTC, IRQ_PCIINTC), | ||
41 | INTC_IRQ(PCI_INTD, IRQ_PCIINTD), | ||
42 | INTC_IRQ(ATA, IRQ_ATA), | ||
43 | INTC_IRQ(FATA, IRQ_FATA), | ||
44 | INTC_IRQ(POWER, IRQ_POWER), | ||
45 | INTC_IRQ(BUTTON, IRQ_BUTTON), | ||
46 | }; | ||
34 | 47 | ||
35 | static struct irq_chip landisk_irq_chip __read_mostly = { | 48 | /* IRLMSK mask register layout for LANDISK */ |
36 | .name = "LANDISK", | 49 | static struct intc_mask_reg mask_registers_landisk[] __initdata = { |
37 | .irq_mask = disable_landisk_irq, | 50 | { PA_IMASK, 0, 8, /* IRLMSK */ |
38 | .irq_unmask = enable_landisk_irq, | 51 | { BUTTON, POWER, FATA, ATA, |
52 | PCI_INTD, PCI_INTC, PCI_INTB, PCI_INTA, | ||
53 | } | ||
54 | }, | ||
39 | }; | 55 | }; |
40 | 56 | ||
57 | static DECLARE_INTC_DESC(intc_desc_landisk, "landisk", vectors_landisk, NULL, | ||
58 | mask_registers_landisk, NULL, NULL); | ||
41 | /* | 59 | /* |
42 | * Initialize IRQ setting | 60 | * Initialize IRQ setting |
43 | */ | 61 | */ |
44 | void __init init_landisk_IRQ(void) | 62 | void __init init_landisk_IRQ(void) |
45 | { | 63 | { |
46 | int i; | 64 | register_intc_controller(&intc_desc_landisk); |
47 | |||
48 | for (i = 5; i < 14; i++) { | ||
49 | disable_irq_nosync(i); | ||
50 | set_irq_chip_and_handler_name(i, &landisk_irq_chip, | ||
51 | handle_level_irq, "level"); | ||
52 | enable_landisk_irq(irq_get_irq_data(i)); | ||
53 | } | ||
54 | __raw_writeb(0x00, PA_PWRINT_CLR); | 65 | __raw_writeb(0x00, PA_PWRINT_CLR); |
55 | } | 66 | } |
diff --git a/arch/sh/boards/mach-landisk/setup.c b/arch/sh/boards/mach-landisk/setup.c index 50337acc18c5..94186cf079b6 100644 --- a/arch/sh/boards/mach-landisk/setup.c +++ b/arch/sh/boards/mach-landisk/setup.c | |||
@@ -21,8 +21,6 @@ | |||
21 | #include <mach-landisk/mach/iodata_landisk.h> | 21 | #include <mach-landisk/mach/iodata_landisk.h> |
22 | #include <asm/io.h> | 22 | #include <asm/io.h> |
23 | 23 | ||
24 | void init_landisk_IRQ(void); | ||
25 | |||
26 | static void landisk_power_off(void) | 24 | static void landisk_power_off(void) |
27 | { | 25 | { |
28 | __raw_writeb(0x01, PA_SHUTDOWN); | 26 | __raw_writeb(0x01, PA_SHUTDOWN); |
@@ -83,7 +81,7 @@ static int __init landisk_devices_setup(void) | |||
83 | ARRAY_SIZE(landisk_devices)); | 81 | ARRAY_SIZE(landisk_devices)); |
84 | } | 82 | } |
85 | 83 | ||
86 | __initcall(landisk_devices_setup); | 84 | device_initcall(landisk_devices_setup); |
87 | 85 | ||
88 | static void __init landisk_setup(char **cmdline_p) | 86 | static void __init landisk_setup(char **cmdline_p) |
89 | { | 87 | { |
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c index c8acfec98695..03a7ffe729d5 100644 --- a/arch/sh/boards/mach-migor/setup.c +++ b/arch/sh/boards/mach-migor/setup.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/input.h> | 13 | #include <linux/input.h> |
14 | #include <linux/input/sh_keysc.h> | 14 | #include <linux/input/sh_keysc.h> |
15 | #include <linux/mfd/sh_mobile_sdhi.h> | 15 | #include <linux/mfd/sh_mobile_sdhi.h> |
16 | #include <linux/mmc/host.h> | ||
16 | #include <linux/mtd/physmap.h> | 17 | #include <linux/mtd/physmap.h> |
17 | #include <linux/mtd/nand.h> | 18 | #include <linux/mtd/nand.h> |
18 | #include <linux/i2c.h> | 19 | #include <linux/i2c.h> |
@@ -410,6 +411,7 @@ static struct resource sdhi_cn9_resources[] = { | |||
410 | static struct sh_mobile_sdhi_info sh7724_sdhi_data = { | 411 | static struct sh_mobile_sdhi_info sh7724_sdhi_data = { |
411 | .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, | 412 | .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, |
412 | .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, | 413 | .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, |
414 | .tmio_caps = MMC_CAP_SDIO_IRQ, | ||
413 | }; | 415 | }; |
414 | 416 | ||
415 | static struct platform_device sdhi_cn9_device = { | 417 | static struct platform_device sdhi_cn9_device = { |
diff --git a/arch/sh/boards/mach-r2d/setup.c b/arch/sh/boards/mach-r2d/setup.c index b84df6a3a93c..4b98a5251f83 100644 --- a/arch/sh/boards/mach-r2d/setup.c +++ b/arch/sh/boards/mach-r2d/setup.c | |||
@@ -258,7 +258,7 @@ static int __init rts7751r2d_devices_setup(void) | |||
258 | return platform_add_devices(rts7751r2d_devices, | 258 | return platform_add_devices(rts7751r2d_devices, |
259 | ARRAY_SIZE(rts7751r2d_devices)); | 259 | ARRAY_SIZE(rts7751r2d_devices)); |
260 | } | 260 | } |
261 | __initcall(rts7751r2d_devices_setup); | 261 | device_initcall(rts7751r2d_devices_setup); |
262 | 262 | ||
263 | static void rts7751r2d_power_off(void) | 263 | static void rts7751r2d_power_off(void) |
264 | { | 264 | { |
diff --git a/arch/sh/boards/mach-sdk7786/setup.c b/arch/sh/boards/mach-sdk7786/setup.c index 75e4ddbbec3e..1521aa75ee3a 100644 --- a/arch/sh/boards/mach-sdk7786/setup.c +++ b/arch/sh/boards/mach-sdk7786/setup.c | |||
@@ -15,13 +15,13 @@ | |||
15 | #include <linux/i2c.h> | 15 | #include <linux/i2c.h> |
16 | #include <linux/irq.h> | 16 | #include <linux/irq.h> |
17 | #include <linux/clk.h> | 17 | #include <linux/clk.h> |
18 | #include <linux/clkdev.h> | ||
18 | #include <mach/fpga.h> | 19 | #include <mach/fpga.h> |
19 | #include <mach/irq.h> | 20 | #include <mach/irq.h> |
20 | #include <asm/machvec.h> | 21 | #include <asm/machvec.h> |
21 | #include <asm/heartbeat.h> | 22 | #include <asm/heartbeat.h> |
22 | #include <asm/sizes.h> | 23 | #include <asm/sizes.h> |
23 | #include <asm/clock.h> | 24 | #include <asm/clock.h> |
24 | #include <asm/clkdev.h> | ||
25 | #include <asm/reboot.h> | 25 | #include <asm/reboot.h> |
26 | #include <asm/smp-ops.h> | 26 | #include <asm/smp-ops.h> |
27 | 27 | ||
@@ -135,7 +135,7 @@ static int __init sdk7786_devices_setup(void) | |||
135 | 135 | ||
136 | return sdk7786_i2c_setup(); | 136 | return sdk7786_i2c_setup(); |
137 | } | 137 | } |
138 | __initcall(sdk7786_devices_setup); | 138 | device_initcall(sdk7786_devices_setup); |
139 | 139 | ||
140 | static int sdk7786_mode_pins(void) | 140 | static int sdk7786_mode_pins(void) |
141 | { | 141 | { |
diff --git a/arch/sh/boards/mach-se/7206/setup.c b/arch/sh/boards/mach-se/7206/setup.c index 33039e0dc568..8ab8330e3fd1 100644 --- a/arch/sh/boards/mach-se/7206/setup.c +++ b/arch/sh/boards/mach-se/7206/setup.c | |||
@@ -77,7 +77,7 @@ static int __init se7206_devices_setup(void) | |||
77 | { | 77 | { |
78 | return platform_add_devices(se7206_devices, ARRAY_SIZE(se7206_devices)); | 78 | return platform_add_devices(se7206_devices, ARRAY_SIZE(se7206_devices)); |
79 | } | 79 | } |
80 | __initcall(se7206_devices_setup); | 80 | device_initcall(se7206_devices_setup); |
81 | 81 | ||
82 | static int se7206_mode_pins(void) | 82 | static int se7206_mode_pins(void) |
83 | { | 83 | { |
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c index 527a0cd956b5..527679394a25 100644 --- a/arch/sh/boards/mach-se/7724/setup.c +++ b/arch/sh/boards/mach-se/7724/setup.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | #include <linux/mfd/sh_mobile_sdhi.h> | 17 | #include <linux/mfd/sh_mobile_sdhi.h> |
18 | #include <linux/mmc/host.h> | ||
18 | #include <linux/mtd/physmap.h> | 19 | #include <linux/mtd/physmap.h> |
19 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
20 | #include <linux/smc91x.h> | 21 | #include <linux/smc91x.h> |
@@ -318,6 +319,10 @@ static struct platform_device fsi_device = { | |||
318 | }, | 319 | }, |
319 | }; | 320 | }; |
320 | 321 | ||
322 | static struct platform_device fsi_ak4642_device = { | ||
323 | .name = "sh_fsi_a_ak4642", | ||
324 | }; | ||
325 | |||
321 | /* KEYSC in SoC (Needs SW33-2 set to ON) */ | 326 | /* KEYSC in SoC (Needs SW33-2 set to ON) */ |
322 | static struct sh_keysc_info keysc_info = { | 327 | static struct sh_keysc_info keysc_info = { |
323 | .mode = SH_KEYSC_MODE_1, | 328 | .mode = SH_KEYSC_MODE_1, |
@@ -467,6 +472,7 @@ static struct resource sdhi0_cn7_resources[] = { | |||
467 | static struct sh_mobile_sdhi_info sh7724_sdhi0_data = { | 472 | static struct sh_mobile_sdhi_info sh7724_sdhi0_data = { |
468 | .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, | 473 | .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, |
469 | .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, | 474 | .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, |
475 | .tmio_caps = MMC_CAP_SDIO_IRQ, | ||
470 | }; | 476 | }; |
471 | 477 | ||
472 | static struct platform_device sdhi0_cn7_device = { | 478 | static struct platform_device sdhi0_cn7_device = { |
@@ -498,6 +504,7 @@ static struct resource sdhi1_cn8_resources[] = { | |||
498 | static struct sh_mobile_sdhi_info sh7724_sdhi1_data = { | 504 | static struct sh_mobile_sdhi_info sh7724_sdhi1_data = { |
499 | .dma_slave_tx = SHDMA_SLAVE_SDHI1_TX, | 505 | .dma_slave_tx = SHDMA_SLAVE_SDHI1_TX, |
500 | .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX, | 506 | .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX, |
507 | .tmio_caps = MMC_CAP_SDIO_IRQ, | ||
501 | }; | 508 | }; |
502 | 509 | ||
503 | static struct platform_device sdhi1_cn8_device = { | 510 | static struct platform_device sdhi1_cn8_device = { |
@@ -590,6 +597,7 @@ static struct platform_device *ms7724se_devices[] __initdata = { | |||
590 | &sh7724_usb0_host_device, | 597 | &sh7724_usb0_host_device, |
591 | &sh7724_usb1_gadget_device, | 598 | &sh7724_usb1_gadget_device, |
592 | &fsi_device, | 599 | &fsi_device, |
600 | &fsi_ak4642_device, | ||
593 | &sdhi0_cn7_device, | 601 | &sdhi0_cn7_device, |
594 | &sdhi1_cn8_device, | 602 | &sdhi1_cn8_device, |
595 | &irda_device, | 603 | &irda_device, |
diff --git a/arch/sh/boards/mach-se/7751/setup.c b/arch/sh/boards/mach-se/7751/setup.c index 9fbc51beb181..4ed60c5e221f 100644 --- a/arch/sh/boards/mach-se/7751/setup.c +++ b/arch/sh/boards/mach-se/7751/setup.c | |||
@@ -48,7 +48,7 @@ static int __init se7751_devices_setup(void) | |||
48 | { | 48 | { |
49 | return platform_add_devices(se7751_devices, ARRAY_SIZE(se7751_devices)); | 49 | return platform_add_devices(se7751_devices, ARRAY_SIZE(se7751_devices)); |
50 | } | 50 | } |
51 | __initcall(se7751_devices_setup); | 51 | device_initcall(se7751_devices_setup); |
52 | 52 | ||
53 | /* | 53 | /* |
54 | * The Machine Vector | 54 | * The Machine Vector |
diff --git a/arch/sh/boards/mach-sh03/rtc.c b/arch/sh/boards/mach-sh03/rtc.c index 1b200990500c..f83ac7995d0f 100644 --- a/arch/sh/boards/mach-sh03/rtc.c +++ b/arch/sh/boards/mach-sh03/rtc.c | |||
@@ -108,7 +108,7 @@ static int set_rtc_mmss(unsigned long nowtime) | |||
108 | __raw_writeb(real_minutes % 10, RTC_MIN1); | 108 | __raw_writeb(real_minutes % 10, RTC_MIN1); |
109 | __raw_writeb(real_minutes / 10, RTC_MIN10); | 109 | __raw_writeb(real_minutes / 10, RTC_MIN10); |
110 | } else { | 110 | } else { |
111 | printk(KERN_WARNING | 111 | printk_once(KERN_NOTICE |
112 | "set_rtc_mmss: can't update from %d to %d\n", | 112 | "set_rtc_mmss: can't update from %d to %d\n", |
113 | cmos_minutes, real_minutes); | 113 | cmos_minutes, real_minutes); |
114 | retval = -1; | 114 | retval = -1; |
diff --git a/arch/sh/boards/mach-sh03/setup.c b/arch/sh/boards/mach-sh03/setup.c index af4a0c012a96..d4f79b2a6514 100644 --- a/arch/sh/boards/mach-sh03/setup.c +++ b/arch/sh/boards/mach-sh03/setup.c | |||
@@ -96,7 +96,7 @@ static int __init sh03_devices_setup(void) | |||
96 | 96 | ||
97 | return platform_add_devices(sh03_devices, ARRAY_SIZE(sh03_devices)); | 97 | return platform_add_devices(sh03_devices, ARRAY_SIZE(sh03_devices)); |
98 | } | 98 | } |
99 | __initcall(sh03_devices_setup); | 99 | device_initcall(sh03_devices_setup); |
100 | 100 | ||
101 | static struct sh_machine_vector mv_sh03 __initmv = { | 101 | static struct sh_machine_vector mv_sh03 __initmv = { |
102 | .mv_name = "Interface (CTP/PCI-SH03)", | 102 | .mv_name = "Interface (CTP/PCI-SH03)", |
diff --git a/arch/sh/boot/romimage/mmcif-sh7724.c b/arch/sh/boot/romimage/mmcif-sh7724.c index 14863d7292cb..c84e7831018d 100644 --- a/arch/sh/boot/romimage/mmcif-sh7724.c +++ b/arch/sh/boot/romimage/mmcif-sh7724.c | |||
@@ -21,9 +21,6 @@ | |||
21 | #define HIZCRC 0xa405015c | 21 | #define HIZCRC 0xa405015c |
22 | #define DRVCRA 0xa405018a | 22 | #define DRVCRA 0xa405018a |
23 | 23 | ||
24 | enum { MMCIF_PROGRESS_ENTER, MMCIF_PROGRESS_INIT, | ||
25 | MMCIF_PROGRESS_LOAD, MMCIF_PROGRESS_DONE }; | ||
26 | |||
27 | /* SH7724 specific MMCIF loader | 24 | /* SH7724 specific MMCIF loader |
28 | * | 25 | * |
29 | * loads the romImage from an MMC card starting from block 512 | 26 | * loads the romImage from an MMC card starting from block 512 |
@@ -63,7 +60,9 @@ asmlinkage void mmcif_loader(unsigned char *buf, unsigned long no_bytes) | |||
63 | mmcif_update_progress(MMCIF_PROGRESS_LOAD); | 60 | mmcif_update_progress(MMCIF_PROGRESS_LOAD); |
64 | 61 | ||
65 | /* load kernel via MMCIF interface */ | 62 | /* load kernel via MMCIF interface */ |
66 | sh_mmcif_boot_slurp(MMCIF_BASE, buf, no_bytes); | 63 | sh_mmcif_boot_do_read(MMCIF_BASE, 512, |
64 | (no_bytes + SH_MMCIF_BBS - 1) / SH_MMCIF_BBS, | ||
65 | buf); | ||
67 | 66 | ||
68 | /* disable clock to the MMCIF hardware block */ | 67 | /* disable clock to the MMCIF hardware block */ |
69 | __raw_writel(__raw_readl(MSTPCR2) | 0x20000000, MSTPCR2); | 68 | __raw_writel(__raw_readl(MSTPCR2) | 0x20000000, MSTPCR2); |
diff --git a/arch/sh/configs/apsh4a3a_defconfig b/arch/sh/configs/apsh4a3a_defconfig new file mode 100644 index 000000000000..6cb327977d13 --- /dev/null +++ b/arch/sh/configs/apsh4a3a_defconfig | |||
@@ -0,0 +1,102 @@ | |||
1 | CONFIG_EXPERIMENTAL=y | ||
2 | CONFIG_SYSVIPC=y | ||
3 | CONFIG_BSD_PROCESS_ACCT=y | ||
4 | CONFIG_IKCONFIG=y | ||
5 | CONFIG_IKCONFIG_PROC=y | ||
6 | CONFIG_LOG_BUF_SHIFT=14 | ||
7 | CONFIG_SYSFS_DEPRECATED=y | ||
8 | CONFIG_SYSFS_DEPRECATED_V2=y | ||
9 | CONFIG_BLK_DEV_INITRD=y | ||
10 | CONFIG_SLAB=y | ||
11 | CONFIG_PROFILING=y | ||
12 | CONFIG_MODULES=y | ||
13 | CONFIG_MODULE_UNLOAD=y | ||
14 | # CONFIG_BLK_DEV_BSG is not set | ||
15 | CONFIG_CPU_SUBTYPE_SH7785=y | ||
16 | CONFIG_MEMORY_START=0x0C000000 | ||
17 | CONFIG_FLATMEM_MANUAL=y | ||
18 | CONFIG_SH_STORE_QUEUES=y | ||
19 | CONFIG_SH_APSH4A3A=y | ||
20 | CONFIG_HIGH_RES_TIMERS=y | ||
21 | CONFIG_KEXEC=y | ||
22 | CONFIG_PREEMPT=y | ||
23 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | ||
24 | CONFIG_NET=y | ||
25 | CONFIG_PACKET=y | ||
26 | CONFIG_UNIX=y | ||
27 | CONFIG_INET=y | ||
28 | CONFIG_IP_ADVANCED_ROUTER=y | ||
29 | CONFIG_IP_PNP=y | ||
30 | CONFIG_IP_PNP_DHCP=y | ||
31 | # CONFIG_INET_LRO is not set | ||
32 | # CONFIG_IPV6 is not set | ||
33 | # CONFIG_WIRELESS is not set | ||
34 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
35 | # CONFIG_FW_LOADER is not set | ||
36 | CONFIG_MTD=y | ||
37 | CONFIG_MTD_CONCAT=y | ||
38 | CONFIG_MTD_PARTITIONS=y | ||
39 | CONFIG_MTD_CHAR=y | ||
40 | CONFIG_MTD_BLOCK=y | ||
41 | CONFIG_MTD_CFI=y | ||
42 | CONFIG_MTD_CFI_AMDSTD=y | ||
43 | CONFIG_MTD_PHYSMAP=y | ||
44 | CONFIG_BLK_DEV_RAM=y | ||
45 | CONFIG_BLK_DEV_RAM_SIZE=16384 | ||
46 | CONFIG_NETDEVICES=y | ||
47 | CONFIG_NET_ETHERNET=y | ||
48 | CONFIG_SMSC911X=y | ||
49 | # CONFIG_NETDEV_1000 is not set | ||
50 | # CONFIG_NETDEV_10000 is not set | ||
51 | # CONFIG_WLAN is not set | ||
52 | # CONFIG_INPUT_MOUSEDEV is not set | ||
53 | # CONFIG_INPUT_KEYBOARD is not set | ||
54 | # CONFIG_INPUT_MOUSE is not set | ||
55 | # CONFIG_SERIO is not set | ||
56 | CONFIG_VT_HW_CONSOLE_BINDING=y | ||
57 | CONFIG_SERIAL_SH_SCI=y | ||
58 | CONFIG_SERIAL_SH_SCI_NR_UARTS=6 | ||
59 | CONFIG_SERIAL_SH_SCI_CONSOLE=y | ||
60 | CONFIG_HW_RANDOM=y | ||
61 | # CONFIG_HWMON is not set | ||
62 | CONFIG_FB=y | ||
63 | CONFIG_FB_SH7785FB=y | ||
64 | CONFIG_FRAMEBUFFER_CONSOLE=y | ||
65 | CONFIG_FONTS=y | ||
66 | CONFIG_FONT_8x8=y | ||
67 | CONFIG_FONT_8x16=y | ||
68 | CONFIG_LOGO=y | ||
69 | # CONFIG_HID_SUPPORT is not set | ||
70 | # CONFIG_USB_SUPPORT is not set | ||
71 | CONFIG_EXT2_FS=y | ||
72 | CONFIG_EXT3_FS=y | ||
73 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | ||
74 | CONFIG_MSDOS_FS=y | ||
75 | CONFIG_VFAT_FS=y | ||
76 | CONFIG_NTFS_FS=y | ||
77 | CONFIG_NTFS_RW=y | ||
78 | CONFIG_PROC_KCORE=y | ||
79 | CONFIG_TMPFS=y | ||
80 | CONFIG_JFFS2_FS=y | ||
81 | CONFIG_CRAMFS=y | ||
82 | CONFIG_NFS_FS=y | ||
83 | CONFIG_NFS_V3=y | ||
84 | CONFIG_NFS_V4=y | ||
85 | CONFIG_CIFS=y | ||
86 | CONFIG_NLS_DEFAULT="utf8" | ||
87 | CONFIG_NLS_CODEPAGE_437=y | ||
88 | CONFIG_NLS_CODEPAGE_932=y | ||
89 | CONFIG_NLS_ASCII=y | ||
90 | CONFIG_NLS_ISO8859_1=y | ||
91 | CONFIG_NLS_UTF8=y | ||
92 | # CONFIG_ENABLE_WARN_DEPRECATED is not set | ||
93 | # CONFIG_ENABLE_MUST_CHECK is not set | ||
94 | CONFIG_DEBUG_FS=y | ||
95 | CONFIG_DEBUG_KERNEL=y | ||
96 | # CONFIG_DEBUG_PREEMPT is not set | ||
97 | # CONFIG_DEBUG_BUGVERBOSE is not set | ||
98 | CONFIG_DEBUG_INFO=y | ||
99 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
100 | # CONFIG_FTRACE is not set | ||
101 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | ||
102 | # CONFIG_CRYPTO_HW is not set | ||
diff --git a/arch/sh/configs/apsh4ad0a_defconfig b/arch/sh/configs/apsh4ad0a_defconfig new file mode 100644 index 000000000000..e71a531f1e31 --- /dev/null +++ b/arch/sh/configs/apsh4ad0a_defconfig | |||
@@ -0,0 +1,133 @@ | |||
1 | CONFIG_EXPERIMENTAL=y | ||
2 | CONFIG_SYSVIPC=y | ||
3 | CONFIG_POSIX_MQUEUE=y | ||
4 | CONFIG_BSD_PROCESS_ACCT=y | ||
5 | CONFIG_RCU_TRACE=y | ||
6 | CONFIG_IKCONFIG=y | ||
7 | CONFIG_IKCONFIG_PROC=y | ||
8 | CONFIG_LOG_BUF_SHIFT=14 | ||
9 | CONFIG_CGROUPS=y | ||
10 | CONFIG_CGROUP_NS=y | ||
11 | CONFIG_CGROUP_FREEZER=y | ||
12 | CONFIG_CGROUP_DEVICE=y | ||
13 | CONFIG_CGROUP_CPUACCT=y | ||
14 | CONFIG_RESOURCE_COUNTERS=y | ||
15 | CONFIG_CGROUP_MEM_RES_CTLR=y | ||
16 | CONFIG_BLK_CGROUP=y | ||
17 | CONFIG_NAMESPACES=y | ||
18 | CONFIG_BLK_DEV_INITRD=y | ||
19 | CONFIG_KALLSYMS_ALL=y | ||
20 | # CONFIG_COMPAT_BRK is not set | ||
21 | CONFIG_SLAB=y | ||
22 | CONFIG_PROFILING=y | ||
23 | CONFIG_MODULES=y | ||
24 | CONFIG_MODULE_UNLOAD=y | ||
25 | # CONFIG_LBDAF is not set | ||
26 | # CONFIG_BLK_DEV_BSG is not set | ||
27 | CONFIG_CFQ_GROUP_IOSCHED=y | ||
28 | CONFIG_CPU_SUBTYPE_SH7786=y | ||
29 | CONFIG_MEMORY_SIZE=0x10000000 | ||
30 | CONFIG_HUGETLB_PAGE_SIZE_1MB=y | ||
31 | CONFIG_MEMORY_HOTPLUG=y | ||
32 | CONFIG_MEMORY_HOTREMOVE=y | ||
33 | CONFIG_KSM=y | ||
34 | CONFIG_SH_STORE_QUEUES=y | ||
35 | CONFIG_SH_APSH4AD0A=y | ||
36 | CONFIG_NO_HZ=y | ||
37 | CONFIG_HIGH_RES_TIMERS=y | ||
38 | CONFIG_CPU_FREQ=y | ||
39 | CONFIG_CPU_FREQ_GOV_POWERSAVE=m | ||
40 | CONFIG_CPU_FREQ_GOV_USERSPACE=m | ||
41 | CONFIG_CPU_FREQ_GOV_ONDEMAND=m | ||
42 | CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m | ||
43 | CONFIG_SH_CPU_FREQ=y | ||
44 | CONFIG_KEXEC=y | ||
45 | CONFIG_SECCOMP=y | ||
46 | CONFIG_PREEMPT=y | ||
47 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | ||
48 | CONFIG_BINFMT_MISC=y | ||
49 | CONFIG_PM=y | ||
50 | CONFIG_PM_DEBUG=y | ||
51 | CONFIG_PM_VERBOSE=y | ||
52 | CONFIG_PM_RUNTIME=y | ||
53 | CONFIG_CPU_IDLE=y | ||
54 | CONFIG_NET=y | ||
55 | CONFIG_PACKET=y | ||
56 | CONFIG_UNIX=y | ||
57 | CONFIG_NET_KEY=y | ||
58 | CONFIG_INET=y | ||
59 | # CONFIG_INET_LRO is not set | ||
60 | # CONFIG_IPV6 is not set | ||
61 | # CONFIG_WIRELESS is not set | ||
62 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
63 | # CONFIG_FW_LOADER is not set | ||
64 | CONFIG_MTD=y | ||
65 | CONFIG_MTD_CFI=y | ||
66 | CONFIG_BLK_DEV_RAM=y | ||
67 | CONFIG_BLK_DEV_RAM_SIZE=16384 | ||
68 | CONFIG_SCSI=y | ||
69 | CONFIG_BLK_DEV_SD=y | ||
70 | CONFIG_SCSI_MULTI_LUN=y | ||
71 | # CONFIG_SCSI_LOWLEVEL is not set | ||
72 | CONFIG_NETDEVICES=y | ||
73 | CONFIG_MDIO_BITBANG=y | ||
74 | CONFIG_NET_ETHERNET=y | ||
75 | CONFIG_SMSC911X=y | ||
76 | # CONFIG_NETDEV_1000 is not set | ||
77 | # CONFIG_NETDEV_10000 is not set | ||
78 | # CONFIG_WLAN is not set | ||
79 | CONFIG_INPUT_EVDEV=y | ||
80 | # CONFIG_INPUT_KEYBOARD is not set | ||
81 | # CONFIG_INPUT_MOUSE is not set | ||
82 | # CONFIG_SERIO is not set | ||
83 | CONFIG_SERIAL_SH_SCI=y | ||
84 | CONFIG_SERIAL_SH_SCI_NR_UARTS=6 | ||
85 | CONFIG_SERIAL_SH_SCI_CONSOLE=y | ||
86 | # CONFIG_LEGACY_PTYS is not set | ||
87 | # CONFIG_HW_RANDOM is not set | ||
88 | # CONFIG_HWMON is not set | ||
89 | CONFIG_VIDEO_OUTPUT_CONTROL=y | ||
90 | CONFIG_FB=y | ||
91 | CONFIG_FB_SH7785FB=y | ||
92 | CONFIG_FRAMEBUFFER_CONSOLE=y | ||
93 | CONFIG_FONTS=y | ||
94 | CONFIG_FONT_8x8=y | ||
95 | CONFIG_FONT_8x16=y | ||
96 | CONFIG_LOGO=y | ||
97 | CONFIG_USB=y | ||
98 | CONFIG_USB_DEBUG=y | ||
99 | CONFIG_USB_MON=y | ||
100 | CONFIG_USB_OHCI_HCD=y | ||
101 | CONFIG_USB_STORAGE=y | ||
102 | CONFIG_EXT2_FS=y | ||
103 | CONFIG_EXT3_FS=y | ||
104 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | ||
105 | CONFIG_MSDOS_FS=y | ||
106 | CONFIG_VFAT_FS=y | ||
107 | CONFIG_NTFS_FS=y | ||
108 | CONFIG_NTFS_RW=y | ||
109 | CONFIG_PROC_KCORE=y | ||
110 | CONFIG_TMPFS=y | ||
111 | CONFIG_HUGETLBFS=y | ||
112 | CONFIG_JFFS2_FS=y | ||
113 | CONFIG_CRAMFS=y | ||
114 | CONFIG_NFS_FS=y | ||
115 | CONFIG_NFS_V3=y | ||
116 | CONFIG_NFS_V4=y | ||
117 | CONFIG_CIFS=y | ||
118 | CONFIG_NLS_DEFAULT="utf8" | ||
119 | CONFIG_NLS_CODEPAGE_437=y | ||
120 | CONFIG_NLS_CODEPAGE_932=y | ||
121 | CONFIG_NLS_ASCII=y | ||
122 | CONFIG_NLS_ISO8859_1=y | ||
123 | CONFIG_NLS_UTF8=y | ||
124 | # CONFIG_ENABLE_MUST_CHECK is not set | ||
125 | CONFIG_MAGIC_SYSRQ=y | ||
126 | CONFIG_DEBUG_KERNEL=y | ||
127 | CONFIG_DEBUG_SHIRQ=y | ||
128 | CONFIG_DETECT_HUNG_TASK=y | ||
129 | CONFIG_DEBUG_INFO=y | ||
130 | CONFIG_DEBUG_VM=y | ||
131 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
132 | CONFIG_DWARF_UNWINDER=y | ||
133 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | ||
diff --git a/arch/sh/configs/sh7757lcr_defconfig b/arch/sh/configs/sh7757lcr_defconfig index 273f3fa198f7..5f7f667b9f3b 100644 --- a/arch/sh/configs/sh7757lcr_defconfig +++ b/arch/sh/configs/sh7757lcr_defconfig | |||
@@ -39,21 +39,15 @@ CONFIG_IPV6=y | |||
39 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | 39 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" |
40 | # CONFIG_FW_LOADER is not set | 40 | # CONFIG_FW_LOADER is not set |
41 | CONFIG_BLK_DEV_RAM=y | 41 | CONFIG_BLK_DEV_RAM=y |
42 | # CONFIG_MISC_DEVICES is not set | ||
43 | CONFIG_NETDEVICES=y | 42 | CONFIG_NETDEVICES=y |
44 | CONFIG_PHYLIB=y | ||
45 | CONFIG_VITESSE_PHY=y | 43 | CONFIG_VITESSE_PHY=y |
46 | CONFIG_MDIO_BITBANG=y | ||
47 | CONFIG_NET_ETHERNET=y | 44 | CONFIG_NET_ETHERNET=y |
48 | CONFIG_MII=y | 45 | CONFIG_SH_ETH=y |
49 | # CONFIG_NETDEV_10000 is not set | 46 | # CONFIG_NETDEV_10000 is not set |
50 | # CONFIG_WLAN is not set | 47 | # CONFIG_WLAN is not set |
51 | # CONFIG_KEYBOARD_ATKBD is not set | 48 | # CONFIG_KEYBOARD_ATKBD is not set |
52 | # CONFIG_MOUSE_PS2 is not set | 49 | # CONFIG_MOUSE_PS2 is not set |
53 | # CONFIG_SERIO is not set | 50 | # CONFIG_SERIO is not set |
54 | CONFIG_SERIAL_8250=y | ||
55 | CONFIG_SERIAL_8250_CONSOLE=y | ||
56 | CONFIG_SERIAL_8250_NR_UARTS=2 | ||
57 | CONFIG_SERIAL_SH_SCI=y | 51 | CONFIG_SERIAL_SH_SCI=y |
58 | CONFIG_SERIAL_SH_SCI_NR_UARTS=3 | 52 | CONFIG_SERIAL_SH_SCI_NR_UARTS=3 |
59 | CONFIG_SERIAL_SH_SCI_CONSOLE=y | 53 | CONFIG_SERIAL_SH_SCI_CONSOLE=y |
@@ -63,7 +57,6 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y | |||
63 | # CONFIG_USB_SUPPORT is not set | 57 | # CONFIG_USB_SUPPORT is not set |
64 | CONFIG_EXT2_FS=y | 58 | CONFIG_EXT2_FS=y |
65 | CONFIG_EXT3_FS=y | 59 | CONFIG_EXT3_FS=y |
66 | CONFIG_INOTIFY=y | ||
67 | CONFIG_ISO9660_FS=y | 60 | CONFIG_ISO9660_FS=y |
68 | CONFIG_VFAT_FS=y | 61 | CONFIG_VFAT_FS=y |
69 | CONFIG_PROC_KCORE=y | 62 | CONFIG_PROC_KCORE=y |
@@ -76,10 +69,8 @@ CONFIG_NLS_CODEPAGE_437=y | |||
76 | CONFIG_NLS_CODEPAGE_932=y | 69 | CONFIG_NLS_CODEPAGE_932=y |
77 | CONFIG_NLS_ISO8859_1=y | 70 | CONFIG_NLS_ISO8859_1=y |
78 | CONFIG_DEBUG_KERNEL=y | 71 | CONFIG_DEBUG_KERNEL=y |
79 | # CONFIG_DETECT_SOFTLOCKUP is not set | ||
80 | # CONFIG_SCHED_DEBUG is not set | 72 | # CONFIG_SCHED_DEBUG is not set |
81 | # CONFIG_DEBUG_BUGVERBOSE is not set | 73 | # CONFIG_DEBUG_BUGVERBOSE is not set |
82 | CONFIG_DEBUG_INFO=y | 74 | CONFIG_DEBUG_INFO=y |
83 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
84 | # CONFIG_FTRACE is not set | 75 | # CONFIG_FTRACE is not set |
85 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 76 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
diff --git a/arch/sh/drivers/pci/fixups-landisk.c b/arch/sh/drivers/pci/fixups-landisk.c index bb1a6bb5149e..95c6e2d94a0a 100644 --- a/arch/sh/drivers/pci/fixups-landisk.c +++ b/arch/sh/drivers/pci/fixups-landisk.c | |||
@@ -1,9 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | * arch/sh/drivers/pci/ops-landisk.c | 2 | * arch/sh/drivers/pci/fixups-landisk.c |
3 | * | 3 | * |
4 | * PCI initialization for the I-O DATA Device, Inc. LANDISK board | 4 | * PCI initialization for the I-O DATA Device, Inc. LANDISK board |
5 | * | 5 | * |
6 | * Copyright (C) 2006 kogiidena | 6 | * Copyright (C) 2006 kogiidena |
7 | * Copyright (C) 2010 Nobuhiro Iwamatsu | ||
7 | * | 8 | * |
8 | * May be copied or modified under the terms of the GNU General Public | 9 | * May be copied or modified under the terms of the GNU General Public |
9 | * License. See linux/COPYING for more information. | 10 | * License. See linux/COPYING for more information. |
@@ -15,6 +16,9 @@ | |||
15 | #include <linux/pci.h> | 16 | #include <linux/pci.h> |
16 | #include "pci-sh4.h" | 17 | #include "pci-sh4.h" |
17 | 18 | ||
19 | #define PCIMCR_MRSET_OFF 0xBFFFFFFF | ||
20 | #define PCIMCR_RFSH_OFF 0xFFFFFFFB | ||
21 | |||
18 | int pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) | 22 | int pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) |
19 | { | 23 | { |
20 | /* | 24 | /* |
@@ -26,9 +30,29 @@ int pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) | |||
26 | int irq = ((slot + pin - 1) & 0x3) + 5; | 30 | int irq = ((slot + pin - 1) & 0x3) + 5; |
27 | 31 | ||
28 | if ((slot | (pin - 1)) > 0x3) { | 32 | if ((slot | (pin - 1)) > 0x3) { |
29 | printk("PCI: Bad IRQ mapping request for slot %d pin %c\n", | 33 | printk(KERN_WARNING "PCI: Bad IRQ mapping request for slot %d pin %c\n", |
30 | slot, pin - 1 + 'A'); | 34 | slot, pin - 1 + 'A'); |
31 | return -1; | 35 | return -1; |
32 | } | 36 | } |
33 | return irq; | 37 | return irq; |
34 | } | 38 | } |
39 | |||
40 | int pci_fixup_pcic(struct pci_channel *chan) | ||
41 | { | ||
42 | unsigned long bcr1, mcr; | ||
43 | |||
44 | bcr1 = __raw_readl(SH7751_BCR1); | ||
45 | bcr1 |= 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */ | ||
46 | pci_write_reg(chan, bcr1, SH4_PCIBCR1); | ||
47 | |||
48 | mcr = __raw_readl(SH7751_MCR); | ||
49 | mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF; | ||
50 | pci_write_reg(chan, mcr, SH4_PCIMCR); | ||
51 | |||
52 | pci_write_reg(chan, 0x0c000000, SH7751_PCICONF5); | ||
53 | pci_write_reg(chan, 0xd0000000, SH7751_PCICONF6); | ||
54 | pci_write_reg(chan, 0x0c000000, SH4_PCILAR0); | ||
55 | pci_write_reg(chan, 0x00000000, SH4_PCILAR1); | ||
56 | |||
57 | return 0; | ||
58 | } | ||
diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index 89ab2c57a4c2..28c5aa58bb45 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h | |||
@@ -11,11 +11,6 @@ | |||
11 | * | 11 | * |
12 | * While read{b,w,l,q} and write{b,w,l,q} contain memory barriers | 12 | * While read{b,w,l,q} and write{b,w,l,q} contain memory barriers |
13 | * automatically, there are also __raw versions, which do not. | 13 | * automatically, there are also __raw versions, which do not. |
14 | * | ||
15 | * Historically, we have also had ctrl_in{b,w,l,q}/ctrl_out{b,w,l,q} for | ||
16 | * SuperH specific I/O (raw I/O to on-chip CPU peripherals). In practice | ||
17 | * these have the same semantics as the __raw variants, and as such, all | ||
18 | * new code should be using the __raw versions. | ||
19 | */ | 14 | */ |
20 | #include <linux/errno.h> | 15 | #include <linux/errno.h> |
21 | #include <asm/cache.h> | 16 | #include <asm/cache.h> |
@@ -231,52 +226,6 @@ __BUILD_IOPORT_STRING(q, u64) | |||
231 | 226 | ||
232 | #endif | 227 | #endif |
233 | 228 | ||
234 | /* | ||
235 | * Legacy SuperH on-chip I/O functions | ||
236 | * | ||
237 | * These are all deprecated, all new (and especially cross-platform) code | ||
238 | * should be using the __raw_xxx() routines directly. | ||
239 | */ | ||
240 | static inline u8 __deprecated ctrl_inb(unsigned long addr) | ||
241 | { | ||
242 | return __raw_readb(addr); | ||
243 | } | ||
244 | |||
245 | static inline u16 __deprecated ctrl_inw(unsigned long addr) | ||
246 | { | ||
247 | return __raw_readw(addr); | ||
248 | } | ||
249 | |||
250 | static inline u32 __deprecated ctrl_inl(unsigned long addr) | ||
251 | { | ||
252 | return __raw_readl(addr); | ||
253 | } | ||
254 | |||
255 | static inline u64 __deprecated ctrl_inq(unsigned long addr) | ||
256 | { | ||
257 | return __raw_readq(addr); | ||
258 | } | ||
259 | |||
260 | static inline void __deprecated ctrl_outb(u8 v, unsigned long addr) | ||
261 | { | ||
262 | __raw_writeb(v, addr); | ||
263 | } | ||
264 | |||
265 | static inline void __deprecated ctrl_outw(u16 v, unsigned long addr) | ||
266 | { | ||
267 | __raw_writew(v, addr); | ||
268 | } | ||
269 | |||
270 | static inline void __deprecated ctrl_outl(u32 v, unsigned long addr) | ||
271 | { | ||
272 | __raw_writel(v, addr); | ||
273 | } | ||
274 | |||
275 | static inline void __deprecated ctrl_outq(u64 v, unsigned long addr) | ||
276 | { | ||
277 | __raw_writeq(v, addr); | ||
278 | } | ||
279 | |||
280 | #define IO_SPACE_LIMIT 0xffffffff | 229 | #define IO_SPACE_LIMIT 0xffffffff |
281 | 230 | ||
282 | /* synco on SH-4A, otherwise a nop */ | 231 | /* synco on SH-4A, otherwise a nop */ |
@@ -341,7 +290,15 @@ __ioremap_29bit(phys_addr_t offset, unsigned long size, pgprot_t prot) | |||
341 | * mapping must be done by the PMB or by using page tables. | 290 | * mapping must be done by the PMB or by using page tables. |
342 | */ | 291 | */ |
343 | if (likely(PXSEG(offset) < P3SEG && PXSEG(last_addr) < P3SEG)) { | 292 | if (likely(PXSEG(offset) < P3SEG && PXSEG(last_addr) < P3SEG)) { |
344 | if (unlikely(pgprot_val(prot) & _PAGE_CACHABLE)) | 293 | u64 flags = pgprot_val(prot); |
294 | |||
295 | /* | ||
296 | * Anything using the legacy PTEA space attributes needs | ||
297 | * to be kicked down to page table mappings. | ||
298 | */ | ||
299 | if (unlikely(flags & _PAGE_PCC_MASK)) | ||
300 | return NULL; | ||
301 | if (unlikely(flags & _PAGE_CACHABLE)) | ||
345 | return (void __iomem *)P1SEGADDR(offset); | 302 | return (void __iomem *)P1SEGADDR(offset); |
346 | 303 | ||
347 | return (void __iomem *)P2SEGADDR(offset); | 304 | return (void __iomem *)P2SEGADDR(offset); |
diff --git a/arch/sh/include/asm/machvec.h b/arch/sh/include/asm/machvec.h index dd5d6e5bf204..57c5c3d0f39f 100644 --- a/arch/sh/include/asm/machvec.h +++ b/arch/sh/include/asm/machvec.h | |||
@@ -31,6 +31,7 @@ struct sh_machine_vector { | |||
31 | int (*mv_mode_pins)(void); | 31 | int (*mv_mode_pins)(void); |
32 | 32 | ||
33 | void (*mv_mem_init)(void); | 33 | void (*mv_mem_init)(void); |
34 | void (*mv_mem_reserve)(void); | ||
34 | }; | 35 | }; |
35 | 36 | ||
36 | extern struct sh_machine_vector sh_mv; | 37 | extern struct sh_machine_vector sh_mv; |
diff --git a/arch/sh/include/asm/pgtable_32.h b/arch/sh/include/asm/pgtable_32.h index 43528ec656ba..b799fe71114c 100644 --- a/arch/sh/include/asm/pgtable_32.h +++ b/arch/sh/include/asm/pgtable_32.h | |||
@@ -76,6 +76,10 @@ | |||
76 | /* Wrapper for extended mode pgprot twiddling */ | 76 | /* Wrapper for extended mode pgprot twiddling */ |
77 | #define _PAGE_EXT(x) ((unsigned long long)(x) << 32) | 77 | #define _PAGE_EXT(x) ((unsigned long long)(x) << 32) |
78 | 78 | ||
79 | #ifdef CONFIG_X2TLB | ||
80 | #define _PAGE_PCC_MASK 0x00000000 /* No legacy PTEA support */ | ||
81 | #else | ||
82 | |||
79 | /* software: moves to PTEA.TC (Timing Control) */ | 83 | /* software: moves to PTEA.TC (Timing Control) */ |
80 | #define _PAGE_PCC_AREA5 0x00000000 /* use BSC registers for area5 */ | 84 | #define _PAGE_PCC_AREA5 0x00000000 /* use BSC registers for area5 */ |
81 | #define _PAGE_PCC_AREA6 0x80000000 /* use BSC registers for area6 */ | 85 | #define _PAGE_PCC_AREA6 0x80000000 /* use BSC registers for area6 */ |
@@ -89,7 +93,8 @@ | |||
89 | #define _PAGE_PCC_ATR8 0x60000000 /* Attribute Memory space, 8 bit bus */ | 93 | #define _PAGE_PCC_ATR8 0x60000000 /* Attribute Memory space, 8 bit bus */ |
90 | #define _PAGE_PCC_ATR16 0x60000001 /* Attribute Memory space, 6 bit bus */ | 94 | #define _PAGE_PCC_ATR16 0x60000001 /* Attribute Memory space, 6 bit bus */ |
91 | 95 | ||
92 | #ifndef CONFIG_X2TLB | 96 | #define _PAGE_PCC_MASK 0xe0000001 |
97 | |||
93 | /* copy the ptea attributes */ | 98 | /* copy the ptea attributes */ |
94 | static inline unsigned long copy_ptea_attributes(unsigned long x) | 99 | static inline unsigned long copy_ptea_attributes(unsigned long x) |
95 | { | 100 | { |
@@ -231,13 +236,7 @@ static inline unsigned long copy_ptea_attributes(unsigned long x) | |||
231 | _PAGE_EXT_KERN_EXEC)) | 236 | _PAGE_EXT_KERN_EXEC)) |
232 | 237 | ||
233 | #define PAGE_KERNEL_PCC(slot, type) \ | 238 | #define PAGE_KERNEL_PCC(slot, type) \ |
234 | __pgprot(_PAGE_PRESENT | _PAGE_DIRTY | \ | 239 | __pgprot(0) |
235 | _PAGE_ACCESSED | _PAGE_FLAGS_HARD | \ | ||
236 | _PAGE_EXT(_PAGE_EXT_KERN_READ | \ | ||
237 | _PAGE_EXT_KERN_WRITE | \ | ||
238 | _PAGE_EXT_KERN_EXEC) \ | ||
239 | (slot ? _PAGE_PCC_AREA5 : _PAGE_PCC_AREA6) | \ | ||
240 | (type)) | ||
241 | 240 | ||
242 | #elif defined(CONFIG_MMU) /* SH-X TLB */ | 241 | #elif defined(CONFIG_MMU) /* SH-X TLB */ |
243 | #define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_CACHABLE | \ | 242 | #define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_CACHABLE | \ |
diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h index c9e7cbc4768a..9c7bdfcaebbd 100644 --- a/arch/sh/include/asm/processor.h +++ b/arch/sh/include/asm/processor.h | |||
@@ -35,7 +35,7 @@ enum cpu_type { | |||
35 | CPU_SH7723, CPU_SH7724, CPU_SH7757, CPU_SHX3, | 35 | CPU_SH7723, CPU_SH7724, CPU_SH7757, CPU_SHX3, |
36 | 36 | ||
37 | /* SH4AL-DSP types */ | 37 | /* SH4AL-DSP types */ |
38 | CPU_SH7343, CPU_SH7722, CPU_SH7366, | 38 | CPU_SH7343, CPU_SH7722, CPU_SH7366, CPU_SH7372, |
39 | 39 | ||
40 | /* SH-5 types */ | 40 | /* SH-5 types */ |
41 | CPU_SH5_101, CPU_SH5_103, | 41 | CPU_SH5_101, CPU_SH5_103, |
diff --git a/arch/sh/include/asm/processor_32.h b/arch/sh/include/asm/processor_32.h index e3c73cdd8c90..900f8d72ffe2 100644 --- a/arch/sh/include/asm/processor_32.h +++ b/arch/sh/include/asm/processor_32.h | |||
@@ -194,15 +194,17 @@ extern unsigned long get_wchan(struct task_struct *p); | |||
194 | #define KSTK_ESP(tsk) (task_pt_regs(tsk)->regs[15]) | 194 | #define KSTK_ESP(tsk) (task_pt_regs(tsk)->regs[15]) |
195 | 195 | ||
196 | #if defined(CONFIG_CPU_SH2A) || defined(CONFIG_CPU_SH4) | 196 | #if defined(CONFIG_CPU_SH2A) || defined(CONFIG_CPU_SH4) |
197 | |||
197 | #define PREFETCH_STRIDE L1_CACHE_BYTES | 198 | #define PREFETCH_STRIDE L1_CACHE_BYTES |
198 | #define ARCH_HAS_PREFETCH | 199 | #define ARCH_HAS_PREFETCH |
199 | #define ARCH_HAS_PREFETCHW | 200 | #define ARCH_HAS_PREFETCHW |
200 | static inline void prefetch(void *x) | 201 | |
202 | static inline void prefetch(const void *x) | ||
201 | { | 203 | { |
202 | __builtin_prefetch(x, 0, 3); | 204 | __builtin_prefetch(x, 0, 3); |
203 | } | 205 | } |
204 | 206 | ||
205 | static inline void prefetchw(void *x) | 207 | static inline void prefetchw(const void *x) |
206 | { | 208 | { |
207 | __builtin_prefetch(x, 1, 3); | 209 | __builtin_prefetch(x, 1, 3); |
208 | } | 210 | } |
diff --git a/arch/sh/include/mach-landisk/mach/iodata_landisk.h b/arch/sh/include/mach-landisk/mach/iodata_landisk.h index 6fb04ab38b9f..f432773a9571 100644 --- a/arch/sh/include/mach-landisk/mach/iodata_landisk.h +++ b/arch/sh/include/mach-landisk/mach/iodata_landisk.h | |||
@@ -2,7 +2,7 @@ | |||
2 | #define __ASM_SH_IODATA_LANDISK_H | 2 | #define __ASM_SH_IODATA_LANDISK_H |
3 | 3 | ||
4 | /* | 4 | /* |
5 | * linux/include/asm-sh/landisk/iodata_landisk.h | 5 | * arch/sh/include/mach-landisk/mach/iodata_landisk.h |
6 | * | 6 | * |
7 | * Copyright (C) 2000 Atom Create Engineering Co., Ltd. | 7 | * Copyright (C) 2000 Atom Create Engineering Co., Ltd. |
8 | * | 8 | * |
@@ -27,7 +27,7 @@ | |||
27 | 27 | ||
28 | #define IRQ_PCIINTA 5 /* PCI INTA IRQ */ | 28 | #define IRQ_PCIINTA 5 /* PCI INTA IRQ */ |
29 | #define IRQ_PCIINTB 6 /* PCI INTB IRQ */ | 29 | #define IRQ_PCIINTB 6 /* PCI INTB IRQ */ |
30 | #define IRQ_PCIINDC 7 /* PCI INTC IRQ */ | 30 | #define IRQ_PCIINTC 7 /* PCI INTC IRQ */ |
31 | #define IRQ_PCIINTD 8 /* PCI INTD IRQ */ | 31 | #define IRQ_PCIINTD 8 /* PCI INTD IRQ */ |
32 | #define IRQ_ATA 9 /* ATA IRQ */ | 32 | #define IRQ_ATA 9 /* ATA IRQ */ |
33 | #define IRQ_FATA 10 /* FATA IRQ */ | 33 | #define IRQ_FATA 10 /* FATA IRQ */ |
@@ -35,6 +35,8 @@ | |||
35 | #define IRQ_BUTTON 12 /* USL-5P Button IRQ */ | 35 | #define IRQ_BUTTON 12 /* USL-5P Button IRQ */ |
36 | #define IRQ_FAULT 13 /* USL-5P Fault IRQ */ | 36 | #define IRQ_FAULT 13 /* USL-5P Fault IRQ */ |
37 | 37 | ||
38 | void init_landisk_IRQ(void); | ||
39 | |||
38 | #define __IO_PREFIX landisk | 40 | #define __IO_PREFIX landisk |
39 | #include <asm/io_generic.h> | 41 | #include <asm/io_generic.h> |
40 | 42 | ||
diff --git a/arch/sh/kernel/cpu/proc.c b/arch/sh/kernel/cpu/proc.c index e80a936f409a..f47be8727b3b 100644 --- a/arch/sh/kernel/cpu/proc.c +++ b/arch/sh/kernel/cpu/proc.c | |||
@@ -25,7 +25,7 @@ static const char *cpu_name[] = { | |||
25 | [CPU_SH5_101] = "SH5-101", [CPU_SH5_103] = "SH5-103", | 25 | [CPU_SH5_101] = "SH5-101", [CPU_SH5_103] = "SH5-103", |
26 | [CPU_MXG] = "MX-G", [CPU_SH7723] = "SH7723", | 26 | [CPU_MXG] = "MX-G", [CPU_SH7723] = "SH7723", |
27 | [CPU_SH7366] = "SH7366", [CPU_SH7724] = "SH7724", | 27 | [CPU_SH7366] = "SH7366", [CPU_SH7724] = "SH7724", |
28 | [CPU_SH_NONE] = "Unknown" | 28 | [CPU_SH7372] = "SH7372", [CPU_SH_NONE] = "Unknown" |
29 | }; | 29 | }; |
30 | 30 | ||
31 | const char *get_cpu_subtype(struct sh_cpuinfo *c) | 31 | const char *get_cpu_subtype(struct sh_cpuinfo *c) |
diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c index c3638516bffc..0f8befccf9fa 100644 --- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c +++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c | |||
@@ -62,6 +62,8 @@ static DECLARE_INTC_DESC(intc_desc, "sh7619", vectors, NULL, | |||
62 | static struct plat_sci_port scif0_platform_data = { | 62 | static struct plat_sci_port scif0_platform_data = { |
63 | .mapbase = 0xf8400000, | 63 | .mapbase = 0xf8400000, |
64 | .flags = UPF_BOOT_AUTOCONF, | 64 | .flags = UPF_BOOT_AUTOCONF, |
65 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
66 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
65 | .type = PORT_SCIF, | 67 | .type = PORT_SCIF, |
66 | .irqs = { 88, 88, 88, 88 }, | 68 | .irqs = { 88, 88, 88, 88 }, |
67 | }; | 69 | }; |
@@ -77,6 +79,8 @@ static struct platform_device scif0_device = { | |||
77 | static struct plat_sci_port scif1_platform_data = { | 79 | static struct plat_sci_port scif1_platform_data = { |
78 | .mapbase = 0xf8410000, | 80 | .mapbase = 0xf8410000, |
79 | .flags = UPF_BOOT_AUTOCONF, | 81 | .flags = UPF_BOOT_AUTOCONF, |
82 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
83 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
80 | .type = PORT_SCIF, | 84 | .type = PORT_SCIF, |
81 | .irqs = { 92, 92, 92, 92 }, | 85 | .irqs = { 92, 92, 92, 92 }, |
82 | }; | 86 | }; |
@@ -92,6 +96,8 @@ static struct platform_device scif1_device = { | |||
92 | static struct plat_sci_port scif2_platform_data = { | 96 | static struct plat_sci_port scif2_platform_data = { |
93 | .mapbase = 0xf8420000, | 97 | .mapbase = 0xf8420000, |
94 | .flags = UPF_BOOT_AUTOCONF, | 98 | .flags = UPF_BOOT_AUTOCONF, |
99 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
100 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
95 | .type = PORT_SCIF, | 101 | .type = PORT_SCIF, |
96 | .irqs = { 96, 96, 96, 96 }, | 102 | .irqs = { 96, 96, 96, 96 }, |
97 | }; | 103 | }; |
diff --git a/arch/sh/kernel/cpu/sh2a/setup-mxg.c b/arch/sh/kernel/cpu/sh2a/setup-mxg.c index 6c96ea02bf8d..949bf2bac28c 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-mxg.c +++ b/arch/sh/kernel/cpu/sh2a/setup-mxg.c | |||
@@ -201,6 +201,8 @@ static struct platform_device mtu2_2_device = { | |||
201 | static struct plat_sci_port scif0_platform_data = { | 201 | static struct plat_sci_port scif0_platform_data = { |
202 | .mapbase = 0xff804000, | 202 | .mapbase = 0xff804000, |
203 | .flags = UPF_BOOT_AUTOCONF, | 203 | .flags = UPF_BOOT_AUTOCONF, |
204 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
205 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
204 | .type = PORT_SCIF, | 206 | .type = PORT_SCIF, |
205 | .irqs = { 220, 220, 220, 220 }, | 207 | .irqs = { 220, 220, 220, 220 }, |
206 | }; | 208 | }; |
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c index d08bf4c07d60..9df558dcdb86 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c | |||
@@ -180,6 +180,8 @@ static DECLARE_INTC_DESC(intc_desc, "sh7201", vectors, groups, | |||
180 | static struct plat_sci_port scif0_platform_data = { | 180 | static struct plat_sci_port scif0_platform_data = { |
181 | .mapbase = 0xfffe8000, | 181 | .mapbase = 0xfffe8000, |
182 | .flags = UPF_BOOT_AUTOCONF, | 182 | .flags = UPF_BOOT_AUTOCONF, |
183 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
184 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
183 | .type = PORT_SCIF, | 185 | .type = PORT_SCIF, |
184 | .irqs = { 180, 180, 180, 180 } | 186 | .irqs = { 180, 180, 180, 180 } |
185 | }; | 187 | }; |
@@ -195,6 +197,8 @@ static struct platform_device scif0_device = { | |||
195 | static struct plat_sci_port scif1_platform_data = { | 197 | static struct plat_sci_port scif1_platform_data = { |
196 | .mapbase = 0xfffe8800, | 198 | .mapbase = 0xfffe8800, |
197 | .flags = UPF_BOOT_AUTOCONF, | 199 | .flags = UPF_BOOT_AUTOCONF, |
200 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
201 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
198 | .type = PORT_SCIF, | 202 | .type = PORT_SCIF, |
199 | .irqs = { 184, 184, 184, 184 } | 203 | .irqs = { 184, 184, 184, 184 } |
200 | }; | 204 | }; |
@@ -210,6 +214,8 @@ static struct platform_device scif1_device = { | |||
210 | static struct plat_sci_port scif2_platform_data = { | 214 | static struct plat_sci_port scif2_platform_data = { |
211 | .mapbase = 0xfffe9000, | 215 | .mapbase = 0xfffe9000, |
212 | .flags = UPF_BOOT_AUTOCONF, | 216 | .flags = UPF_BOOT_AUTOCONF, |
217 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
218 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
213 | .type = PORT_SCIF, | 219 | .type = PORT_SCIF, |
214 | .irqs = { 188, 188, 188, 188 } | 220 | .irqs = { 188, 188, 188, 188 } |
215 | }; | 221 | }; |
@@ -225,6 +231,8 @@ static struct platform_device scif2_device = { | |||
225 | static struct plat_sci_port scif3_platform_data = { | 231 | static struct plat_sci_port scif3_platform_data = { |
226 | .mapbase = 0xfffe9800, | 232 | .mapbase = 0xfffe9800, |
227 | .flags = UPF_BOOT_AUTOCONF, | 233 | .flags = UPF_BOOT_AUTOCONF, |
234 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
235 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
228 | .type = PORT_SCIF, | 236 | .type = PORT_SCIF, |
229 | .irqs = { 192, 192, 192, 192 } | 237 | .irqs = { 192, 192, 192, 192 } |
230 | }; | 238 | }; |
@@ -240,6 +248,8 @@ static struct platform_device scif3_device = { | |||
240 | static struct plat_sci_port scif4_platform_data = { | 248 | static struct plat_sci_port scif4_platform_data = { |
241 | .mapbase = 0xfffea000, | 249 | .mapbase = 0xfffea000, |
242 | .flags = UPF_BOOT_AUTOCONF, | 250 | .flags = UPF_BOOT_AUTOCONF, |
251 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
252 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
243 | .type = PORT_SCIF, | 253 | .type = PORT_SCIF, |
244 | .irqs = { 196, 196, 196, 196 } | 254 | .irqs = { 196, 196, 196, 196 } |
245 | }; | 255 | }; |
@@ -255,6 +265,8 @@ static struct platform_device scif4_device = { | |||
255 | static struct plat_sci_port scif5_platform_data = { | 265 | static struct plat_sci_port scif5_platform_data = { |
256 | .mapbase = 0xfffea800, | 266 | .mapbase = 0xfffea800, |
257 | .flags = UPF_BOOT_AUTOCONF, | 267 | .flags = UPF_BOOT_AUTOCONF, |
268 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
269 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
258 | .type = PORT_SCIF, | 270 | .type = PORT_SCIF, |
259 | .irqs = { 200, 200, 200, 200 } | 271 | .irqs = { 200, 200, 200, 200 } |
260 | }; | 272 | }; |
@@ -270,6 +282,8 @@ static struct platform_device scif5_device = { | |||
270 | static struct plat_sci_port scif6_platform_data = { | 282 | static struct plat_sci_port scif6_platform_data = { |
271 | .mapbase = 0xfffeb000, | 283 | .mapbase = 0xfffeb000, |
272 | .flags = UPF_BOOT_AUTOCONF, | 284 | .flags = UPF_BOOT_AUTOCONF, |
285 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
286 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
273 | .type = PORT_SCIF, | 287 | .type = PORT_SCIF, |
274 | .irqs = { 204, 204, 204, 204 } | 288 | .irqs = { 204, 204, 204, 204 } |
275 | }; | 289 | }; |
@@ -285,6 +299,8 @@ static struct platform_device scif6_device = { | |||
285 | static struct plat_sci_port scif7_platform_data = { | 299 | static struct plat_sci_port scif7_platform_data = { |
286 | .mapbase = 0xfffeb800, | 300 | .mapbase = 0xfffeb800, |
287 | .flags = UPF_BOOT_AUTOCONF, | 301 | .flags = UPF_BOOT_AUTOCONF, |
302 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
303 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
288 | .type = PORT_SCIF, | 304 | .type = PORT_SCIF, |
289 | .irqs = { 208, 208, 208, 208 } | 305 | .irqs = { 208, 208, 208, 208 } |
290 | }; | 306 | }; |
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c index 832f401b5860..a43124e608c3 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c | |||
@@ -176,6 +176,8 @@ static DECLARE_INTC_DESC(intc_desc, "sh7203", vectors, groups, | |||
176 | static struct plat_sci_port scif0_platform_data = { | 176 | static struct plat_sci_port scif0_platform_data = { |
177 | .mapbase = 0xfffe8000, | 177 | .mapbase = 0xfffe8000, |
178 | .flags = UPF_BOOT_AUTOCONF, | 178 | .flags = UPF_BOOT_AUTOCONF, |
179 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
180 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
179 | .type = PORT_SCIF, | 181 | .type = PORT_SCIF, |
180 | .irqs = { 192, 192, 192, 192 }, | 182 | .irqs = { 192, 192, 192, 192 }, |
181 | }; | 183 | }; |
@@ -191,6 +193,8 @@ static struct platform_device scif0_device = { | |||
191 | static struct plat_sci_port scif1_platform_data = { | 193 | static struct plat_sci_port scif1_platform_data = { |
192 | .mapbase = 0xfffe8800, | 194 | .mapbase = 0xfffe8800, |
193 | .flags = UPF_BOOT_AUTOCONF, | 195 | .flags = UPF_BOOT_AUTOCONF, |
196 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
197 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
194 | .type = PORT_SCIF, | 198 | .type = PORT_SCIF, |
195 | .irqs = { 196, 196, 196, 196 }, | 199 | .irqs = { 196, 196, 196, 196 }, |
196 | }; | 200 | }; |
@@ -206,6 +210,8 @@ static struct platform_device scif1_device = { | |||
206 | static struct plat_sci_port scif2_platform_data = { | 210 | static struct plat_sci_port scif2_platform_data = { |
207 | .mapbase = 0xfffe9000, | 211 | .mapbase = 0xfffe9000, |
208 | .flags = UPF_BOOT_AUTOCONF, | 212 | .flags = UPF_BOOT_AUTOCONF, |
213 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
214 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
209 | .type = PORT_SCIF, | 215 | .type = PORT_SCIF, |
210 | .irqs = { 200, 200, 200, 200 }, | 216 | .irqs = { 200, 200, 200, 200 }, |
211 | }; | 217 | }; |
@@ -221,6 +227,8 @@ static struct platform_device scif2_device = { | |||
221 | static struct plat_sci_port scif3_platform_data = { | 227 | static struct plat_sci_port scif3_platform_data = { |
222 | .mapbase = 0xfffe9800, | 228 | .mapbase = 0xfffe9800, |
223 | .flags = UPF_BOOT_AUTOCONF, | 229 | .flags = UPF_BOOT_AUTOCONF, |
230 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
231 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
224 | .type = PORT_SCIF, | 232 | .type = PORT_SCIF, |
225 | .irqs = { 204, 204, 204, 204 }, | 233 | .irqs = { 204, 204, 204, 204 }, |
226 | }; | 234 | }; |
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c index dc47b04e1049..5d14f849aea3 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c | |||
@@ -136,6 +136,8 @@ static DECLARE_INTC_DESC(intc_desc, "sh7206", vectors, groups, | |||
136 | static struct plat_sci_port scif0_platform_data = { | 136 | static struct plat_sci_port scif0_platform_data = { |
137 | .mapbase = 0xfffe8000, | 137 | .mapbase = 0xfffe8000, |
138 | .flags = UPF_BOOT_AUTOCONF, | 138 | .flags = UPF_BOOT_AUTOCONF, |
139 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
140 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
139 | .type = PORT_SCIF, | 141 | .type = PORT_SCIF, |
140 | .irqs = { 240, 240, 240, 240 }, | 142 | .irqs = { 240, 240, 240, 240 }, |
141 | }; | 143 | }; |
@@ -151,6 +153,8 @@ static struct platform_device scif0_device = { | |||
151 | static struct plat_sci_port scif1_platform_data = { | 153 | static struct plat_sci_port scif1_platform_data = { |
152 | .mapbase = 0xfffe8800, | 154 | .mapbase = 0xfffe8800, |
153 | .flags = UPF_BOOT_AUTOCONF, | 155 | .flags = UPF_BOOT_AUTOCONF, |
156 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
157 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
154 | .type = PORT_SCIF, | 158 | .type = PORT_SCIF, |
155 | .irqs = { 244, 244, 244, 244 }, | 159 | .irqs = { 244, 244, 244, 244 }, |
156 | }; | 160 | }; |
@@ -166,6 +170,8 @@ static struct platform_device scif1_device = { | |||
166 | static struct plat_sci_port scif2_platform_data = { | 170 | static struct plat_sci_port scif2_platform_data = { |
167 | .mapbase = 0xfffe9000, | 171 | .mapbase = 0xfffe9000, |
168 | .flags = UPF_BOOT_AUTOCONF, | 172 | .flags = UPF_BOOT_AUTOCONF, |
173 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
174 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
169 | .type = PORT_SCIF, | 175 | .type = PORT_SCIF, |
170 | .irqs = { 248, 248, 248, 248 }, | 176 | .irqs = { 248, 248, 248, 248 }, |
171 | }; | 177 | }; |
@@ -181,6 +187,8 @@ static struct platform_device scif2_device = { | |||
181 | static struct plat_sci_port scif3_platform_data = { | 187 | static struct plat_sci_port scif3_platform_data = { |
182 | .mapbase = 0xfffe9800, | 188 | .mapbase = 0xfffe9800, |
183 | .flags = UPF_BOOT_AUTOCONF, | 189 | .flags = UPF_BOOT_AUTOCONF, |
190 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
191 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
184 | .type = PORT_SCIF, | 192 | .type = PORT_SCIF, |
185 | .irqs = { 252, 252, 252, 252 }, | 193 | .irqs = { 252, 252, 252, 252 }, |
186 | }; | 194 | }; |
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c index baadd7f54d94..cd2e702feb7e 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c | |||
@@ -70,6 +70,9 @@ static DECLARE_INTC_DESC(intc_desc, "sh7705", vectors, NULL, | |||
70 | static struct plat_sci_port scif0_platform_data = { | 70 | static struct plat_sci_port scif0_platform_data = { |
71 | .mapbase = 0xa4410000, | 71 | .mapbase = 0xa4410000, |
72 | .flags = UPF_BOOT_AUTOCONF, | 72 | .flags = UPF_BOOT_AUTOCONF, |
73 | .scscr = SCSCR_TIE | SCSCR_RIE | SCSCR_TE | | ||
74 | SCSCR_RE | SCSCR_CKE1 | SCSCR_CKE0, | ||
75 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
73 | .type = PORT_SCIF, | 76 | .type = PORT_SCIF, |
74 | .irqs = { 56, 56, 56 }, | 77 | .irqs = { 56, 56, 56 }, |
75 | }; | 78 | }; |
@@ -85,6 +88,8 @@ static struct platform_device scif0_device = { | |||
85 | static struct plat_sci_port scif1_platform_data = { | 88 | static struct plat_sci_port scif1_platform_data = { |
86 | .mapbase = 0xa4400000, | 89 | .mapbase = 0xa4400000, |
87 | .flags = UPF_BOOT_AUTOCONF, | 90 | .flags = UPF_BOOT_AUTOCONF, |
91 | .scscr = SCSCR_TIE | SCSCR_RIE | SCSCR_TE | SCSCR_RE, | ||
92 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
88 | .type = PORT_SCIF, | 93 | .type = PORT_SCIF, |
89 | .irqs = { 52, 52, 52 }, | 94 | .irqs = { 52, 52, 52 }, |
90 | }; | 95 | }; |
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c index 3cf8c8ef7b32..4551ad647c2c 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c | |||
@@ -109,6 +109,8 @@ static struct platform_device rtc_device = { | |||
109 | static struct plat_sci_port scif0_platform_data = { | 109 | static struct plat_sci_port scif0_platform_data = { |
110 | .mapbase = 0xfffffe80, | 110 | .mapbase = 0xfffffe80, |
111 | .flags = UPF_BOOT_AUTOCONF, | 111 | .flags = UPF_BOOT_AUTOCONF, |
112 | .scscr = SCSCR_TE | SCSCR_RE, | ||
113 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
112 | .type = PORT_SCI, | 114 | .type = PORT_SCI, |
113 | .irqs = { 23, 23, 23, 0 }, | 115 | .irqs = { 23, 23, 23, 0 }, |
114 | }; | 116 | }; |
@@ -126,6 +128,8 @@ static struct platform_device scif0_device = { | |||
126 | static struct plat_sci_port scif1_platform_data = { | 128 | static struct plat_sci_port scif1_platform_data = { |
127 | .mapbase = 0xa4000150, | 129 | .mapbase = 0xa4000150, |
128 | .flags = UPF_BOOT_AUTOCONF, | 130 | .flags = UPF_BOOT_AUTOCONF, |
131 | .scscr = SCSCR_TE | SCSCR_RE, | ||
132 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
129 | .type = PORT_SCIF, | 133 | .type = PORT_SCIF, |
130 | .irqs = { 56, 56, 56, 56 }, | 134 | .irqs = { 56, 56, 56, 56 }, |
131 | }; | 135 | }; |
@@ -143,6 +147,8 @@ static struct platform_device scif1_device = { | |||
143 | static struct plat_sci_port scif2_platform_data = { | 147 | static struct plat_sci_port scif2_platform_data = { |
144 | .mapbase = 0xa4000140, | 148 | .mapbase = 0xa4000140, |
145 | .flags = UPF_BOOT_AUTOCONF, | 149 | .flags = UPF_BOOT_AUTOCONF, |
150 | .scscr = SCSCR_TE | SCSCR_RE, | ||
151 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
146 | .type = PORT_IRDA, | 152 | .type = PORT_IRDA, |
147 | .irqs = { 52, 52, 52, 52 }, | 153 | .irqs = { 52, 52, 52, 52 }, |
148 | }; | 154 | }; |
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c index b0c2fb4ab479..78f6b01d42c3 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c | |||
@@ -99,6 +99,9 @@ static struct platform_device rtc_device = { | |||
99 | static struct plat_sci_port scif0_platform_data = { | 99 | static struct plat_sci_port scif0_platform_data = { |
100 | .mapbase = 0xa4400000, | 100 | .mapbase = 0xa4400000, |
101 | .flags = UPF_BOOT_AUTOCONF, | 101 | .flags = UPF_BOOT_AUTOCONF, |
102 | .scscr = SCSCR_TE | SCSCR_RE | SCSCR_REIE | | ||
103 | SCSCR_CKE1 | SCSCR_CKE0, | ||
104 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
102 | .type = PORT_SCIF, | 105 | .type = PORT_SCIF, |
103 | .irqs = { 52, 52, 52, 52 }, | 106 | .irqs = { 52, 52, 52, 52 }, |
104 | }; | 107 | }; |
@@ -114,6 +117,9 @@ static struct platform_device scif0_device = { | |||
114 | static struct plat_sci_port scif1_platform_data = { | 117 | static struct plat_sci_port scif1_platform_data = { |
115 | .mapbase = 0xa4410000, | 118 | .mapbase = 0xa4410000, |
116 | .flags = UPF_BOOT_AUTOCONF, | 119 | .flags = UPF_BOOT_AUTOCONF, |
120 | .scscr = SCSCR_TE | SCSCR_RE | SCSCR_REIE | | ||
121 | SCSCR_CKE1 | SCSCR_CKE0, | ||
122 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
117 | .type = PORT_SCIF, | 123 | .type = PORT_SCIF, |
118 | .irqs = { 56, 56, 56, 56 }, | 124 | .irqs = { 56, 56, 56, 56 }, |
119 | }; | 125 | }; |
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c index 24b17135d5d2..365b94a6fcb7 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * SH7720 Setup | 2 | * Setup code for SH7720, SH7721. |
3 | * | 3 | * |
4 | * Copyright (C) 2007 Markus Brunner, Mark Jonas | 4 | * Copyright (C) 2007 Markus Brunner, Mark Jonas |
5 | * Copyright (C) 2009 Paul Mundt | 5 | * Copyright (C) 2009 Paul Mundt |
@@ -51,6 +51,8 @@ static struct platform_device rtc_device = { | |||
51 | static struct plat_sci_port scif0_platform_data = { | 51 | static struct plat_sci_port scif0_platform_data = { |
52 | .mapbase = 0xa4430000, | 52 | .mapbase = 0xa4430000, |
53 | .flags = UPF_BOOT_AUTOCONF, | 53 | .flags = UPF_BOOT_AUTOCONF, |
54 | .scscr = SCSCR_RE | SCSCR_TE, | ||
55 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
54 | .type = PORT_SCIF, | 56 | .type = PORT_SCIF, |
55 | .irqs = { 80, 80, 80, 80 }, | 57 | .irqs = { 80, 80, 80, 80 }, |
56 | }; | 58 | }; |
@@ -66,6 +68,8 @@ static struct platform_device scif0_device = { | |||
66 | static struct plat_sci_port scif1_platform_data = { | 68 | static struct plat_sci_port scif1_platform_data = { |
67 | .mapbase = 0xa4438000, | 69 | .mapbase = 0xa4438000, |
68 | .flags = UPF_BOOT_AUTOCONF, | 70 | .flags = UPF_BOOT_AUTOCONF, |
71 | .scscr = SCSCR_RE | SCSCR_TE, | ||
72 | .scbrr_algo_id = SCBRR_ALGO_4, | ||
69 | .type = PORT_SCIF, | 73 | .type = PORT_SCIF, |
70 | .irqs = { 81, 81, 81, 81 }, | 74 | .irqs = { 81, 81, 81, 81 }, |
71 | }; | 75 | }; |
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c index b93458f33b74..971cf0fce4f5 100644 --- a/arch/sh/kernel/cpu/sh4/probe.c +++ b/arch/sh/kernel/cpu/sh4/probe.c | |||
@@ -151,8 +151,14 @@ void __cpuinit cpu_probe(void) | |||
151 | boot_cpu_data.flags |= CPU_HAS_L2_CACHE; | 151 | boot_cpu_data.flags |= CPU_HAS_L2_CACHE; |
152 | break; | 152 | break; |
153 | case 0x10: | 153 | case 0x10: |
154 | case 0x11: | ||
154 | boot_cpu_data.type = CPU_SH7757; | 155 | boot_cpu_data.type = CPU_SH7757; |
155 | break; | 156 | break; |
157 | case 0xd0: | ||
158 | case 0x40: /* yon-ten-go */ | ||
159 | boot_cpu_data.type = CPU_SH7372; | ||
160 | break; | ||
161 | |||
156 | } | 162 | } |
157 | break; | 163 | break; |
158 | case 0x4000: /* 1st cut */ | 164 | case 0x4000: /* 1st cut */ |
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c index e916b18e1f7c..5b2833159b7d 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c | |||
@@ -18,6 +18,8 @@ | |||
18 | static struct plat_sci_port scif0_platform_data = { | 18 | static struct plat_sci_port scif0_platform_data = { |
19 | .mapbase = 0xffe80000, | 19 | .mapbase = 0xffe80000, |
20 | .flags = UPF_BOOT_AUTOCONF, | 20 | .flags = UPF_BOOT_AUTOCONF, |
21 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
22 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
21 | .type = PORT_SCIF, | 23 | .type = PORT_SCIF, |
22 | .irqs = { 40, 41, 43, 42 }, | 24 | .irqs = { 40, 41, 43, 42 }, |
23 | }; | 25 | }; |
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index 911d196e86b5..c2b0aaaedcae 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/io.h> | 14 | #include <linux/io.h> |
15 | #include <linux/sh_timer.h> | 15 | #include <linux/sh_timer.h> |
16 | #include <linux/serial_sci.h> | 16 | #include <linux/serial_sci.h> |
17 | #include <asm/machtypes.h> | ||
17 | 18 | ||
18 | static struct resource rtc_resources[] = { | 19 | static struct resource rtc_resources[] = { |
19 | [0] = { | 20 | [0] = { |
@@ -35,33 +36,37 @@ static struct platform_device rtc_device = { | |||
35 | .resource = rtc_resources, | 36 | .resource = rtc_resources, |
36 | }; | 37 | }; |
37 | 38 | ||
38 | static struct plat_sci_port scif0_platform_data = { | 39 | static struct plat_sci_port sci_platform_data = { |
39 | .mapbase = 0xffe00000, | 40 | .mapbase = 0xffe00000, |
40 | .flags = UPF_BOOT_AUTOCONF, | 41 | .flags = UPF_BOOT_AUTOCONF, |
42 | .scscr = SCSCR_TE | SCSCR_RE, | ||
43 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
41 | .type = PORT_SCI, | 44 | .type = PORT_SCI, |
42 | .irqs = { 23, 23, 23, 0 }, | 45 | .irqs = { 23, 23, 23, 0 }, |
43 | }; | 46 | }; |
44 | 47 | ||
45 | static struct platform_device scif0_device = { | 48 | static struct platform_device sci_device = { |
46 | .name = "sh-sci", | 49 | .name = "sh-sci", |
47 | .id = 0, | 50 | .id = 0, |
48 | .dev = { | 51 | .dev = { |
49 | .platform_data = &scif0_platform_data, | 52 | .platform_data = &sci_platform_data, |
50 | }, | 53 | }, |
51 | }; | 54 | }; |
52 | 55 | ||
53 | static struct plat_sci_port scif1_platform_data = { | 56 | static struct plat_sci_port scif_platform_data = { |
54 | .mapbase = 0xffe80000, | 57 | .mapbase = 0xffe80000, |
55 | .flags = UPF_BOOT_AUTOCONF, | 58 | .flags = UPF_BOOT_AUTOCONF, |
59 | .scscr = SCSCR_TE | SCSCR_RE | SCSCR_REIE, | ||
60 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
56 | .type = PORT_SCIF, | 61 | .type = PORT_SCIF, |
57 | .irqs = { 40, 40, 40, 40 }, | 62 | .irqs = { 40, 40, 40, 40 }, |
58 | }; | 63 | }; |
59 | 64 | ||
60 | static struct platform_device scif1_device = { | 65 | static struct platform_device scif_device = { |
61 | .name = "sh-sci", | 66 | .name = "sh-sci", |
62 | .id = 1, | 67 | .id = 1, |
63 | .dev = { | 68 | .dev = { |
64 | .platform_data = &scif1_platform_data, | 69 | .platform_data = &scif_platform_data, |
65 | }, | 70 | }, |
66 | }; | 71 | }; |
67 | 72 | ||
@@ -210,8 +215,6 @@ static struct platform_device tmu4_device = { | |||
210 | #endif | 215 | #endif |
211 | 216 | ||
212 | static struct platform_device *sh7750_devices[] __initdata = { | 217 | static struct platform_device *sh7750_devices[] __initdata = { |
213 | &scif0_device, | ||
214 | &scif1_device, | ||
215 | &rtc_device, | 218 | &rtc_device, |
216 | &tmu0_device, | 219 | &tmu0_device, |
217 | &tmu1_device, | 220 | &tmu1_device, |
@@ -226,14 +229,19 @@ static struct platform_device *sh7750_devices[] __initdata = { | |||
226 | 229 | ||
227 | static int __init sh7750_devices_setup(void) | 230 | static int __init sh7750_devices_setup(void) |
228 | { | 231 | { |
232 | if (mach_is_rts7751r2d()) { | ||
233 | platform_register_device(&scif_device); | ||
234 | } else { | ||
235 | platform_register_device(&sci_device); | ||
236 | platform_register_device(&scif_device); | ||
237 | } | ||
238 | |||
229 | return platform_add_devices(sh7750_devices, | 239 | return platform_add_devices(sh7750_devices, |
230 | ARRAY_SIZE(sh7750_devices)); | 240 | ARRAY_SIZE(sh7750_devices)); |
231 | } | 241 | } |
232 | arch_initcall(sh7750_devices_setup); | 242 | arch_initcall(sh7750_devices_setup); |
233 | 243 | ||
234 | static struct platform_device *sh7750_early_devices[] __initdata = { | 244 | static struct platform_device *sh7750_early_devices[] __initdata = { |
235 | &scif0_device, | ||
236 | &scif1_device, | ||
237 | &tmu0_device, | 245 | &tmu0_device, |
238 | &tmu1_device, | 246 | &tmu1_device, |
239 | &tmu2_device, | 247 | &tmu2_device, |
@@ -247,6 +255,14 @@ static struct platform_device *sh7750_early_devices[] __initdata = { | |||
247 | 255 | ||
248 | void __init plat_early_device_setup(void) | 256 | void __init plat_early_device_setup(void) |
249 | { | 257 | { |
258 | if (mach_is_rts7751r2d()) { | ||
259 | scif_platform_data.scscr |= SCSCR_CKE1; | ||
260 | early_platform_add_devices(&scif_device, 1); | ||
261 | } else { | ||
262 | early_platform_add_devices(&sci_device, 1); | ||
263 | early_platform_add_devices(&scif_device, 1); | ||
264 | } | ||
265 | |||
250 | early_platform_add_devices(sh7750_early_devices, | 266 | early_platform_add_devices(sh7750_early_devices, |
251 | ARRAY_SIZE(sh7750_early_devices)); | 267 | ARRAY_SIZE(sh7750_early_devices)); |
252 | } | 268 | } |
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c index 48ea8fe85dc5..78bbf232e391 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c | |||
@@ -129,6 +129,8 @@ static DECLARE_INTC_DESC(intc_desc_irq, "sh7760-irq", vectors_irq, groups, | |||
129 | static struct plat_sci_port scif0_platform_data = { | 129 | static struct plat_sci_port scif0_platform_data = { |
130 | .mapbase = 0xfe600000, | 130 | .mapbase = 0xfe600000, |
131 | .flags = UPF_BOOT_AUTOCONF, | 131 | .flags = UPF_BOOT_AUTOCONF, |
132 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
133 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
132 | .type = PORT_SCIF, | 134 | .type = PORT_SCIF, |
133 | .irqs = { 52, 53, 55, 54 }, | 135 | .irqs = { 52, 53, 55, 54 }, |
134 | }; | 136 | }; |
@@ -145,6 +147,8 @@ static struct plat_sci_port scif1_platform_data = { | |||
145 | .mapbase = 0xfe610000, | 147 | .mapbase = 0xfe610000, |
146 | .flags = UPF_BOOT_AUTOCONF, | 148 | .flags = UPF_BOOT_AUTOCONF, |
147 | .type = PORT_SCIF, | 149 | .type = PORT_SCIF, |
150 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
151 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
148 | .irqs = { 72, 73, 75, 74 }, | 152 | .irqs = { 72, 73, 75, 74 }, |
149 | }; | 153 | }; |
150 | 154 | ||
@@ -159,6 +163,8 @@ static struct platform_device scif1_device = { | |||
159 | static struct plat_sci_port scif2_platform_data = { | 163 | static struct plat_sci_port scif2_platform_data = { |
160 | .mapbase = 0xfe620000, | 164 | .mapbase = 0xfe620000, |
161 | .flags = UPF_BOOT_AUTOCONF, | 165 | .flags = UPF_BOOT_AUTOCONF, |
166 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
167 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
162 | .type = PORT_SCIF, | 168 | .type = PORT_SCIF, |
163 | .irqs = { 76, 77, 79, 78 }, | 169 | .irqs = { 76, 77, 79, 78 }, |
164 | }; | 170 | }; |
@@ -174,6 +180,8 @@ static struct platform_device scif2_device = { | |||
174 | static struct plat_sci_port scif3_platform_data = { | 180 | static struct plat_sci_port scif3_platform_data = { |
175 | .mapbase = 0xfe480000, | 181 | .mapbase = 0xfe480000, |
176 | .flags = UPF_BOOT_AUTOCONF, | 182 | .flags = UPF_BOOT_AUTOCONF, |
183 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
184 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
177 | .type = PORT_SCI, | 185 | .type = PORT_SCI, |
178 | .irqs = { 80, 81, 82, 0 }, | 186 | .irqs = { 80, 81, 82, 0 }, |
179 | }; | 187 | }; |
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c index 3681cafdb4af..1b8848317e9c 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c | |||
@@ -19,6 +19,8 @@ | |||
19 | static struct plat_sci_port scif0_platform_data = { | 19 | static struct plat_sci_port scif0_platform_data = { |
20 | .mapbase = 0xffe00000, | 20 | .mapbase = 0xffe00000, |
21 | .flags = UPF_BOOT_AUTOCONF, | 21 | .flags = UPF_BOOT_AUTOCONF, |
22 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, | ||
23 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
22 | .type = PORT_SCIF, | 24 | .type = PORT_SCIF, |
23 | .irqs = { 80, 80, 80, 80 }, | 25 | .irqs = { 80, 80, 80, 80 }, |
24 | }; | 26 | }; |
@@ -34,6 +36,8 @@ static struct platform_device scif0_device = { | |||
34 | static struct plat_sci_port scif1_platform_data = { | 36 | static struct plat_sci_port scif1_platform_data = { |
35 | .mapbase = 0xffe10000, | 37 | .mapbase = 0xffe10000, |
36 | .flags = UPF_BOOT_AUTOCONF, | 38 | .flags = UPF_BOOT_AUTOCONF, |
39 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, | ||
40 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
37 | .type = PORT_SCIF, | 41 | .type = PORT_SCIF, |
38 | .irqs = { 81, 81, 81, 81 }, | 42 | .irqs = { 81, 81, 81, 81 }, |
39 | }; | 43 | }; |
@@ -49,6 +53,8 @@ static struct platform_device scif1_device = { | |||
49 | static struct plat_sci_port scif2_platform_data = { | 53 | static struct plat_sci_port scif2_platform_data = { |
50 | .mapbase = 0xffe20000, | 54 | .mapbase = 0xffe20000, |
51 | .flags = UPF_BOOT_AUTOCONF, | 55 | .flags = UPF_BOOT_AUTOCONF, |
56 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, | ||
57 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
52 | .type = PORT_SCIF, | 58 | .type = PORT_SCIF, |
53 | .irqs = { 82, 82, 82, 82 }, | 59 | .irqs = { 82, 82, 82, 82 }, |
54 | }; | 60 | }; |
@@ -64,6 +70,8 @@ static struct platform_device scif2_device = { | |||
64 | static struct plat_sci_port scif3_platform_data = { | 70 | static struct plat_sci_port scif3_platform_data = { |
65 | .mapbase = 0xffe30000, | 71 | .mapbase = 0xffe30000, |
66 | .flags = UPF_BOOT_AUTOCONF, | 72 | .flags = UPF_BOOT_AUTOCONF, |
73 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, | ||
74 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
67 | .type = PORT_SCIF, | 75 | .type = PORT_SCIF, |
68 | .irqs = { 83, 83, 83, 83 }, | 76 | .irqs = { 83, 83, 83, 83 }, |
69 | }; | 77 | }; |
@@ -360,6 +368,8 @@ void __init plat_early_device_setup(void) | |||
360 | 368 | ||
361 | enum { | 369 | enum { |
362 | UNUSED = 0, | 370 | UNUSED = 0, |
371 | ENABLED, | ||
372 | DISABLED, | ||
363 | 373 | ||
364 | /* interrupt sources */ | 374 | /* interrupt sources */ |
365 | IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, | 375 | IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, |
@@ -375,15 +385,13 @@ enum { | |||
375 | I2C0_ALI, I2C0_TACKI, I2C0_WAITI, I2C0_DTEI, | 385 | I2C0_ALI, I2C0_TACKI, I2C0_WAITI, I2C0_DTEI, |
376 | I2C1_ALI, I2C1_TACKI, I2C1_WAITI, I2C1_DTEI, | 386 | I2C1_ALI, I2C1_TACKI, I2C1_WAITI, I2C1_DTEI, |
377 | SIM_TEI, SIM_TXI, SIM_RXI, SIM_ERI, | 387 | SIM_TEI, SIM_TXI, SIM_RXI, SIM_ERI, |
378 | IRDA, | 388 | IRDA, SDHI, CMT, TSIF, SIU, |
379 | SDHI0, SDHI1, SDHI2, SDHI3, | ||
380 | CMT, TSIF, SIU, | ||
381 | TMU0, TMU1, TMU2, | 389 | TMU0, TMU1, TMU2, |
382 | JPU, LCDC, | 390 | JPU, LCDC, |
383 | 391 | ||
384 | /* interrupt groups */ | 392 | /* interrupt groups */ |
385 | 393 | ||
386 | DMAC0123, VIOVOU, MMC, DMAC45, FLCTL, I2C0, I2C1, SIM, SDHI, USB, | 394 | DMAC0123, VIOVOU, MMC, DMAC45, FLCTL, I2C0, I2C1, SIM, USB, |
387 | }; | 395 | }; |
388 | 396 | ||
389 | static struct intc_vect vectors[] __initdata = { | 397 | static struct intc_vect vectors[] __initdata = { |
@@ -412,8 +420,8 @@ static struct intc_vect vectors[] __initdata = { | |||
412 | INTC_VECT(FLCTL_FLTREQ0I, 0xdc0), INTC_VECT(FLCTL_FLTREQ1I, 0xde0), | 420 | INTC_VECT(FLCTL_FLTREQ0I, 0xdc0), INTC_VECT(FLCTL_FLTREQ1I, 0xde0), |
413 | INTC_VECT(I2C0_ALI, 0xe00), INTC_VECT(I2C0_TACKI, 0xe20), | 421 | INTC_VECT(I2C0_ALI, 0xe00), INTC_VECT(I2C0_TACKI, 0xe20), |
414 | INTC_VECT(I2C0_WAITI, 0xe40), INTC_VECT(I2C0_DTEI, 0xe60), | 422 | INTC_VECT(I2C0_WAITI, 0xe40), INTC_VECT(I2C0_DTEI, 0xe60), |
415 | INTC_VECT(SDHI0, 0xe80), INTC_VECT(SDHI1, 0xea0), | 423 | INTC_VECT(SDHI, 0xe80), INTC_VECT(SDHI, 0xea0), |
416 | INTC_VECT(SDHI2, 0xec0), INTC_VECT(SDHI3, 0xee0), | 424 | INTC_VECT(SDHI, 0xec0), INTC_VECT(SDHI, 0xee0), |
417 | INTC_VECT(CMT, 0xf00), INTC_VECT(TSIF, 0xf20), | 425 | INTC_VECT(CMT, 0xf00), INTC_VECT(TSIF, 0xf20), |
418 | INTC_VECT(SIU, 0xf80), | 426 | INTC_VECT(SIU, 0xf80), |
419 | INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420), | 427 | INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420), |
@@ -431,7 +439,6 @@ static struct intc_group groups[] __initdata = { | |||
431 | INTC_GROUP(I2C0, I2C0_ALI, I2C0_TACKI, I2C0_WAITI, I2C0_DTEI), | 439 | INTC_GROUP(I2C0, I2C0_ALI, I2C0_TACKI, I2C0_WAITI, I2C0_DTEI), |
432 | INTC_GROUP(I2C1, I2C1_ALI, I2C1_TACKI, I2C1_WAITI, I2C1_DTEI), | 440 | INTC_GROUP(I2C1, I2C1_ALI, I2C1_TACKI, I2C1_WAITI, I2C1_DTEI), |
433 | INTC_GROUP(SIM, SIM_TEI, SIM_TXI, SIM_RXI, SIM_ERI), | 441 | INTC_GROUP(SIM, SIM_TEI, SIM_TXI, SIM_RXI, SIM_ERI), |
434 | INTC_GROUP(SDHI, SDHI0, SDHI1, SDHI2, SDHI3), | ||
435 | INTC_GROUP(USB, USBI0, USBI1), | 442 | INTC_GROUP(USB, USBI0, USBI1), |
436 | }; | 443 | }; |
437 | 444 | ||
@@ -452,7 +459,7 @@ static struct intc_mask_reg mask_registers[] __initdata = { | |||
452 | { I2C0_DTEI, I2C0_WAITI, I2C0_TACKI, I2C0_ALI, | 459 | { I2C0_DTEI, I2C0_WAITI, I2C0_TACKI, I2C0_ALI, |
453 | FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLENDI, FLCTL_FLSTEI } }, | 460 | FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLENDI, FLCTL_FLSTEI } }, |
454 | { 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */ | 461 | { 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */ |
455 | { SDHI3, SDHI2, SDHI1, SDHI0, 0, 0, 0, SIU } }, | 462 | { DISABLED, ENABLED, ENABLED, ENABLED, 0, 0, 0, SIU } }, |
456 | { 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */ | 463 | { 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */ |
457 | { 0, 0, 0, CMT, 0, USBI1, USBI0 } }, | 464 | { 0, 0, 0, CMT, 0, USBI1, USBI0 } }, |
458 | { 0xa40800a8, 0xa40800e8, 8, /* IMR10 / IMCR10 */ | 465 | { 0xa40800a8, 0xa40800e8, 8, /* IMR10 / IMCR10 */ |
@@ -488,9 +495,13 @@ static struct intc_mask_reg ack_registers[] __initdata = { | |||
488 | { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, | 495 | { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, |
489 | }; | 496 | }; |
490 | 497 | ||
491 | static DECLARE_INTC_DESC_ACK(intc_desc, "sh7343", vectors, groups, | 498 | static struct intc_desc intc_desc __initdata = { |
492 | mask_registers, prio_registers, sense_registers, | 499 | .name = "sh7343", |
493 | ack_registers); | 500 | .force_enable = ENABLED, |
501 | .force_disable = DISABLED, | ||
502 | .hw = INTC_HW_DESC(vectors, groups, mask_registers, | ||
503 | prio_registers, sense_registers, ack_registers), | ||
504 | }; | ||
494 | 505 | ||
495 | void __init plat_irq_setup(void) | 506 | void __init plat_irq_setup(void) |
496 | { | 507 | { |
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c index 8dab9e1bbd89..82616af64d62 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c | |||
@@ -21,6 +21,8 @@ | |||
21 | static struct plat_sci_port scif0_platform_data = { | 21 | static struct plat_sci_port scif0_platform_data = { |
22 | .mapbase = 0xffe00000, | 22 | .mapbase = 0xffe00000, |
23 | .flags = UPF_BOOT_AUTOCONF, | 23 | .flags = UPF_BOOT_AUTOCONF, |
24 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
25 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
24 | .type = PORT_SCIF, | 26 | .type = PORT_SCIF, |
25 | .irqs = { 80, 80, 80, 80 }, | 27 | .irqs = { 80, 80, 80, 80 }, |
26 | }; | 28 | }; |
@@ -319,6 +321,8 @@ void __init plat_early_device_setup(void) | |||
319 | 321 | ||
320 | enum { | 322 | enum { |
321 | UNUSED=0, | 323 | UNUSED=0, |
324 | ENABLED, | ||
325 | DISABLED, | ||
322 | 326 | ||
323 | /* interrupt sources */ | 327 | /* interrupt sources */ |
324 | IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, | 328 | IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, |
@@ -332,14 +336,13 @@ enum { | |||
332 | DENC, MSIOF, | 336 | DENC, MSIOF, |
333 | FLCTL_FLSTEI, FLCTL_FLENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I, | 337 | FLCTL_FLSTEI, FLCTL_FLENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I, |
334 | I2C_ALI, I2C_TACKI, I2C_WAITI, I2C_DTEI, | 338 | I2C_ALI, I2C_TACKI, I2C_WAITI, I2C_DTEI, |
335 | SDHI0, SDHI1, SDHI2, SDHI3, | 339 | SDHI, CMT, TSIF, SIU, |
336 | CMT, TSIF, SIU, | ||
337 | TMU0, TMU1, TMU2, | 340 | TMU0, TMU1, TMU2, |
338 | VEU2, LCDC, | 341 | VEU2, LCDC, |
339 | 342 | ||
340 | /* interrupt groups */ | 343 | /* interrupt groups */ |
341 | 344 | ||
342 | DMAC0123, VIOVOU, MMC, DMAC45, FLCTL, I2C, SDHI, | 345 | DMAC0123, VIOVOU, MMC, DMAC45, FLCTL, I2C, |
343 | }; | 346 | }; |
344 | 347 | ||
345 | static struct intc_vect vectors[] __initdata = { | 348 | static struct intc_vect vectors[] __initdata = { |
@@ -364,8 +367,8 @@ static struct intc_vect vectors[] __initdata = { | |||
364 | INTC_VECT(FLCTL_FLTREQ0I, 0xdc0), INTC_VECT(FLCTL_FLTREQ1I, 0xde0), | 367 | INTC_VECT(FLCTL_FLTREQ0I, 0xdc0), INTC_VECT(FLCTL_FLTREQ1I, 0xde0), |
365 | INTC_VECT(I2C_ALI, 0xe00), INTC_VECT(I2C_TACKI, 0xe20), | 368 | INTC_VECT(I2C_ALI, 0xe00), INTC_VECT(I2C_TACKI, 0xe20), |
366 | INTC_VECT(I2C_WAITI, 0xe40), INTC_VECT(I2C_DTEI, 0xe60), | 369 | INTC_VECT(I2C_WAITI, 0xe40), INTC_VECT(I2C_DTEI, 0xe60), |
367 | INTC_VECT(SDHI0, 0xe80), INTC_VECT(SDHI1, 0xea0), | 370 | INTC_VECT(SDHI, 0xe80), INTC_VECT(SDHI, 0xea0), |
368 | INTC_VECT(SDHI2, 0xec0), INTC_VECT(SDHI3, 0xee0), | 371 | INTC_VECT(SDHI, 0xec0), INTC_VECT(SDHI, 0xee0), |
369 | INTC_VECT(CMT, 0xf00), INTC_VECT(TSIF, 0xf20), | 372 | INTC_VECT(CMT, 0xf00), INTC_VECT(TSIF, 0xf20), |
370 | INTC_VECT(SIU, 0xf80), | 373 | INTC_VECT(SIU, 0xf80), |
371 | INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420), | 374 | INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420), |
@@ -381,7 +384,6 @@ static struct intc_group groups[] __initdata = { | |||
381 | INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLENDI, | 384 | INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLENDI, |
382 | FLCTL_FLTREQ0I, FLCTL_FLTREQ1I), | 385 | FLCTL_FLTREQ0I, FLCTL_FLTREQ1I), |
383 | INTC_GROUP(I2C, I2C_ALI, I2C_TACKI, I2C_WAITI, I2C_DTEI), | 386 | INTC_GROUP(I2C, I2C_ALI, I2C_TACKI, I2C_WAITI, I2C_DTEI), |
384 | INTC_GROUP(SDHI, SDHI0, SDHI1, SDHI2, SDHI3), | ||
385 | }; | 387 | }; |
386 | 388 | ||
387 | static struct intc_mask_reg mask_registers[] __initdata = { | 389 | static struct intc_mask_reg mask_registers[] __initdata = { |
@@ -403,7 +405,7 @@ static struct intc_mask_reg mask_registers[] __initdata = { | |||
403 | { I2C_DTEI, I2C_WAITI, I2C_TACKI, I2C_ALI, | 405 | { I2C_DTEI, I2C_WAITI, I2C_TACKI, I2C_ALI, |
404 | FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLENDI, FLCTL_FLSTEI } }, | 406 | FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLENDI, FLCTL_FLSTEI } }, |
405 | { 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */ | 407 | { 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */ |
406 | { SDHI3, SDHI2, SDHI1, SDHI0, 0, 0, 0, SIU } }, | 408 | { DISABLED, ENABLED, ENABLED, ENABLED, 0, 0, 0, SIU } }, |
407 | { 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */ | 409 | { 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */ |
408 | { 0, 0, 0, CMT, 0, USB, } }, | 410 | { 0, 0, 0, CMT, 0, USB, } }, |
409 | { 0xa40800a8, 0xa40800e8, 8, /* IMR10 / IMCR10 */ | 411 | { 0xa40800a8, 0xa40800e8, 8, /* IMR10 / IMCR10 */ |
@@ -441,9 +443,13 @@ static struct intc_mask_reg ack_registers[] __initdata = { | |||
441 | { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, | 443 | { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, |
442 | }; | 444 | }; |
443 | 445 | ||
444 | static DECLARE_INTC_DESC_ACK(intc_desc, "sh7366", vectors, groups, | 446 | static struct intc_desc intc_desc __initdata = { |
445 | mask_registers, prio_registers, sense_registers, | 447 | .name = "sh7366", |
446 | ack_registers); | 448 | .force_enable = ENABLED, |
449 | .force_disable = DISABLED, | ||
450 | .hw = INTC_HW_DESC(vectors, groups, mask_registers, | ||
451 | prio_registers, sense_registers, ack_registers), | ||
452 | }; | ||
447 | 453 | ||
448 | void __init plat_irq_setup(void) | 454 | void __init plat_irq_setup(void) |
449 | { | 455 | { |
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index d551ed8dea95..5813d8023619 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c | |||
@@ -181,6 +181,8 @@ struct platform_device dma_device = { | |||
181 | static struct plat_sci_port scif0_platform_data = { | 181 | static struct plat_sci_port scif0_platform_data = { |
182 | .mapbase = 0xffe00000, | 182 | .mapbase = 0xffe00000, |
183 | .flags = UPF_BOOT_AUTOCONF, | 183 | .flags = UPF_BOOT_AUTOCONF, |
184 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
185 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
184 | .type = PORT_SCIF, | 186 | .type = PORT_SCIF, |
185 | .irqs = { 80, 80, 80, 80 }, | 187 | .irqs = { 80, 80, 80, 80 }, |
186 | }; | 188 | }; |
@@ -196,6 +198,8 @@ static struct platform_device scif0_device = { | |||
196 | static struct plat_sci_port scif1_platform_data = { | 198 | static struct plat_sci_port scif1_platform_data = { |
197 | .mapbase = 0xffe10000, | 199 | .mapbase = 0xffe10000, |
198 | .flags = UPF_BOOT_AUTOCONF, | 200 | .flags = UPF_BOOT_AUTOCONF, |
201 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
202 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
199 | .type = PORT_SCIF, | 203 | .type = PORT_SCIF, |
200 | .irqs = { 81, 81, 81, 81 }, | 204 | .irqs = { 81, 81, 81, 81 }, |
201 | }; | 205 | }; |
@@ -211,6 +215,8 @@ static struct platform_device scif1_device = { | |||
211 | static struct plat_sci_port scif2_platform_data = { | 215 | static struct plat_sci_port scif2_platform_data = { |
212 | .mapbase = 0xffe20000, | 216 | .mapbase = 0xffe20000, |
213 | .flags = UPF_BOOT_AUTOCONF, | 217 | .flags = UPF_BOOT_AUTOCONF, |
218 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
219 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
214 | .type = PORT_SCIF, | 220 | .type = PORT_SCIF, |
215 | .irqs = { 82, 82, 82, 82 }, | 221 | .irqs = { 82, 82, 82, 82 }, |
216 | }; | 222 | }; |
@@ -699,7 +705,7 @@ static struct intc_mask_reg mask_registers[] __initdata = { | |||
699 | { I2C_DTEI, I2C_WAITI, I2C_TACKI, I2C_ALI, | 705 | { I2C_DTEI, I2C_WAITI, I2C_TACKI, I2C_ALI, |
700 | FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLENDI, FLCTL_FLSTEI } }, | 706 | FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLENDI, FLCTL_FLSTEI } }, |
701 | { 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */ | 707 | { 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */ |
702 | { DISABLED, DISABLED, ENABLED, ENABLED, 0, 0, TWODG, SIU } }, | 708 | { DISABLED, ENABLED, ENABLED, ENABLED, 0, 0, TWODG, SIU } }, |
703 | { 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */ | 709 | { 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */ |
704 | { 0, 0, 0, CMT, 0, USB_USBI1, USB_USBI0, } }, | 710 | { 0, 0, 0, CMT, 0, USB_USBI1, USB_USBI0, } }, |
705 | { 0xa40800a8, 0xa40800e8, 8, /* IMR10 / IMCR10 */ | 711 | { 0xa40800a8, 0xa40800e8, 8, /* IMR10 / IMCR10 */ |
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c index 0eadefdbbba1..072382280f96 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c | |||
@@ -24,6 +24,8 @@ | |||
24 | static struct plat_sci_port scif0_platform_data = { | 24 | static struct plat_sci_port scif0_platform_data = { |
25 | .mapbase = 0xffe00000, | 25 | .mapbase = 0xffe00000, |
26 | .flags = UPF_BOOT_AUTOCONF, | 26 | .flags = UPF_BOOT_AUTOCONF, |
27 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
28 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
27 | .type = PORT_SCIF, | 29 | .type = PORT_SCIF, |
28 | .irqs = { 80, 80, 80, 80 }, | 30 | .irqs = { 80, 80, 80, 80 }, |
29 | }; | 31 | }; |
@@ -39,6 +41,8 @@ static struct platform_device scif0_device = { | |||
39 | static struct plat_sci_port scif1_platform_data = { | 41 | static struct plat_sci_port scif1_platform_data = { |
40 | .mapbase = 0xffe10000, | 42 | .mapbase = 0xffe10000, |
41 | .flags = UPF_BOOT_AUTOCONF, | 43 | .flags = UPF_BOOT_AUTOCONF, |
44 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
45 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
42 | .type = PORT_SCIF, | 46 | .type = PORT_SCIF, |
43 | .irqs = { 81, 81, 81, 81 }, | 47 | .irqs = { 81, 81, 81, 81 }, |
44 | }; | 48 | }; |
@@ -54,6 +58,8 @@ static struct platform_device scif1_device = { | |||
54 | static struct plat_sci_port scif2_platform_data = { | 58 | static struct plat_sci_port scif2_platform_data = { |
55 | .mapbase = 0xffe20000, | 59 | .mapbase = 0xffe20000, |
56 | .flags = UPF_BOOT_AUTOCONF, | 60 | .flags = UPF_BOOT_AUTOCONF, |
61 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
62 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
57 | .type = PORT_SCIF, | 63 | .type = PORT_SCIF, |
58 | .irqs = { 82, 82, 82, 82 }, | 64 | .irqs = { 82, 82, 82, 82 }, |
59 | }; | 65 | }; |
@@ -69,6 +75,8 @@ static struct platform_device scif2_device = { | |||
69 | static struct plat_sci_port scif3_platform_data = { | 75 | static struct plat_sci_port scif3_platform_data = { |
70 | .mapbase = 0xa4e30000, | 76 | .mapbase = 0xa4e30000, |
71 | .flags = UPF_BOOT_AUTOCONF, | 77 | .flags = UPF_BOOT_AUTOCONF, |
78 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
79 | .scbrr_algo_id = SCBRR_ALGO_3, | ||
72 | .type = PORT_SCIFA, | 80 | .type = PORT_SCIFA, |
73 | .irqs = { 56, 56, 56, 56 }, | 81 | .irqs = { 56, 56, 56, 56 }, |
74 | }; | 82 | }; |
@@ -84,6 +92,8 @@ static struct platform_device scif3_device = { | |||
84 | static struct plat_sci_port scif4_platform_data = { | 92 | static struct plat_sci_port scif4_platform_data = { |
85 | .mapbase = 0xa4e40000, | 93 | .mapbase = 0xa4e40000, |
86 | .flags = UPF_BOOT_AUTOCONF, | 94 | .flags = UPF_BOOT_AUTOCONF, |
95 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
96 | .scbrr_algo_id = SCBRR_ALGO_3, | ||
87 | .type = PORT_SCIFA, | 97 | .type = PORT_SCIFA, |
88 | .irqs = { 88, 88, 88, 88 }, | 98 | .irqs = { 88, 88, 88, 88 }, |
89 | }; | 99 | }; |
@@ -99,6 +109,8 @@ static struct platform_device scif4_device = { | |||
99 | static struct plat_sci_port scif5_platform_data = { | 109 | static struct plat_sci_port scif5_platform_data = { |
100 | .mapbase = 0xa4e50000, | 110 | .mapbase = 0xa4e50000, |
101 | .flags = UPF_BOOT_AUTOCONF, | 111 | .flags = UPF_BOOT_AUTOCONF, |
112 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
113 | .scbrr_algo_id = SCBRR_ALGO_3, | ||
102 | .type = PORT_SCIFA, | 114 | .type = PORT_SCIFA, |
103 | .irqs = { 109, 109, 109, 109 }, | 115 | .irqs = { 109, 109, 109, 109 }, |
104 | }; | 116 | }; |
@@ -719,7 +731,7 @@ static struct intc_group groups[] __initdata = { | |||
719 | static struct intc_mask_reg mask_registers[] __initdata = { | 731 | static struct intc_mask_reg mask_registers[] __initdata = { |
720 | { 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */ | 732 | { 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */ |
721 | { 0, TMU1_TUNI2, TMU1_TUNI1, TMU1_TUNI0, | 733 | { 0, TMU1_TUNI2, TMU1_TUNI1, TMU1_TUNI0, |
722 | 0, DISABLED, ENABLED, ENABLED } }, | 734 | 0, ENABLED, ENABLED, ENABLED } }, |
723 | { 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */ | 735 | { 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */ |
724 | { VIO_VOUI, VIO_VEU2HI,VIO_BEUI,VIO_CEUI,DMAC0A_DEI3,DMAC0A_DEI2,DMAC0A_DEI1,DMAC0A_DEI0 } }, | 736 | { VIO_VOUI, VIO_VEU2HI,VIO_BEUI,VIO_CEUI,DMAC0A_DEI3,DMAC0A_DEI2,DMAC0A_DEI1,DMAC0A_DEI0 } }, |
725 | { 0xa4080088, 0xa40800c8, 8, /* IMR2 / IMCR2 */ | 737 | { 0xa4080088, 0xa40800c8, 8, /* IMR2 / IMCR2 */ |
@@ -736,7 +748,7 @@ static struct intc_mask_reg mask_registers[] __initdata = { | |||
736 | { I2C_DTEI, I2C_WAITI, I2C_TACKI, I2C_ALI, | 748 | { I2C_DTEI, I2C_WAITI, I2C_TACKI, I2C_ALI, |
737 | FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } }, | 749 | FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } }, |
738 | { 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */ | 750 | { 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */ |
739 | { 0, DISABLED, ENABLED, ENABLED, | 751 | { 0, ENABLED, ENABLED, ENABLED, |
740 | 0, 0, SCIFA_SCIFA2, SIU_SIUI } }, | 752 | 0, 0, SCIFA_SCIFA2, SIU_SIUI } }, |
741 | { 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */ | 753 | { 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */ |
742 | { 0, 0, 0, CMT_CMTI, 0, 0, USB_USI0,0 } }, | 754 | { 0, 0, 0, CMT_CMTI, 0, 0, USB_USI0,0 } }, |
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index 828c9657eb52..0333fe9e3881 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c | |||
@@ -257,6 +257,8 @@ static struct platform_device dma1_device = { | |||
257 | static struct plat_sci_port scif0_platform_data = { | 257 | static struct plat_sci_port scif0_platform_data = { |
258 | .mapbase = 0xffe00000, | 258 | .mapbase = 0xffe00000, |
259 | .flags = UPF_BOOT_AUTOCONF, | 259 | .flags = UPF_BOOT_AUTOCONF, |
260 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
261 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
260 | .type = PORT_SCIF, | 262 | .type = PORT_SCIF, |
261 | .irqs = { 80, 80, 80, 80 }, | 263 | .irqs = { 80, 80, 80, 80 }, |
262 | }; | 264 | }; |
@@ -272,6 +274,8 @@ static struct platform_device scif0_device = { | |||
272 | static struct plat_sci_port scif1_platform_data = { | 274 | static struct plat_sci_port scif1_platform_data = { |
273 | .mapbase = 0xffe10000, | 275 | .mapbase = 0xffe10000, |
274 | .flags = UPF_BOOT_AUTOCONF, | 276 | .flags = UPF_BOOT_AUTOCONF, |
277 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
278 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
275 | .type = PORT_SCIF, | 279 | .type = PORT_SCIF, |
276 | .irqs = { 81, 81, 81, 81 }, | 280 | .irqs = { 81, 81, 81, 81 }, |
277 | }; | 281 | }; |
@@ -287,6 +291,8 @@ static struct platform_device scif1_device = { | |||
287 | static struct plat_sci_port scif2_platform_data = { | 291 | static struct plat_sci_port scif2_platform_data = { |
288 | .mapbase = 0xffe20000, | 292 | .mapbase = 0xffe20000, |
289 | .flags = UPF_BOOT_AUTOCONF, | 293 | .flags = UPF_BOOT_AUTOCONF, |
294 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
295 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
290 | .type = PORT_SCIF, | 296 | .type = PORT_SCIF, |
291 | .irqs = { 82, 82, 82, 82 }, | 297 | .irqs = { 82, 82, 82, 82 }, |
292 | }; | 298 | }; |
@@ -302,6 +308,8 @@ static struct platform_device scif2_device = { | |||
302 | static struct plat_sci_port scif3_platform_data = { | 308 | static struct plat_sci_port scif3_platform_data = { |
303 | .mapbase = 0xa4e30000, | 309 | .mapbase = 0xa4e30000, |
304 | .flags = UPF_BOOT_AUTOCONF, | 310 | .flags = UPF_BOOT_AUTOCONF, |
311 | .scscr = SCSCR_RE | SCSCR_TE, | ||
312 | .scbrr_algo_id = SCBRR_ALGO_3, | ||
305 | .type = PORT_SCIFA, | 313 | .type = PORT_SCIFA, |
306 | .irqs = { 56, 56, 56, 56 }, | 314 | .irqs = { 56, 56, 56, 56 }, |
307 | }; | 315 | }; |
@@ -317,6 +325,8 @@ static struct platform_device scif3_device = { | |||
317 | static struct plat_sci_port scif4_platform_data = { | 325 | static struct plat_sci_port scif4_platform_data = { |
318 | .mapbase = 0xa4e40000, | 326 | .mapbase = 0xa4e40000, |
319 | .flags = UPF_BOOT_AUTOCONF, | 327 | .flags = UPF_BOOT_AUTOCONF, |
328 | .scscr = SCSCR_RE | SCSCR_TE, | ||
329 | .scbrr_algo_id = SCBRR_ALGO_3, | ||
320 | .type = PORT_SCIFA, | 330 | .type = PORT_SCIFA, |
321 | .irqs = { 88, 88, 88, 88 }, | 331 | .irqs = { 88, 88, 88, 88 }, |
322 | }; | 332 | }; |
@@ -332,6 +342,8 @@ static struct platform_device scif4_device = { | |||
332 | static struct plat_sci_port scif5_platform_data = { | 342 | static struct plat_sci_port scif5_platform_data = { |
333 | .mapbase = 0xa4e50000, | 343 | .mapbase = 0xa4e50000, |
334 | .flags = UPF_BOOT_AUTOCONF, | 344 | .flags = UPF_BOOT_AUTOCONF, |
345 | .scscr = SCSCR_RE | SCSCR_TE, | ||
346 | .scbrr_algo_id = SCBRR_ALGO_3, | ||
335 | .type = PORT_SCIFA, | 347 | .type = PORT_SCIFA, |
336 | .irqs = { 109, 109, 109, 109 }, | 348 | .irqs = { 109, 109, 109, 109 }, |
337 | }; | 349 | }; |
@@ -1144,7 +1156,7 @@ static struct intc_group groups[] __initdata = { | |||
1144 | static struct intc_mask_reg mask_registers[] __initdata = { | 1156 | static struct intc_mask_reg mask_registers[] __initdata = { |
1145 | { 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */ | 1157 | { 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */ |
1146 | { 0, TMU1_TUNI2, TMU1_TUNI1, TMU1_TUNI0, | 1158 | { 0, TMU1_TUNI2, TMU1_TUNI1, TMU1_TUNI0, |
1147 | 0, DISABLED, ENABLED, ENABLED } }, | 1159 | 0, ENABLED, ENABLED, ENABLED } }, |
1148 | { 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */ | 1160 | { 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */ |
1149 | { VIO_VOU, VIO_VEU1, VIO_BEU0, VIO_CEU0, | 1161 | { VIO_VOU, VIO_VEU1, VIO_BEU0, VIO_CEU0, |
1150 | DMAC0A_DEI3, DMAC0A_DEI2, DMAC0A_DEI1, DMAC0A_DEI0 } }, | 1162 | DMAC0A_DEI3, DMAC0A_DEI2, DMAC0A_DEI1, DMAC0A_DEI0 } }, |
@@ -1166,7 +1178,7 @@ static struct intc_mask_reg mask_registers[] __initdata = { | |||
1166 | { I2C0_DTEI, I2C0_WAITI, I2C0_TACKI, I2C0_ALI, | 1178 | { I2C0_DTEI, I2C0_WAITI, I2C0_TACKI, I2C0_ALI, |
1167 | I2C1_DTEI, I2C1_WAITI, I2C1_TACKI, I2C1_ALI } }, | 1179 | I2C1_DTEI, I2C1_WAITI, I2C1_TACKI, I2C1_ALI } }, |
1168 | { 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */ | 1180 | { 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */ |
1169 | { DISABLED, DISABLED, ENABLED, ENABLED, | 1181 | { DISABLED, ENABLED, ENABLED, ENABLED, |
1170 | 0, 0, SCIFA5, FSI } }, | 1182 | 0, 0, SCIFA5, FSI } }, |
1171 | { 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */ | 1183 | { 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */ |
1172 | { 0, 0, 0, CMT, 0, USB1, USB0, 0 } }, | 1184 | { 0, 0, 0, CMT, 0, USB1, USB0, 0 } }, |
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c index 749c6388d5a5..9c1de2633ac3 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c | |||
@@ -20,6 +20,8 @@ | |||
20 | static struct plat_sci_port scif2_platform_data = { | 20 | static struct plat_sci_port scif2_platform_data = { |
21 | .mapbase = 0xfe4b0000, /* SCIF2 */ | 21 | .mapbase = 0xfe4b0000, /* SCIF2 */ |
22 | .flags = UPF_BOOT_AUTOCONF, | 22 | .flags = UPF_BOOT_AUTOCONF, |
23 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
24 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
23 | .type = PORT_SCIF, | 25 | .type = PORT_SCIF, |
24 | .irqs = { 40, 40, 40, 40 }, | 26 | .irqs = { 40, 40, 40, 40 }, |
25 | }; | 27 | }; |
@@ -35,6 +37,8 @@ static struct platform_device scif2_device = { | |||
35 | static struct plat_sci_port scif3_platform_data = { | 37 | static struct plat_sci_port scif3_platform_data = { |
36 | .mapbase = 0xfe4c0000, /* SCIF3 */ | 38 | .mapbase = 0xfe4c0000, /* SCIF3 */ |
37 | .flags = UPF_BOOT_AUTOCONF, | 39 | .flags = UPF_BOOT_AUTOCONF, |
40 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
41 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
38 | .type = PORT_SCIF, | 42 | .type = PORT_SCIF, |
39 | .irqs = { 76, 76, 76, 76 }, | 43 | .irqs = { 76, 76, 76, 76 }, |
40 | }; | 44 | }; |
@@ -50,6 +54,8 @@ static struct platform_device scif3_device = { | |||
50 | static struct plat_sci_port scif4_platform_data = { | 54 | static struct plat_sci_port scif4_platform_data = { |
51 | .mapbase = 0xfe4d0000, /* SCIF4 */ | 55 | .mapbase = 0xfe4d0000, /* SCIF4 */ |
52 | .flags = UPF_BOOT_AUTOCONF, | 56 | .flags = UPF_BOOT_AUTOCONF, |
57 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
58 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
53 | .type = PORT_SCIF, | 59 | .type = PORT_SCIF, |
54 | .irqs = { 104, 104, 104, 104 }, | 60 | .irqs = { 104, 104, 104, 104 }, |
55 | }; | 61 | }; |
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c index 5b5f6b005fc5..593eca6509b5 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c | |||
@@ -19,6 +19,8 @@ | |||
19 | static struct plat_sci_port scif0_platform_data = { | 19 | static struct plat_sci_port scif0_platform_data = { |
20 | .mapbase = 0xffe00000, | 20 | .mapbase = 0xffe00000, |
21 | .flags = UPF_BOOT_AUTOCONF, | 21 | .flags = UPF_BOOT_AUTOCONF, |
22 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
23 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
22 | .type = PORT_SCIF, | 24 | .type = PORT_SCIF, |
23 | .irqs = { 40, 40, 40, 40 }, | 25 | .irqs = { 40, 40, 40, 40 }, |
24 | }; | 26 | }; |
@@ -34,6 +36,8 @@ static struct platform_device scif0_device = { | |||
34 | static struct plat_sci_port scif1_platform_data = { | 36 | static struct plat_sci_port scif1_platform_data = { |
35 | .mapbase = 0xffe08000, | 37 | .mapbase = 0xffe08000, |
36 | .flags = UPF_BOOT_AUTOCONF, | 38 | .flags = UPF_BOOT_AUTOCONF, |
39 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
40 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
37 | .type = PORT_SCIF, | 41 | .type = PORT_SCIF, |
38 | .irqs = { 76, 76, 76, 76 }, | 42 | .irqs = { 76, 76, 76, 76 }, |
39 | }; | 43 | }; |
@@ -49,6 +53,8 @@ static struct platform_device scif1_device = { | |||
49 | static struct plat_sci_port scif2_platform_data = { | 53 | static struct plat_sci_port scif2_platform_data = { |
50 | .mapbase = 0xffe10000, | 54 | .mapbase = 0xffe10000, |
51 | .flags = UPF_BOOT_AUTOCONF, | 55 | .flags = UPF_BOOT_AUTOCONF, |
56 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
57 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
52 | .type = PORT_SCIF, | 58 | .type = PORT_SCIF, |
53 | .irqs = { 104, 104, 104, 104 }, | 59 | .irqs = { 104, 104, 104, 104 }, |
54 | }; | 60 | }; |
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c index 7270d7fd6761..2c6aa22cf5f6 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c | |||
@@ -17,6 +17,8 @@ | |||
17 | static struct plat_sci_port scif0_platform_data = { | 17 | static struct plat_sci_port scif0_platform_data = { |
18 | .mapbase = 0xff923000, | 18 | .mapbase = 0xff923000, |
19 | .flags = UPF_BOOT_AUTOCONF, | 19 | .flags = UPF_BOOT_AUTOCONF, |
20 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, | ||
21 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
20 | .type = PORT_SCIF, | 22 | .type = PORT_SCIF, |
21 | .irqs = { 61, 61, 61, 61 }, | 23 | .irqs = { 61, 61, 61, 61 }, |
22 | }; | 24 | }; |
@@ -32,6 +34,8 @@ static struct platform_device scif0_device = { | |||
32 | static struct plat_sci_port scif1_platform_data = { | 34 | static struct plat_sci_port scif1_platform_data = { |
33 | .mapbase = 0xff924000, | 35 | .mapbase = 0xff924000, |
34 | .flags = UPF_BOOT_AUTOCONF, | 36 | .flags = UPF_BOOT_AUTOCONF, |
37 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, | ||
38 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
35 | .type = PORT_SCIF, | 39 | .type = PORT_SCIF, |
36 | .irqs = { 62, 62, 62, 62 }, | 40 | .irqs = { 62, 62, 62, 62 }, |
37 | }; | 41 | }; |
@@ -47,6 +51,8 @@ static struct platform_device scif1_device = { | |||
47 | static struct plat_sci_port scif2_platform_data = { | 51 | static struct plat_sci_port scif2_platform_data = { |
48 | .mapbase = 0xff925000, | 52 | .mapbase = 0xff925000, |
49 | .flags = UPF_BOOT_AUTOCONF, | 53 | .flags = UPF_BOOT_AUTOCONF, |
54 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, | ||
55 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
50 | .type = PORT_SCIF, | 56 | .type = PORT_SCIF, |
51 | .irqs = { 63, 63, 63, 63 }, | 57 | .irqs = { 63, 63, 63, 63 }, |
52 | }; | 58 | }; |
@@ -62,6 +68,8 @@ static struct platform_device scif2_device = { | |||
62 | static struct plat_sci_port scif3_platform_data = { | 68 | static struct plat_sci_port scif3_platform_data = { |
63 | .mapbase = 0xff926000, | 69 | .mapbase = 0xff926000, |
64 | .flags = UPF_BOOT_AUTOCONF, | 70 | .flags = UPF_BOOT_AUTOCONF, |
71 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, | ||
72 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
65 | .type = PORT_SCIF, | 73 | .type = PORT_SCIF, |
66 | .irqs = { 64, 64, 64, 64 }, | 74 | .irqs = { 64, 64, 64, 64 }, |
67 | }; | 75 | }; |
@@ -77,6 +85,8 @@ static struct platform_device scif3_device = { | |||
77 | static struct plat_sci_port scif4_platform_data = { | 85 | static struct plat_sci_port scif4_platform_data = { |
78 | .mapbase = 0xff927000, | 86 | .mapbase = 0xff927000, |
79 | .flags = UPF_BOOT_AUTOCONF, | 87 | .flags = UPF_BOOT_AUTOCONF, |
88 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, | ||
89 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
80 | .type = PORT_SCIF, | 90 | .type = PORT_SCIF, |
81 | .irqs = { 65, 65, 65, 65 }, | 91 | .irqs = { 65, 65, 65, 65 }, |
82 | }; | 92 | }; |
@@ -92,6 +102,8 @@ static struct platform_device scif4_device = { | |||
92 | static struct plat_sci_port scif5_platform_data = { | 102 | static struct plat_sci_port scif5_platform_data = { |
93 | .mapbase = 0xff928000, | 103 | .mapbase = 0xff928000, |
94 | .flags = UPF_BOOT_AUTOCONF, | 104 | .flags = UPF_BOOT_AUTOCONF, |
105 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, | ||
106 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
95 | .type = PORT_SCIF, | 107 | .type = PORT_SCIF, |
96 | .irqs = { 66, 66, 66, 66 }, | 108 | .irqs = { 66, 66, 66, 66 }, |
97 | }; | 109 | }; |
@@ -107,6 +119,8 @@ static struct platform_device scif5_device = { | |||
107 | static struct plat_sci_port scif6_platform_data = { | 119 | static struct plat_sci_port scif6_platform_data = { |
108 | .mapbase = 0xff929000, | 120 | .mapbase = 0xff929000, |
109 | .flags = UPF_BOOT_AUTOCONF, | 121 | .flags = UPF_BOOT_AUTOCONF, |
122 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, | ||
123 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
110 | .type = PORT_SCIF, | 124 | .type = PORT_SCIF, |
111 | .irqs = { 67, 67, 67, 67 }, | 125 | .irqs = { 67, 67, 67, 67 }, |
112 | }; | 126 | }; |
@@ -122,6 +136,8 @@ static struct platform_device scif6_device = { | |||
122 | static struct plat_sci_port scif7_platform_data = { | 136 | static struct plat_sci_port scif7_platform_data = { |
123 | .mapbase = 0xff92a000, | 137 | .mapbase = 0xff92a000, |
124 | .flags = UPF_BOOT_AUTOCONF, | 138 | .flags = UPF_BOOT_AUTOCONF, |
139 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, | ||
140 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
125 | .type = PORT_SCIF, | 141 | .type = PORT_SCIF, |
126 | .irqs = { 68, 68, 68, 68 }, | 142 | .irqs = { 68, 68, 68, 68 }, |
127 | }; | 143 | }; |
@@ -137,6 +153,8 @@ static struct platform_device scif7_device = { | |||
137 | static struct plat_sci_port scif8_platform_data = { | 153 | static struct plat_sci_port scif8_platform_data = { |
138 | .mapbase = 0xff92b000, | 154 | .mapbase = 0xff92b000, |
139 | .flags = UPF_BOOT_AUTOCONF, | 155 | .flags = UPF_BOOT_AUTOCONF, |
156 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, | ||
157 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
140 | .type = PORT_SCIF, | 158 | .type = PORT_SCIF, |
141 | .irqs = { 69, 69, 69, 69 }, | 159 | .irqs = { 69, 69, 69, 69 }, |
142 | }; | 160 | }; |
@@ -152,6 +170,8 @@ static struct platform_device scif8_device = { | |||
152 | static struct plat_sci_port scif9_platform_data = { | 170 | static struct plat_sci_port scif9_platform_data = { |
153 | .mapbase = 0xff92c000, | 171 | .mapbase = 0xff92c000, |
154 | .flags = UPF_BOOT_AUTOCONF, | 172 | .flags = UPF_BOOT_AUTOCONF, |
173 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, | ||
174 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
155 | .type = PORT_SCIF, | 175 | .type = PORT_SCIF, |
156 | .irqs = { 70, 70, 70, 70 }, | 176 | .irqs = { 70, 70, 70, 70 }, |
157 | }; | 177 | }; |
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index 0f414864f76b..08add7fa6849 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c | |||
@@ -20,6 +20,8 @@ | |||
20 | static struct plat_sci_port scif0_platform_data = { | 20 | static struct plat_sci_port scif0_platform_data = { |
21 | .mapbase = 0xffe00000, | 21 | .mapbase = 0xffe00000, |
22 | .flags = UPF_BOOT_AUTOCONF, | 22 | .flags = UPF_BOOT_AUTOCONF, |
23 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, | ||
24 | .scbrr_algo_id = SCBRR_ALGO_1, | ||
23 | .type = PORT_SCIF, | 25 | .type = PORT_SCIF, |
24 | .irqs = { 40, 40, 40, 40 }, | 26 | .irqs = { 40, 40, 40, 40 }, |
25 | }; | 27 | }; |
@@ -35,6 +37,8 @@ static struct platform_device scif0_device = { | |||
35 | static struct plat_sci_port scif1_platform_data = { | 37 | static struct plat_sci_port scif1_platform_data = { |
36 | .mapbase = 0xffe10000, | 38 | .mapbase = 0xffe10000, |
37 | .flags = UPF_BOOT_AUTOCONF, | 39 | .flags = UPF_BOOT_AUTOCONF, |
40 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, | ||
41 | .scbrr_algo_id = SCBRR_ALGO_1, | ||
38 | .type = PORT_SCIF, | 42 | .type = PORT_SCIF, |
39 | .irqs = { 76, 76, 76, 76 }, | 43 | .irqs = { 76, 76, 76, 76 }, |
40 | }; | 44 | }; |
@@ -379,6 +383,7 @@ static int __init sh7780_devices_setup(void) | |||
379 | ARRAY_SIZE(sh7780_devices)); | 383 | ARRAY_SIZE(sh7780_devices)); |
380 | } | 384 | } |
381 | arch_initcall(sh7780_devices_setup); | 385 | arch_initcall(sh7780_devices_setup); |
386 | |||
382 | static struct platform_device *sh7780_early_devices[] __initdata = { | 387 | static struct platform_device *sh7780_early_devices[] __initdata = { |
383 | &scif0_device, | 388 | &scif0_device, |
384 | &scif1_device, | 389 | &scif1_device, |
@@ -392,6 +397,13 @@ static struct platform_device *sh7780_early_devices[] __initdata = { | |||
392 | 397 | ||
393 | void __init plat_early_device_setup(void) | 398 | void __init plat_early_device_setup(void) |
394 | { | 399 | { |
400 | if (mach_is_sh2007()) { | ||
401 | scif0_platform_data.scscr &= ~SCSCR_CKE1; | ||
402 | scif0_platform_data.scbrr_algo_id = SCBRR_ALGO_2; | ||
403 | scif1_platform_data.scscr &= ~SCSCR_CKE1; | ||
404 | scif1_platform_data.scbrr_algo_id = SCBRR_ALGO_2; | ||
405 | } | ||
406 | |||
395 | early_platform_add_devices(sh7780_early_devices, | 407 | early_platform_add_devices(sh7780_early_devices, |
396 | ARRAY_SIZE(sh7780_early_devices)); | 408 | ARRAY_SIZE(sh7780_early_devices)); |
397 | } | 409 | } |
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index c9a572bc6dc8..18d8fc136fb2 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c | |||
@@ -23,6 +23,8 @@ | |||
23 | static struct plat_sci_port scif0_platform_data = { | 23 | static struct plat_sci_port scif0_platform_data = { |
24 | .mapbase = 0xffea0000, | 24 | .mapbase = 0xffea0000, |
25 | .flags = UPF_BOOT_AUTOCONF, | 25 | .flags = UPF_BOOT_AUTOCONF, |
26 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, | ||
27 | .scbrr_algo_id = SCBRR_ALGO_1, | ||
26 | .type = PORT_SCIF, | 28 | .type = PORT_SCIF, |
27 | .irqs = { 40, 40, 40, 40 }, | 29 | .irqs = { 40, 40, 40, 40 }, |
28 | }; | 30 | }; |
@@ -38,6 +40,8 @@ static struct platform_device scif0_device = { | |||
38 | static struct plat_sci_port scif1_platform_data = { | 40 | static struct plat_sci_port scif1_platform_data = { |
39 | .mapbase = 0xffeb0000, | 41 | .mapbase = 0xffeb0000, |
40 | .flags = UPF_BOOT_AUTOCONF, | 42 | .flags = UPF_BOOT_AUTOCONF, |
43 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, | ||
44 | .scbrr_algo_id = SCBRR_ALGO_1, | ||
41 | .type = PORT_SCIF, | 45 | .type = PORT_SCIF, |
42 | .irqs = { 44, 44, 44, 44 }, | 46 | .irqs = { 44, 44, 44, 44 }, |
43 | }; | 47 | }; |
@@ -53,6 +57,8 @@ static struct platform_device scif1_device = { | |||
53 | static struct plat_sci_port scif2_platform_data = { | 57 | static struct plat_sci_port scif2_platform_data = { |
54 | .mapbase = 0xffec0000, | 58 | .mapbase = 0xffec0000, |
55 | .flags = UPF_BOOT_AUTOCONF, | 59 | .flags = UPF_BOOT_AUTOCONF, |
60 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, | ||
61 | .scbrr_algo_id = SCBRR_ALGO_1, | ||
56 | .type = PORT_SCIF, | 62 | .type = PORT_SCIF, |
57 | .irqs = { 60, 60, 60, 60 }, | 63 | .irqs = { 60, 60, 60, 60 }, |
58 | }; | 64 | }; |
@@ -68,6 +74,8 @@ static struct platform_device scif2_device = { | |||
68 | static struct plat_sci_port scif3_platform_data = { | 74 | static struct plat_sci_port scif3_platform_data = { |
69 | .mapbase = 0xffed0000, | 75 | .mapbase = 0xffed0000, |
70 | .flags = UPF_BOOT_AUTOCONF, | 76 | .flags = UPF_BOOT_AUTOCONF, |
77 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, | ||
78 | .scbrr_algo_id = SCBRR_ALGO_1, | ||
71 | .type = PORT_SCIF, | 79 | .type = PORT_SCIF, |
72 | .irqs = { 61, 61, 61, 61 }, | 80 | .irqs = { 61, 61, 61, 61 }, |
73 | }; | 81 | }; |
@@ -83,6 +91,8 @@ static struct platform_device scif3_device = { | |||
83 | static struct plat_sci_port scif4_platform_data = { | 91 | static struct plat_sci_port scif4_platform_data = { |
84 | .mapbase = 0xffee0000, | 92 | .mapbase = 0xffee0000, |
85 | .flags = UPF_BOOT_AUTOCONF, | 93 | .flags = UPF_BOOT_AUTOCONF, |
94 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, | ||
95 | .scbrr_algo_id = SCBRR_ALGO_1, | ||
86 | .type = PORT_SCIF, | 96 | .type = PORT_SCIF, |
87 | .irqs = { 62, 62, 62, 62 }, | 97 | .irqs = { 62, 62, 62, 62 }, |
88 | }; | 98 | }; |
@@ -98,6 +108,8 @@ static struct platform_device scif4_device = { | |||
98 | static struct plat_sci_port scif5_platform_data = { | 108 | static struct plat_sci_port scif5_platform_data = { |
99 | .mapbase = 0xffef0000, | 109 | .mapbase = 0xffef0000, |
100 | .flags = UPF_BOOT_AUTOCONF, | 110 | .flags = UPF_BOOT_AUTOCONF, |
111 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, | ||
112 | .scbrr_algo_id = SCBRR_ALGO_1, | ||
101 | .type = PORT_SCIF, | 113 | .type = PORT_SCIF, |
102 | .irqs = { 63, 63, 63, 63 }, | 114 | .irqs = { 63, 63, 63, 63 }, |
103 | }; | 115 | }; |
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c index 0170dbda1d00..1656b8c91faf 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c | |||
@@ -29,6 +29,8 @@ | |||
29 | static struct plat_sci_port scif0_platform_data = { | 29 | static struct plat_sci_port scif0_platform_data = { |
30 | .mapbase = 0xffea0000, | 30 | .mapbase = 0xffea0000, |
31 | .flags = UPF_BOOT_AUTOCONF, | 31 | .flags = UPF_BOOT_AUTOCONF, |
32 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, | ||
33 | .scbrr_algo_id = SCBRR_ALGO_1, | ||
32 | .type = PORT_SCIF, | 34 | .type = PORT_SCIF, |
33 | .irqs = { 40, 41, 43, 42 }, | 35 | .irqs = { 40, 41, 43, 42 }, |
34 | }; | 36 | }; |
@@ -47,6 +49,8 @@ static struct platform_device scif0_device = { | |||
47 | static struct plat_sci_port scif1_platform_data = { | 49 | static struct plat_sci_port scif1_platform_data = { |
48 | .mapbase = 0xffeb0000, | 50 | .mapbase = 0xffeb0000, |
49 | .flags = UPF_BOOT_AUTOCONF, | 51 | .flags = UPF_BOOT_AUTOCONF, |
52 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, | ||
53 | .scbrr_algo_id = SCBRR_ALGO_1, | ||
50 | .type = PORT_SCIF, | 54 | .type = PORT_SCIF, |
51 | .irqs = { 44, 44, 44, 44 }, | 55 | .irqs = { 44, 44, 44, 44 }, |
52 | }; | 56 | }; |
@@ -62,6 +66,8 @@ static struct platform_device scif1_device = { | |||
62 | static struct plat_sci_port scif2_platform_data = { | 66 | static struct plat_sci_port scif2_platform_data = { |
63 | .mapbase = 0xffec0000, | 67 | .mapbase = 0xffec0000, |
64 | .flags = UPF_BOOT_AUTOCONF, | 68 | .flags = UPF_BOOT_AUTOCONF, |
69 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, | ||
70 | .scbrr_algo_id = SCBRR_ALGO_1, | ||
65 | .type = PORT_SCIF, | 71 | .type = PORT_SCIF, |
66 | .irqs = { 50, 50, 50, 50 }, | 72 | .irqs = { 50, 50, 50, 50 }, |
67 | }; | 73 | }; |
@@ -77,6 +83,8 @@ static struct platform_device scif2_device = { | |||
77 | static struct plat_sci_port scif3_platform_data = { | 83 | static struct plat_sci_port scif3_platform_data = { |
78 | .mapbase = 0xffed0000, | 84 | .mapbase = 0xffed0000, |
79 | .flags = UPF_BOOT_AUTOCONF, | 85 | .flags = UPF_BOOT_AUTOCONF, |
86 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, | ||
87 | .scbrr_algo_id = SCBRR_ALGO_1, | ||
80 | .type = PORT_SCIF, | 88 | .type = PORT_SCIF, |
81 | .irqs = { 51, 51, 51, 51 }, | 89 | .irqs = { 51, 51, 51, 51 }, |
82 | }; | 90 | }; |
@@ -92,6 +100,8 @@ static struct platform_device scif3_device = { | |||
92 | static struct plat_sci_port scif4_platform_data = { | 100 | static struct plat_sci_port scif4_platform_data = { |
93 | .mapbase = 0xffee0000, | 101 | .mapbase = 0xffee0000, |
94 | .flags = UPF_BOOT_AUTOCONF, | 102 | .flags = UPF_BOOT_AUTOCONF, |
103 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, | ||
104 | .scbrr_algo_id = SCBRR_ALGO_1, | ||
95 | .type = PORT_SCIF, | 105 | .type = PORT_SCIF, |
96 | .irqs = { 52, 52, 52, 52 }, | 106 | .irqs = { 52, 52, 52, 52 }, |
97 | }; | 107 | }; |
@@ -107,6 +117,8 @@ static struct platform_device scif4_device = { | |||
107 | static struct plat_sci_port scif5_platform_data = { | 117 | static struct plat_sci_port scif5_platform_data = { |
108 | .mapbase = 0xffef0000, | 118 | .mapbase = 0xffef0000, |
109 | .flags = UPF_BOOT_AUTOCONF, | 119 | .flags = UPF_BOOT_AUTOCONF, |
120 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, | ||
121 | .scbrr_algo_id = SCBRR_ALGO_1, | ||
110 | .type = PORT_SCIF, | 122 | .type = PORT_SCIF, |
111 | .irqs = { 53, 53, 53, 53 }, | 123 | .irqs = { 53, 53, 53, 53 }, |
112 | }; | 124 | }; |
diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c index 013f0b144489..bb208806dc1a 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c | |||
@@ -29,6 +29,8 @@ | |||
29 | static struct plat_sci_port scif0_platform_data = { | 29 | static struct plat_sci_port scif0_platform_data = { |
30 | .mapbase = 0xffc30000, | 30 | .mapbase = 0xffc30000, |
31 | .flags = UPF_BOOT_AUTOCONF, | 31 | .flags = UPF_BOOT_AUTOCONF, |
32 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
33 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
32 | .type = PORT_SCIF, | 34 | .type = PORT_SCIF, |
33 | .irqs = { 40, 41, 43, 42 }, | 35 | .irqs = { 40, 41, 43, 42 }, |
34 | }; | 36 | }; |
@@ -44,6 +46,8 @@ static struct platform_device scif0_device = { | |||
44 | static struct plat_sci_port scif1_platform_data = { | 46 | static struct plat_sci_port scif1_platform_data = { |
45 | .mapbase = 0xffc40000, | 47 | .mapbase = 0xffc40000, |
46 | .flags = UPF_BOOT_AUTOCONF, | 48 | .flags = UPF_BOOT_AUTOCONF, |
49 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
50 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
47 | .type = PORT_SCIF, | 51 | .type = PORT_SCIF, |
48 | .irqs = { 44, 45, 47, 46 }, | 52 | .irqs = { 44, 45, 47, 46 }, |
49 | }; | 53 | }; |
@@ -59,6 +63,8 @@ static struct platform_device scif1_device = { | |||
59 | static struct plat_sci_port scif2_platform_data = { | 63 | static struct plat_sci_port scif2_platform_data = { |
60 | .mapbase = 0xffc60000, | 64 | .mapbase = 0xffc60000, |
61 | .flags = UPF_BOOT_AUTOCONF, | 65 | .flags = UPF_BOOT_AUTOCONF, |
66 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
67 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
62 | .type = PORT_SCIF, | 68 | .type = PORT_SCIF, |
63 | .irqs = { 52, 53, 55, 54 }, | 69 | .irqs = { 52, 53, 55, 54 }, |
64 | }; | 70 | }; |
diff --git a/arch/sh/kernel/cpu/sh5/setup-sh5.c b/arch/sh/kernel/cpu/sh5/setup-sh5.c index d910666142b1..18419f1de963 100644 --- a/arch/sh/kernel/cpu/sh5/setup-sh5.c +++ b/arch/sh/kernel/cpu/sh5/setup-sh5.c | |||
@@ -19,6 +19,8 @@ | |||
19 | static struct plat_sci_port scif0_platform_data = { | 19 | static struct plat_sci_port scif0_platform_data = { |
20 | .mapbase = PHYS_PERIPHERAL_BLOCK + 0x01030000, | 20 | .mapbase = PHYS_PERIPHERAL_BLOCK + 0x01030000, |
21 | .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, | 21 | .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, |
22 | .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, | ||
23 | .scbrr_algo_id = SCBRR_ALGO_2, | ||
22 | .type = PORT_SCIF, | 24 | .type = PORT_SCIF, |
23 | .irqs = { 39, 40, 42, 0 }, | 25 | .irqs = { 39, 40, 42, 0 }, |
24 | }; | 26 | }; |
diff --git a/arch/sh/kernel/cpu/shmobile/cpuidle.c b/arch/sh/kernel/cpu/shmobile/cpuidle.c index 83972aa319c2..c19e2a940e3f 100644 --- a/arch/sh/kernel/cpu/shmobile/cpuidle.c +++ b/arch/sh/kernel/cpu/shmobile/cpuidle.c | |||
@@ -81,7 +81,6 @@ void sh_mobile_setup_cpuidle(void) | |||
81 | state->target_residency = 1 * 2; | 81 | state->target_residency = 1 * 2; |
82 | state->power_usage = 3; | 82 | state->power_usage = 3; |
83 | state->flags = 0; | 83 | state->flags = 0; |
84 | state->flags |= CPUIDLE_FLAG_SHALLOW; | ||
85 | state->flags |= CPUIDLE_FLAG_TIME_VALID; | 84 | state->flags |= CPUIDLE_FLAG_TIME_VALID; |
86 | state->enter = cpuidle_sleep_enter; | 85 | state->enter = cpuidle_sleep_enter; |
87 | 86 | ||
diff --git a/arch/sh/kernel/cpu/shmobile/pm.c b/arch/sh/kernel/cpu/shmobile/pm.c index e55968712706..a6f95ae4aae7 100644 --- a/arch/sh/kernel/cpu/shmobile/pm.c +++ b/arch/sh/kernel/cpu/shmobile/pm.c | |||
@@ -141,7 +141,7 @@ static int sh_pm_enter(suspend_state_t state) | |||
141 | return 0; | 141 | return 0; |
142 | } | 142 | } |
143 | 143 | ||
144 | static struct platform_suspend_ops sh_pm_ops = { | 144 | static const struct platform_suspend_ops sh_pm_ops = { |
145 | .enter = sh_pm_enter, | 145 | .enter = sh_pm_enter, |
146 | .valid = suspend_valid_only_mem, | 146 | .valid = suspend_valid_only_mem, |
147 | }; | 147 | }; |
diff --git a/arch/sh/mm/cache-sh5.c b/arch/sh/mm/cache-sh5.c index eb4cc4ec7952..d1bffbcd9d52 100644 --- a/arch/sh/mm/cache-sh5.c +++ b/arch/sh/mm/cache-sh5.c | |||
@@ -568,7 +568,7 @@ static void sh5_flush_dcache_page(void *page) | |||
568 | } | 568 | } |
569 | 569 | ||
570 | /* | 570 | /* |
571 | * Flush the range [start,end] of kernel virtual adddress space from | 571 | * Flush the range [start,end] of kernel virtual address space from |
572 | * the I-cache. The corresponding range must be purged from the | 572 | * the I-cache. The corresponding range must be purged from the |
573 | * D-cache also because the SH-5 doesn't have cache snooping between | 573 | * D-cache also because the SH-5 doesn't have cache snooping between |
574 | * the caches. The addresses will be visible through the superpage | 574 | * the caches. The addresses will be visible through the superpage |
diff --git a/arch/sh/mm/hugetlbpage.c b/arch/sh/mm/hugetlbpage.c index 9163db3e8d15..d7762349ea48 100644 --- a/arch/sh/mm/hugetlbpage.c +++ b/arch/sh/mm/hugetlbpage.c | |||
@@ -35,7 +35,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, | |||
35 | if (pud) { | 35 | if (pud) { |
36 | pmd = pmd_alloc(mm, pud, addr); | 36 | pmd = pmd_alloc(mm, pud, addr); |
37 | if (pmd) | 37 | if (pmd) |
38 | pte = pte_alloc_map(mm, pmd, addr); | 38 | pte = pte_alloc_map(mm, NULL, pmd, addr); |
39 | } | 39 | } |
40 | } | 40 | } |
41 | 41 | ||
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 3385b28acaac..0d3f912e3334 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * linux/arch/sh/mm/init.c | 2 | * linux/arch/sh/mm/init.c |
3 | * | 3 | * |
4 | * Copyright (C) 1999 Niibe Yutaka | 4 | * Copyright (C) 1999 Niibe Yutaka |
5 | * Copyright (C) 2002 - 2010 Paul Mundt | 5 | * Copyright (C) 2002 - 2011 Paul Mundt |
6 | * | 6 | * |
7 | * Based on linux/arch/i386/mm/init.c: | 7 | * Based on linux/arch/i386/mm/init.c: |
8 | * Copyright (C) 1995 Linus Torvalds | 8 | * Copyright (C) 1995 Linus Torvalds |
@@ -325,11 +325,17 @@ void __init paging_init(void) | |||
325 | int nid; | 325 | int nid; |
326 | 326 | ||
327 | memblock_init(); | 327 | memblock_init(); |
328 | |||
329 | sh_mv.mv_mem_init(); | 328 | sh_mv.mv_mem_init(); |
330 | 329 | ||
331 | early_reserve_mem(); | 330 | early_reserve_mem(); |
332 | 331 | ||
332 | /* | ||
333 | * Once the early reservations are out of the way, give the | ||
334 | * platforms a chance to kick out some memory. | ||
335 | */ | ||
336 | if (sh_mv.mv_mem_reserve) | ||
337 | sh_mv.mv_mem_reserve(); | ||
338 | |||
333 | memblock_enforce_memory_limit(memory_limit); | 339 | memblock_enforce_memory_limit(memory_limit); |
334 | memblock_analyze(); | 340 | memblock_analyze(); |
335 | 341 | ||
diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types index 0e68465e7b50..6dd56c4d0054 100644 --- a/arch/sh/tools/mach-types +++ b/arch/sh/tools/mach-types | |||
@@ -9,6 +9,7 @@ SE SH_SOLUTION_ENGINE | |||
9 | HIGHLANDER SH_HIGHLANDER | 9 | HIGHLANDER SH_HIGHLANDER |
10 | RTS7751R2D SH_RTS7751R2D | 10 | RTS7751R2D SH_RTS7751R2D |
11 | RSK SH_RSK | 11 | RSK SH_RSK |
12 | ALPHA_BOARD SH_ALPHA_BOARD | ||
12 | 13 | ||
13 | # | 14 | # |
14 | # List of companion chips / MFDs. | 15 | # List of companion chips / MFDs. |
@@ -61,3 +62,5 @@ ESPT SH_ESPT | |||
61 | POLARIS SH_POLARIS | 62 | POLARIS SH_POLARIS |
62 | KFR2R09 SH_KFR2R09 | 63 | KFR2R09 SH_KFR2R09 |
63 | ECOVEC SH_ECOVEC | 64 | ECOVEC SH_ECOVEC |
65 | APSH4A3A SH_APSH4A3A | ||
66 | APSH4AD0A SH_APSH4AD0A | ||
diff --git a/arch/sparc/kernel/module.c b/arch/sparc/kernel/module.c index ee3c7dde8d9f..8d348c474a2f 100644 --- a/arch/sparc/kernel/module.c +++ b/arch/sparc/kernel/module.c | |||
@@ -23,17 +23,11 @@ | |||
23 | 23 | ||
24 | static void *module_map(unsigned long size) | 24 | static void *module_map(unsigned long size) |
25 | { | 25 | { |
26 | struct vm_struct *area; | 26 | if (PAGE_ALIGN(size) > MODULES_LEN) |
27 | |||
28 | size = PAGE_ALIGN(size); | ||
29 | if (!size || size > MODULES_LEN) | ||
30 | return NULL; | ||
31 | |||
32 | area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END); | ||
33 | if (!area) | ||
34 | return NULL; | 27 | return NULL; |
35 | 28 | return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END, | |
36 | return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL); | 29 | GFP_KERNEL, PAGE_KERNEL, -1, |
30 | __builtin_return_address(0)); | ||
37 | } | 31 | } |
38 | 32 | ||
39 | static char *dot2underscore(char *name) | 33 | static char *dot2underscore(char *name) |
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c index 42ad2ba85010..1e9770936c3b 100644 --- a/arch/sparc/kernel/traps_64.c +++ b/arch/sparc/kernel/traps_64.c | |||
@@ -622,7 +622,7 @@ static const char CHAFSR_PERR_msg[] = | |||
622 | static const char CHAFSR_IERR_msg[] = | 622 | static const char CHAFSR_IERR_msg[] = |
623 | "Internal processor error"; | 623 | "Internal processor error"; |
624 | static const char CHAFSR_ISAP_msg[] = | 624 | static const char CHAFSR_ISAP_msg[] = |
625 | "System request parity error on incoming addresss"; | 625 | "System request parity error on incoming address"; |
626 | static const char CHAFSR_UCU_msg[] = | 626 | static const char CHAFSR_UCU_msg[] = |
627 | "Uncorrectable E-cache ECC error for ifetch/data"; | 627 | "Uncorrectable E-cache ECC error for ifetch/data"; |
628 | static const char CHAFSR_UCC_msg[] = | 628 | static const char CHAFSR_UCC_msg[] = |
diff --git a/arch/sparc/mm/generic_32.c b/arch/sparc/mm/generic_32.c index 5edcac184eaf..e6067b75f11c 100644 --- a/arch/sparc/mm/generic_32.c +++ b/arch/sparc/mm/generic_32.c | |||
@@ -50,7 +50,7 @@ static inline int io_remap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned | |||
50 | end = PGDIR_SIZE; | 50 | end = PGDIR_SIZE; |
51 | offset -= address; | 51 | offset -= address; |
52 | do { | 52 | do { |
53 | pte_t * pte = pte_alloc_map(mm, pmd, address); | 53 | pte_t *pte = pte_alloc_map(mm, NULL, pmd, address); |
54 | if (!pte) | 54 | if (!pte) |
55 | return -ENOMEM; | 55 | return -ENOMEM; |
56 | io_remap_pte_range(mm, pte, address, end - address, address + offset, prot, space); | 56 | io_remap_pte_range(mm, pte, address, end - address, address + offset, prot, space); |
diff --git a/arch/sparc/mm/generic_64.c b/arch/sparc/mm/generic_64.c index 04f2bf4cd571..3cb00dfd4bd6 100644 --- a/arch/sparc/mm/generic_64.c +++ b/arch/sparc/mm/generic_64.c | |||
@@ -92,7 +92,7 @@ static inline int io_remap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned | |||
92 | end = PGDIR_SIZE; | 92 | end = PGDIR_SIZE; |
93 | offset -= address; | 93 | offset -= address; |
94 | do { | 94 | do { |
95 | pte_t * pte = pte_alloc_map(mm, pmd, address); | 95 | pte_t *pte = pte_alloc_map(mm, NULL, pmd, address); |
96 | if (!pte) | 96 | if (!pte) |
97 | return -ENOMEM; | 97 | return -ENOMEM; |
98 | io_remap_pte_range(mm, pte, address, end - address, address + offset, prot, space); | 98 | io_remap_pte_range(mm, pte, address, end - address, address + offset, prot, space); |
diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c index 5fdddf134caa..f4e97646ce23 100644 --- a/arch/sparc/mm/hugetlbpage.c +++ b/arch/sparc/mm/hugetlbpage.c | |||
@@ -214,7 +214,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, | |||
214 | if (pud) { | 214 | if (pud) { |
215 | pmd = pmd_alloc(mm, pud, addr); | 215 | pmd = pmd_alloc(mm, pud, addr); |
216 | if (pmd) | 216 | if (pmd) |
217 | pte = pte_alloc_map(mm, pmd, addr); | 217 | pte = pte_alloc_map(mm, NULL, pmd, addr); |
218 | } | 218 | } |
219 | return pte; | 219 | return pte; |
220 | } | 220 | } |
diff --git a/arch/um/Kconfig.um b/arch/um/Kconfig.um index 50d6aa20c353..f8d1d0d47fe6 100644 --- a/arch/um/Kconfig.um +++ b/arch/um/Kconfig.um | |||
@@ -131,7 +131,7 @@ config NR_CPUS | |||
131 | 131 | ||
132 | config HIGHMEM | 132 | config HIGHMEM |
133 | bool "Highmem support (EXPERIMENTAL)" | 133 | bool "Highmem support (EXPERIMENTAL)" |
134 | depends on !64BIT && EXPERIMENTAL | 134 | depends on !64BIT && BROKEN |
135 | default n | 135 | default n |
136 | help | 136 | help |
137 | This was used to allow UML to run with big amounts of memory. | 137 | This was used to allow UML to run with big amounts of memory. |
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 1664cce7b0ac..050e4ddbbb65 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c | |||
@@ -821,12 +821,12 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty, | |||
821 | 821 | ||
822 | static void unregister_winch(struct tty_struct *tty) | 822 | static void unregister_winch(struct tty_struct *tty) |
823 | { | 823 | { |
824 | struct list_head *ele; | 824 | struct list_head *ele, *next; |
825 | struct winch *winch; | 825 | struct winch *winch; |
826 | 826 | ||
827 | spin_lock(&winch_handler_lock); | 827 | spin_lock(&winch_handler_lock); |
828 | 828 | ||
829 | list_for_each(ele, &winch_handlers) { | 829 | list_for_each_safe(ele, next, &winch_handlers) { |
830 | winch = list_entry(ele, struct winch, list); | 830 | winch = list_entry(ele, struct winch, list); |
831 | if (winch->tty == tty) { | 831 | if (winch->tty == tty) { |
832 | free_winch(winch, 1); | 832 | free_winch(winch, 1); |
diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c index 8501e7d0015c..7e0619c2c2c6 100644 --- a/arch/um/drivers/mmapper_kern.c +++ b/arch/um/drivers/mmapper_kern.c | |||
@@ -37,13 +37,7 @@ static ssize_t mmapper_write(struct file *file, const char __user *buf, | |||
37 | if (*ppos > mmapper_size) | 37 | if (*ppos > mmapper_size) |
38 | return -EINVAL; | 38 | return -EINVAL; |
39 | 39 | ||
40 | if (count > mmapper_size - *ppos) | 40 | return simple_write_to_buffer(v_buf, mmapper_size, ppos, buf, count); |
41 | count = mmapper_size - *ppos; | ||
42 | |||
43 | if (copy_from_user(&v_buf[*ppos], buf, count)) | ||
44 | return -EFAULT; | ||
45 | |||
46 | return count; | ||
47 | } | 41 | } |
48 | 42 | ||
49 | static long mmapper_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 43 | static long mmapper_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
@@ -137,3 +131,4 @@ module_exit(mmapper_exit); | |||
137 | 131 | ||
138 | MODULE_AUTHOR("Greg Lonnon <glonnon@ridgerun.com>"); | 132 | MODULE_AUTHOR("Greg Lonnon <glonnon@ridgerun.com>"); |
139 | MODULE_DESCRIPTION("DSPLinux simulator mmapper driver"); | 133 | MODULE_DESCRIPTION("DSPLinux simulator mmapper driver"); |
134 | MODULE_LICENSE("GPL"); | ||
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c index 3d099f974785..1aee587e9c5d 100644 --- a/arch/um/kernel/skas/mmu.c +++ b/arch/um/kernel/skas/mmu.c | |||
@@ -31,7 +31,7 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc, | |||
31 | if (!pmd) | 31 | if (!pmd) |
32 | goto out_pmd; | 32 | goto out_pmd; |
33 | 33 | ||
34 | pte = pte_alloc_map(mm, pmd, proc); | 34 | pte = pte_alloc_map(mm, NULL, pmd, proc); |
35 | if (!pte) | 35 | if (!pte) |
36 | goto out_pte; | 36 | goto out_pte; |
37 | 37 | ||
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index b6fccb07123e..36ed2e2c896b 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -51,6 +51,7 @@ config X86 | |||
51 | select HAVE_KERNEL_GZIP | 51 | select HAVE_KERNEL_GZIP |
52 | select HAVE_KERNEL_BZIP2 | 52 | select HAVE_KERNEL_BZIP2 |
53 | select HAVE_KERNEL_LZMA | 53 | select HAVE_KERNEL_LZMA |
54 | select HAVE_KERNEL_XZ | ||
54 | select HAVE_KERNEL_LZO | 55 | select HAVE_KERNEL_LZO |
55 | select HAVE_HW_BREAKPOINT | 56 | select HAVE_HW_BREAKPOINT |
56 | select HAVE_MIXED_BREAKPOINTS_REGS | 57 | select HAVE_MIXED_BREAKPOINTS_REGS |
@@ -65,6 +66,7 @@ config X86 | |||
65 | select HAVE_SPARSE_IRQ | 66 | select HAVE_SPARSE_IRQ |
66 | select GENERIC_IRQ_PROBE | 67 | select GENERIC_IRQ_PROBE |
67 | select GENERIC_PENDING_IRQ if SMP | 68 | select GENERIC_PENDING_IRQ if SMP |
69 | select USE_GENERIC_SMP_HELPERS if SMP | ||
68 | 70 | ||
69 | config INSTRUCTION_DECODER | 71 | config INSTRUCTION_DECODER |
70 | def_bool (KPROBES || PERF_EVENTS) | 72 | def_bool (KPROBES || PERF_EVENTS) |
@@ -203,10 +205,6 @@ config HAVE_INTEL_TXT | |||
203 | def_bool y | 205 | def_bool y |
204 | depends on EXPERIMENTAL && DMAR && ACPI | 206 | depends on EXPERIMENTAL && DMAR && ACPI |
205 | 207 | ||
206 | config USE_GENERIC_SMP_HELPERS | ||
207 | def_bool y | ||
208 | depends on SMP | ||
209 | |||
210 | config X86_32_SMP | 208 | config X86_32_SMP |
211 | def_bool y | 209 | def_bool y |
212 | depends on X86_32 && SMP | 210 | depends on X86_32 && SMP |
@@ -2078,11 +2076,17 @@ config OLPC_OPENFIRMWARE | |||
2078 | bool "Support for OLPC's Open Firmware" | 2076 | bool "Support for OLPC's Open Firmware" |
2079 | depends on !X86_64 && !X86_PAE | 2077 | depends on !X86_64 && !X86_PAE |
2080 | default n | 2078 | default n |
2079 | select OF | ||
2081 | help | 2080 | help |
2082 | This option adds support for the implementation of Open Firmware | 2081 | This option adds support for the implementation of Open Firmware |
2083 | that is used on the OLPC XO-1 Children's Machine. | 2082 | that is used on the OLPC XO-1 Children's Machine. |
2084 | If unsure, say N here. | 2083 | If unsure, say N here. |
2085 | 2084 | ||
2085 | config OLPC_OPENFIRMWARE_DT | ||
2086 | bool | ||
2087 | default y if OLPC_OPENFIRMWARE && PROC_DEVICETREE | ||
2088 | select OF_PROMTREE | ||
2089 | |||
2086 | endif # X86_32 | 2090 | endif # X86_32 |
2087 | 2091 | ||
2088 | config AMD_NB | 2092 | config AMD_NB |
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index 0c229551eead..09664efb9cee 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile | |||
@@ -4,7 +4,7 @@ | |||
4 | # create a compressed vmlinux image from the original vmlinux | 4 | # create a compressed vmlinux image from the original vmlinux |
5 | # | 5 | # |
6 | 6 | ||
7 | targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma vmlinux.bin.lzo head_$(BITS).o misc.o string.o cmdline.o early_serial_console.o piggy.o | 7 | targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma vmlinux.bin.xz vmlinux.bin.lzo head_$(BITS).o misc.o string.o cmdline.o early_serial_console.o piggy.o |
8 | 8 | ||
9 | KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2 | 9 | KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2 |
10 | KBUILD_CFLAGS += -fno-strict-aliasing -fPIC | 10 | KBUILD_CFLAGS += -fno-strict-aliasing -fPIC |
@@ -49,12 +49,15 @@ $(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y) FORCE | |||
49 | $(call if_changed,bzip2) | 49 | $(call if_changed,bzip2) |
50 | $(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) FORCE | 50 | $(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) FORCE |
51 | $(call if_changed,lzma) | 51 | $(call if_changed,lzma) |
52 | $(obj)/vmlinux.bin.xz: $(vmlinux.bin.all-y) FORCE | ||
53 | $(call if_changed,xzkern) | ||
52 | $(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y) FORCE | 54 | $(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y) FORCE |
53 | $(call if_changed,lzo) | 55 | $(call if_changed,lzo) |
54 | 56 | ||
55 | suffix-$(CONFIG_KERNEL_GZIP) := gz | 57 | suffix-$(CONFIG_KERNEL_GZIP) := gz |
56 | suffix-$(CONFIG_KERNEL_BZIP2) := bz2 | 58 | suffix-$(CONFIG_KERNEL_BZIP2) := bz2 |
57 | suffix-$(CONFIG_KERNEL_LZMA) := lzma | 59 | suffix-$(CONFIG_KERNEL_LZMA) := lzma |
60 | suffix-$(CONFIG_KERNEL_XZ) := xz | ||
58 | suffix-$(CONFIG_KERNEL_LZO) := lzo | 61 | suffix-$(CONFIG_KERNEL_LZO) := lzo |
59 | 62 | ||
60 | quiet_cmd_mkpiggy = MKPIGGY $@ | 63 | quiet_cmd_mkpiggy = MKPIGGY $@ |
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index 325c05294fc4..3a19d04cebeb 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c | |||
@@ -139,6 +139,10 @@ static int lines, cols; | |||
139 | #include "../../../../lib/decompress_unlzma.c" | 139 | #include "../../../../lib/decompress_unlzma.c" |
140 | #endif | 140 | #endif |
141 | 141 | ||
142 | #ifdef CONFIG_KERNEL_XZ | ||
143 | #include "../../../../lib/decompress_unxz.c" | ||
144 | #endif | ||
145 | |||
142 | #ifdef CONFIG_KERNEL_LZO | 146 | #ifdef CONFIG_KERNEL_LZO |
143 | #include "../../../../lib/decompress_unlzo.c" | 147 | #include "../../../../lib/decompress_unlzo.c" |
144 | #endif | 148 | #endif |
diff --git a/arch/x86/boot/compressed/mkpiggy.c b/arch/x86/boot/compressed/mkpiggy.c index 5c228129d175..646aa78ba5fd 100644 --- a/arch/x86/boot/compressed/mkpiggy.c +++ b/arch/x86/boot/compressed/mkpiggy.c | |||
@@ -74,7 +74,7 @@ int main(int argc, char *argv[]) | |||
74 | 74 | ||
75 | offs = (olen > ilen) ? olen - ilen : 0; | 75 | offs = (olen > ilen) ? olen - ilen : 0; |
76 | offs += olen >> 12; /* Add 8 bytes for each 32K block */ | 76 | offs += olen >> 12; /* Add 8 bytes for each 32K block */ |
77 | offs += 32*1024 + 18; /* Add 32K + 18 bytes slack */ | 77 | offs += 64*1024 + 128; /* Add 64K + 128 bytes slack */ |
78 | offs = (offs+4095) & ~4095; /* Round to a 4K boundary */ | 78 | offs = (offs+4095) & ~4095; /* Round to a 4K boundary */ |
79 | 79 | ||
80 | printf(".section \".rodata..compressed\",\"a\",@progbits\n"); | 80 | printf(".section \".rodata..compressed\",\"a\",@progbits\n"); |
diff --git a/arch/x86/crypto/aesni-intel_asm.S b/arch/x86/crypto/aesni-intel_asm.S index ff16756a51c1..8fe2a4966b7a 100644 --- a/arch/x86/crypto/aesni-intel_asm.S +++ b/arch/x86/crypto/aesni-intel_asm.S | |||
@@ -9,6 +9,20 @@ | |||
9 | * Vinodh Gopal <vinodh.gopal@intel.com> | 9 | * Vinodh Gopal <vinodh.gopal@intel.com> |
10 | * Kahraman Akdemir | 10 | * Kahraman Akdemir |
11 | * | 11 | * |
12 | * Added RFC4106 AES-GCM support for 128-bit keys under the AEAD | ||
13 | * interface for 64-bit kernels. | ||
14 | * Authors: Erdinc Ozturk (erdinc.ozturk@intel.com) | ||
15 | * Aidan O'Mahony (aidan.o.mahony@intel.com) | ||
16 | * Adrian Hoban <adrian.hoban@intel.com> | ||
17 | * James Guilford (james.guilford@intel.com) | ||
18 | * Gabriele Paoloni <gabriele.paoloni@intel.com> | ||
19 | * Tadeusz Struk (tadeusz.struk@intel.com) | ||
20 | * Wajdi Feghali (wajdi.k.feghali@intel.com) | ||
21 | * Copyright (c) 2010, Intel Corporation. | ||
22 | * | ||
23 | * Ported x86_64 version to x86: | ||
24 | * Author: Mathias Krause <minipli@googlemail.com> | ||
25 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | 26 | * This program is free software; you can redistribute it and/or modify |
13 | * it under the terms of the GNU General Public License as published by | 27 | * it under the terms of the GNU General Public License as published by |
14 | * the Free Software Foundation; either version 2 of the License, or | 28 | * the Free Software Foundation; either version 2 of the License, or |
@@ -18,8 +32,62 @@ | |||
18 | #include <linux/linkage.h> | 32 | #include <linux/linkage.h> |
19 | #include <asm/inst.h> | 33 | #include <asm/inst.h> |
20 | 34 | ||
35 | #ifdef __x86_64__ | ||
36 | .data | ||
37 | POLY: .octa 0xC2000000000000000000000000000001 | ||
38 | TWOONE: .octa 0x00000001000000000000000000000001 | ||
39 | |||
40 | # order of these constants should not change. | ||
41 | # more specifically, ALL_F should follow SHIFT_MASK, | ||
42 | # and ZERO should follow ALL_F | ||
43 | |||
44 | SHUF_MASK: .octa 0x000102030405060708090A0B0C0D0E0F | ||
45 | MASK1: .octa 0x0000000000000000ffffffffffffffff | ||
46 | MASK2: .octa 0xffffffffffffffff0000000000000000 | ||
47 | SHIFT_MASK: .octa 0x0f0e0d0c0b0a09080706050403020100 | ||
48 | ALL_F: .octa 0xffffffffffffffffffffffffffffffff | ||
49 | ZERO: .octa 0x00000000000000000000000000000000 | ||
50 | ONE: .octa 0x00000000000000000000000000000001 | ||
51 | F_MIN_MASK: .octa 0xf1f2f3f4f5f6f7f8f9fafbfcfdfeff0 | ||
52 | dec: .octa 0x1 | ||
53 | enc: .octa 0x2 | ||
54 | |||
55 | |||
21 | .text | 56 | .text |
22 | 57 | ||
58 | |||
59 | #define STACK_OFFSET 8*3 | ||
60 | #define HashKey 16*0 // store HashKey <<1 mod poly here | ||
61 | #define HashKey_2 16*1 // store HashKey^2 <<1 mod poly here | ||
62 | #define HashKey_3 16*2 // store HashKey^3 <<1 mod poly here | ||
63 | #define HashKey_4 16*3 // store HashKey^4 <<1 mod poly here | ||
64 | #define HashKey_k 16*4 // store XOR of High 64 bits and Low 64 | ||
65 | // bits of HashKey <<1 mod poly here | ||
66 | //(for Karatsuba purposes) | ||
67 | #define HashKey_2_k 16*5 // store XOR of High 64 bits and Low 64 | ||
68 | // bits of HashKey^2 <<1 mod poly here | ||
69 | // (for Karatsuba purposes) | ||
70 | #define HashKey_3_k 16*6 // store XOR of High 64 bits and Low 64 | ||
71 | // bits of HashKey^3 <<1 mod poly here | ||
72 | // (for Karatsuba purposes) | ||
73 | #define HashKey_4_k 16*7 // store XOR of High 64 bits and Low 64 | ||
74 | // bits of HashKey^4 <<1 mod poly here | ||
75 | // (for Karatsuba purposes) | ||
76 | #define VARIABLE_OFFSET 16*8 | ||
77 | |||
78 | #define arg1 rdi | ||
79 | #define arg2 rsi | ||
80 | #define arg3 rdx | ||
81 | #define arg4 rcx | ||
82 | #define arg5 r8 | ||
83 | #define arg6 r9 | ||
84 | #define arg7 STACK_OFFSET+8(%r14) | ||
85 | #define arg8 STACK_OFFSET+16(%r14) | ||
86 | #define arg9 STACK_OFFSET+24(%r14) | ||
87 | #define arg10 STACK_OFFSET+32(%r14) | ||
88 | #endif | ||
89 | |||
90 | |||
23 | #define STATE1 %xmm0 | 91 | #define STATE1 %xmm0 |
24 | #define STATE2 %xmm4 | 92 | #define STATE2 %xmm4 |
25 | #define STATE3 %xmm5 | 93 | #define STATE3 %xmm5 |
@@ -32,12 +100,16 @@ | |||
32 | #define IN IN1 | 100 | #define IN IN1 |
33 | #define KEY %xmm2 | 101 | #define KEY %xmm2 |
34 | #define IV %xmm3 | 102 | #define IV %xmm3 |
103 | |||
35 | #define BSWAP_MASK %xmm10 | 104 | #define BSWAP_MASK %xmm10 |
36 | #define CTR %xmm11 | 105 | #define CTR %xmm11 |
37 | #define INC %xmm12 | 106 | #define INC %xmm12 |
38 | 107 | ||
108 | #ifdef __x86_64__ | ||
109 | #define AREG %rax | ||
39 | #define KEYP %rdi | 110 | #define KEYP %rdi |
40 | #define OUTP %rsi | 111 | #define OUTP %rsi |
112 | #define UKEYP OUTP | ||
41 | #define INP %rdx | 113 | #define INP %rdx |
42 | #define LEN %rcx | 114 | #define LEN %rcx |
43 | #define IVP %r8 | 115 | #define IVP %r8 |
@@ -46,6 +118,1588 @@ | |||
46 | #define TKEYP T1 | 118 | #define TKEYP T1 |
47 | #define T2 %r11 | 119 | #define T2 %r11 |
48 | #define TCTR_LOW T2 | 120 | #define TCTR_LOW T2 |
121 | #else | ||
122 | #define AREG %eax | ||
123 | #define KEYP %edi | ||
124 | #define OUTP AREG | ||
125 | #define UKEYP OUTP | ||
126 | #define INP %edx | ||
127 | #define LEN %esi | ||
128 | #define IVP %ebp | ||
129 | #define KLEN %ebx | ||
130 | #define T1 %ecx | ||
131 | #define TKEYP T1 | ||
132 | #endif | ||
133 | |||
134 | |||
135 | #ifdef __x86_64__ | ||
136 | /* GHASH_MUL MACRO to implement: Data*HashKey mod (128,127,126,121,0) | ||
137 | * | ||
138 | * | ||
139 | * Input: A and B (128-bits each, bit-reflected) | ||
140 | * Output: C = A*B*x mod poly, (i.e. >>1 ) | ||
141 | * To compute GH = GH*HashKey mod poly, give HK = HashKey<<1 mod poly as input | ||
142 | * GH = GH * HK * x mod poly which is equivalent to GH*HashKey mod poly. | ||
143 | * | ||
144 | */ | ||
145 | .macro GHASH_MUL GH HK TMP1 TMP2 TMP3 TMP4 TMP5 | ||
146 | movdqa \GH, \TMP1 | ||
147 | pshufd $78, \GH, \TMP2 | ||
148 | pshufd $78, \HK, \TMP3 | ||
149 | pxor \GH, \TMP2 # TMP2 = a1+a0 | ||
150 | pxor \HK, \TMP3 # TMP3 = b1+b0 | ||
151 | PCLMULQDQ 0x11, \HK, \TMP1 # TMP1 = a1*b1 | ||
152 | PCLMULQDQ 0x00, \HK, \GH # GH = a0*b0 | ||
153 | PCLMULQDQ 0x00, \TMP3, \TMP2 # TMP2 = (a0+a1)*(b1+b0) | ||
154 | pxor \GH, \TMP2 | ||
155 | pxor \TMP1, \TMP2 # TMP2 = (a0*b0)+(a1*b0) | ||
156 | movdqa \TMP2, \TMP3 | ||
157 | pslldq $8, \TMP3 # left shift TMP3 2 DWs | ||
158 | psrldq $8, \TMP2 # right shift TMP2 2 DWs | ||
159 | pxor \TMP3, \GH | ||
160 | pxor \TMP2, \TMP1 # TMP2:GH holds the result of GH*HK | ||
161 | |||
162 | # first phase of the reduction | ||
163 | |||
164 | movdqa \GH, \TMP2 | ||
165 | movdqa \GH, \TMP3 | ||
166 | movdqa \GH, \TMP4 # copy GH into TMP2,TMP3 and TMP4 | ||
167 | # in in order to perform | ||
168 | # independent shifts | ||
169 | pslld $31, \TMP2 # packed right shift <<31 | ||
170 | pslld $30, \TMP3 # packed right shift <<30 | ||
171 | pslld $25, \TMP4 # packed right shift <<25 | ||
172 | pxor \TMP3, \TMP2 # xor the shifted versions | ||
173 | pxor \TMP4, \TMP2 | ||
174 | movdqa \TMP2, \TMP5 | ||
175 | psrldq $4, \TMP5 # right shift TMP5 1 DW | ||
176 | pslldq $12, \TMP2 # left shift TMP2 3 DWs | ||
177 | pxor \TMP2, \GH | ||
178 | |||
179 | # second phase of the reduction | ||
180 | |||
181 | movdqa \GH,\TMP2 # copy GH into TMP2,TMP3 and TMP4 | ||
182 | # in in order to perform | ||
183 | # independent shifts | ||
184 | movdqa \GH,\TMP3 | ||
185 | movdqa \GH,\TMP4 | ||
186 | psrld $1,\TMP2 # packed left shift >>1 | ||
187 | psrld $2,\TMP3 # packed left shift >>2 | ||
188 | psrld $7,\TMP4 # packed left shift >>7 | ||
189 | pxor \TMP3,\TMP2 # xor the shifted versions | ||
190 | pxor \TMP4,\TMP2 | ||
191 | pxor \TMP5, \TMP2 | ||
192 | pxor \TMP2, \GH | ||
193 | pxor \TMP1, \GH # result is in TMP1 | ||
194 | .endm | ||
195 | |||
196 | /* | ||
197 | * if a = number of total plaintext bytes | ||
198 | * b = floor(a/16) | ||
199 | * num_initial_blocks = b mod 4 | ||
200 | * encrypt the initial num_initial_blocks blocks and apply ghash on | ||
201 | * the ciphertext | ||
202 | * %r10, %r11, %r12, %rax, %xmm5, %xmm6, %xmm7, %xmm8, %xmm9 registers | ||
203 | * are clobbered | ||
204 | * arg1, %arg2, %arg3, %r14 are used as a pointer only, not modified | ||
205 | */ | ||
206 | |||
207 | |||
208 | .macro INITIAL_BLOCKS_DEC num_initial_blocks TMP1 TMP2 TMP3 TMP4 TMP5 XMM0 XMM1 \ | ||
209 | XMM2 XMM3 XMM4 XMMDst TMP6 TMP7 i i_seq operation | ||
210 | mov arg7, %r10 # %r10 = AAD | ||
211 | mov arg8, %r12 # %r12 = aadLen | ||
212 | mov %r12, %r11 | ||
213 | pxor %xmm\i, %xmm\i | ||
214 | _get_AAD_loop\num_initial_blocks\operation: | ||
215 | movd (%r10), \TMP1 | ||
216 | pslldq $12, \TMP1 | ||
217 | psrldq $4, %xmm\i | ||
218 | pxor \TMP1, %xmm\i | ||
219 | add $4, %r10 | ||
220 | sub $4, %r12 | ||
221 | jne _get_AAD_loop\num_initial_blocks\operation | ||
222 | cmp $16, %r11 | ||
223 | je _get_AAD_loop2_done\num_initial_blocks\operation | ||
224 | mov $16, %r12 | ||
225 | _get_AAD_loop2\num_initial_blocks\operation: | ||
226 | psrldq $4, %xmm\i | ||
227 | sub $4, %r12 | ||
228 | cmp %r11, %r12 | ||
229 | jne _get_AAD_loop2\num_initial_blocks\operation | ||
230 | _get_AAD_loop2_done\num_initial_blocks\operation: | ||
231 | movdqa SHUF_MASK(%rip), %xmm14 | ||
232 | PSHUFB_XMM %xmm14, %xmm\i # byte-reflect the AAD data | ||
233 | |||
234 | xor %r11, %r11 # initialise the data pointer offset as zero | ||
235 | |||
236 | # start AES for num_initial_blocks blocks | ||
237 | |||
238 | mov %arg5, %rax # %rax = *Y0 | ||
239 | movdqu (%rax), \XMM0 # XMM0 = Y0 | ||
240 | movdqa SHUF_MASK(%rip), %xmm14 | ||
241 | PSHUFB_XMM %xmm14, \XMM0 | ||
242 | |||
243 | .if (\i == 5) || (\i == 6) || (\i == 7) | ||
244 | .irpc index, \i_seq | ||
245 | paddd ONE(%rip), \XMM0 # INCR Y0 | ||
246 | movdqa \XMM0, %xmm\index | ||
247 | movdqa SHUF_MASK(%rip), %xmm14 | ||
248 | PSHUFB_XMM %xmm14, %xmm\index # perform a 16 byte swap | ||
249 | |||
250 | .endr | ||
251 | .irpc index, \i_seq | ||
252 | pxor 16*0(%arg1), %xmm\index | ||
253 | .endr | ||
254 | .irpc index, \i_seq | ||
255 | movaps 0x10(%rdi), \TMP1 | ||
256 | AESENC \TMP1, %xmm\index # Round 1 | ||
257 | .endr | ||
258 | .irpc index, \i_seq | ||
259 | movaps 0x20(%arg1), \TMP1 | ||
260 | AESENC \TMP1, %xmm\index # Round 2 | ||
261 | .endr | ||
262 | .irpc index, \i_seq | ||
263 | movaps 0x30(%arg1), \TMP1 | ||
264 | AESENC \TMP1, %xmm\index # Round 2 | ||
265 | .endr | ||
266 | .irpc index, \i_seq | ||
267 | movaps 0x40(%arg1), \TMP1 | ||
268 | AESENC \TMP1, %xmm\index # Round 2 | ||
269 | .endr | ||
270 | .irpc index, \i_seq | ||
271 | movaps 0x50(%arg1), \TMP1 | ||
272 | AESENC \TMP1, %xmm\index # Round 2 | ||
273 | .endr | ||
274 | .irpc index, \i_seq | ||
275 | movaps 0x60(%arg1), \TMP1 | ||
276 | AESENC \TMP1, %xmm\index # Round 2 | ||
277 | .endr | ||
278 | .irpc index, \i_seq | ||
279 | movaps 0x70(%arg1), \TMP1 | ||
280 | AESENC \TMP1, %xmm\index # Round 2 | ||
281 | .endr | ||
282 | .irpc index, \i_seq | ||
283 | movaps 0x80(%arg1), \TMP1 | ||
284 | AESENC \TMP1, %xmm\index # Round 2 | ||
285 | .endr | ||
286 | .irpc index, \i_seq | ||
287 | movaps 0x90(%arg1), \TMP1 | ||
288 | AESENC \TMP1, %xmm\index # Round 2 | ||
289 | .endr | ||
290 | .irpc index, \i_seq | ||
291 | movaps 0xa0(%arg1), \TMP1 | ||
292 | AESENCLAST \TMP1, %xmm\index # Round 10 | ||
293 | .endr | ||
294 | .irpc index, \i_seq | ||
295 | movdqu (%arg3 , %r11, 1), \TMP1 | ||
296 | pxor \TMP1, %xmm\index | ||
297 | movdqu %xmm\index, (%arg2 , %r11, 1) | ||
298 | # write back plaintext/ciphertext for num_initial_blocks | ||
299 | add $16, %r11 | ||
300 | |||
301 | movdqa \TMP1, %xmm\index | ||
302 | movdqa SHUF_MASK(%rip), %xmm14 | ||
303 | PSHUFB_XMM %xmm14, %xmm\index | ||
304 | |||
305 | # prepare plaintext/ciphertext for GHASH computation | ||
306 | .endr | ||
307 | .endif | ||
308 | GHASH_MUL %xmm\i, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 | ||
309 | # apply GHASH on num_initial_blocks blocks | ||
310 | |||
311 | .if \i == 5 | ||
312 | pxor %xmm5, %xmm6 | ||
313 | GHASH_MUL %xmm6, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 | ||
314 | pxor %xmm6, %xmm7 | ||
315 | GHASH_MUL %xmm7, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 | ||
316 | pxor %xmm7, %xmm8 | ||
317 | GHASH_MUL %xmm8, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 | ||
318 | .elseif \i == 6 | ||
319 | pxor %xmm6, %xmm7 | ||
320 | GHASH_MUL %xmm7, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 | ||
321 | pxor %xmm7, %xmm8 | ||
322 | GHASH_MUL %xmm8, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 | ||
323 | .elseif \i == 7 | ||
324 | pxor %xmm7, %xmm8 | ||
325 | GHASH_MUL %xmm8, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 | ||
326 | .endif | ||
327 | cmp $64, %r13 | ||
328 | jl _initial_blocks_done\num_initial_blocks\operation | ||
329 | # no need for precomputed values | ||
330 | /* | ||
331 | * | ||
332 | * Precomputations for HashKey parallel with encryption of first 4 blocks. | ||
333 | * Haskey_i_k holds XORed values of the low and high parts of the Haskey_i | ||
334 | */ | ||
335 | paddd ONE(%rip), \XMM0 # INCR Y0 | ||
336 | movdqa \XMM0, \XMM1 | ||
337 | movdqa SHUF_MASK(%rip), %xmm14 | ||
338 | PSHUFB_XMM %xmm14, \XMM1 # perform a 16 byte swap | ||
339 | |||
340 | paddd ONE(%rip), \XMM0 # INCR Y0 | ||
341 | movdqa \XMM0, \XMM2 | ||
342 | movdqa SHUF_MASK(%rip), %xmm14 | ||
343 | PSHUFB_XMM %xmm14, \XMM2 # perform a 16 byte swap | ||
344 | |||
345 | paddd ONE(%rip), \XMM0 # INCR Y0 | ||
346 | movdqa \XMM0, \XMM3 | ||
347 | movdqa SHUF_MASK(%rip), %xmm14 | ||
348 | PSHUFB_XMM %xmm14, \XMM3 # perform a 16 byte swap | ||
349 | |||
350 | paddd ONE(%rip), \XMM0 # INCR Y0 | ||
351 | movdqa \XMM0, \XMM4 | ||
352 | movdqa SHUF_MASK(%rip), %xmm14 | ||
353 | PSHUFB_XMM %xmm14, \XMM4 # perform a 16 byte swap | ||
354 | |||
355 | pxor 16*0(%arg1), \XMM1 | ||
356 | pxor 16*0(%arg1), \XMM2 | ||
357 | pxor 16*0(%arg1), \XMM3 | ||
358 | pxor 16*0(%arg1), \XMM4 | ||
359 | movdqa \TMP3, \TMP5 | ||
360 | pshufd $78, \TMP3, \TMP1 | ||
361 | pxor \TMP3, \TMP1 | ||
362 | movdqa \TMP1, HashKey_k(%rsp) | ||
363 | GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7 | ||
364 | # TMP5 = HashKey^2<<1 (mod poly) | ||
365 | movdqa \TMP5, HashKey_2(%rsp) | ||
366 | # HashKey_2 = HashKey^2<<1 (mod poly) | ||
367 | pshufd $78, \TMP5, \TMP1 | ||
368 | pxor \TMP5, \TMP1 | ||
369 | movdqa \TMP1, HashKey_2_k(%rsp) | ||
370 | .irpc index, 1234 # do 4 rounds | ||
371 | movaps 0x10*\index(%arg1), \TMP1 | ||
372 | AESENC \TMP1, \XMM1 | ||
373 | AESENC \TMP1, \XMM2 | ||
374 | AESENC \TMP1, \XMM3 | ||
375 | AESENC \TMP1, \XMM4 | ||
376 | .endr | ||
377 | GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7 | ||
378 | # TMP5 = HashKey^3<<1 (mod poly) | ||
379 | movdqa \TMP5, HashKey_3(%rsp) | ||
380 | pshufd $78, \TMP5, \TMP1 | ||
381 | pxor \TMP5, \TMP1 | ||
382 | movdqa \TMP1, HashKey_3_k(%rsp) | ||
383 | .irpc index, 56789 # do next 5 rounds | ||
384 | movaps 0x10*\index(%arg1), \TMP1 | ||
385 | AESENC \TMP1, \XMM1 | ||
386 | AESENC \TMP1, \XMM2 | ||
387 | AESENC \TMP1, \XMM3 | ||
388 | AESENC \TMP1, \XMM4 | ||
389 | .endr | ||
390 | GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7 | ||
391 | # TMP5 = HashKey^3<<1 (mod poly) | ||
392 | movdqa \TMP5, HashKey_4(%rsp) | ||
393 | pshufd $78, \TMP5, \TMP1 | ||
394 | pxor \TMP5, \TMP1 | ||
395 | movdqa \TMP1, HashKey_4_k(%rsp) | ||
396 | movaps 0xa0(%arg1), \TMP2 | ||
397 | AESENCLAST \TMP2, \XMM1 | ||
398 | AESENCLAST \TMP2, \XMM2 | ||
399 | AESENCLAST \TMP2, \XMM3 | ||
400 | AESENCLAST \TMP2, \XMM4 | ||
401 | movdqu 16*0(%arg3 , %r11 , 1), \TMP1 | ||
402 | pxor \TMP1, \XMM1 | ||
403 | movdqu \XMM1, 16*0(%arg2 , %r11 , 1) | ||
404 | movdqa \TMP1, \XMM1 | ||
405 | movdqu 16*1(%arg3 , %r11 , 1), \TMP1 | ||
406 | pxor \TMP1, \XMM2 | ||
407 | movdqu \XMM2, 16*1(%arg2 , %r11 , 1) | ||
408 | movdqa \TMP1, \XMM2 | ||
409 | movdqu 16*2(%arg3 , %r11 , 1), \TMP1 | ||
410 | pxor \TMP1, \XMM3 | ||
411 | movdqu \XMM3, 16*2(%arg2 , %r11 , 1) | ||
412 | movdqa \TMP1, \XMM3 | ||
413 | movdqu 16*3(%arg3 , %r11 , 1), \TMP1 | ||
414 | pxor \TMP1, \XMM4 | ||
415 | movdqu \XMM4, 16*3(%arg2 , %r11 , 1) | ||
416 | movdqa \TMP1, \XMM4 | ||
417 | add $64, %r11 | ||
418 | movdqa SHUF_MASK(%rip), %xmm14 | ||
419 | PSHUFB_XMM %xmm14, \XMM1 # perform a 16 byte swap | ||
420 | pxor \XMMDst, \XMM1 | ||
421 | # combine GHASHed value with the corresponding ciphertext | ||
422 | movdqa SHUF_MASK(%rip), %xmm14 | ||
423 | PSHUFB_XMM %xmm14, \XMM2 # perform a 16 byte swap | ||
424 | movdqa SHUF_MASK(%rip), %xmm14 | ||
425 | PSHUFB_XMM %xmm14, \XMM3 # perform a 16 byte swap | ||
426 | movdqa SHUF_MASK(%rip), %xmm14 | ||
427 | PSHUFB_XMM %xmm14, \XMM4 # perform a 16 byte swap | ||
428 | |||
429 | _initial_blocks_done\num_initial_blocks\operation: | ||
430 | |||
431 | .endm | ||
432 | |||
433 | |||
434 | /* | ||
435 | * if a = number of total plaintext bytes | ||
436 | * b = floor(a/16) | ||
437 | * num_initial_blocks = b mod 4 | ||
438 | * encrypt the initial num_initial_blocks blocks and apply ghash on | ||
439 | * the ciphertext | ||
440 | * %r10, %r11, %r12, %rax, %xmm5, %xmm6, %xmm7, %xmm8, %xmm9 registers | ||
441 | * are clobbered | ||
442 | * arg1, %arg2, %arg3, %r14 are used as a pointer only, not modified | ||
443 | */ | ||
444 | |||
445 | |||
446 | .macro INITIAL_BLOCKS_ENC num_initial_blocks TMP1 TMP2 TMP3 TMP4 TMP5 XMM0 XMM1 \ | ||
447 | XMM2 XMM3 XMM4 XMMDst TMP6 TMP7 i i_seq operation | ||
448 | mov arg7, %r10 # %r10 = AAD | ||
449 | mov arg8, %r12 # %r12 = aadLen | ||
450 | mov %r12, %r11 | ||
451 | pxor %xmm\i, %xmm\i | ||
452 | _get_AAD_loop\num_initial_blocks\operation: | ||
453 | movd (%r10), \TMP1 | ||
454 | pslldq $12, \TMP1 | ||
455 | psrldq $4, %xmm\i | ||
456 | pxor \TMP1, %xmm\i | ||
457 | add $4, %r10 | ||
458 | sub $4, %r12 | ||
459 | jne _get_AAD_loop\num_initial_blocks\operation | ||
460 | cmp $16, %r11 | ||
461 | je _get_AAD_loop2_done\num_initial_blocks\operation | ||
462 | mov $16, %r12 | ||
463 | _get_AAD_loop2\num_initial_blocks\operation: | ||
464 | psrldq $4, %xmm\i | ||
465 | sub $4, %r12 | ||
466 | cmp %r11, %r12 | ||
467 | jne _get_AAD_loop2\num_initial_blocks\operation | ||
468 | _get_AAD_loop2_done\num_initial_blocks\operation: | ||
469 | movdqa SHUF_MASK(%rip), %xmm14 | ||
470 | PSHUFB_XMM %xmm14, %xmm\i # byte-reflect the AAD data | ||
471 | |||
472 | xor %r11, %r11 # initialise the data pointer offset as zero | ||
473 | |||
474 | # start AES for num_initial_blocks blocks | ||
475 | |||
476 | mov %arg5, %rax # %rax = *Y0 | ||
477 | movdqu (%rax), \XMM0 # XMM0 = Y0 | ||
478 | movdqa SHUF_MASK(%rip), %xmm14 | ||
479 | PSHUFB_XMM %xmm14, \XMM0 | ||
480 | |||
481 | .if (\i == 5) || (\i == 6) || (\i == 7) | ||
482 | .irpc index, \i_seq | ||
483 | paddd ONE(%rip), \XMM0 # INCR Y0 | ||
484 | movdqa \XMM0, %xmm\index | ||
485 | movdqa SHUF_MASK(%rip), %xmm14 | ||
486 | PSHUFB_XMM %xmm14, %xmm\index # perform a 16 byte swap | ||
487 | |||
488 | .endr | ||
489 | .irpc index, \i_seq | ||
490 | pxor 16*0(%arg1), %xmm\index | ||
491 | .endr | ||
492 | .irpc index, \i_seq | ||
493 | movaps 0x10(%rdi), \TMP1 | ||
494 | AESENC \TMP1, %xmm\index # Round 1 | ||
495 | .endr | ||
496 | .irpc index, \i_seq | ||
497 | movaps 0x20(%arg1), \TMP1 | ||
498 | AESENC \TMP1, %xmm\index # Round 2 | ||
499 | .endr | ||
500 | .irpc index, \i_seq | ||
501 | movaps 0x30(%arg1), \TMP1 | ||
502 | AESENC \TMP1, %xmm\index # Round 2 | ||
503 | .endr | ||
504 | .irpc index, \i_seq | ||
505 | movaps 0x40(%arg1), \TMP1 | ||
506 | AESENC \TMP1, %xmm\index # Round 2 | ||
507 | .endr | ||
508 | .irpc index, \i_seq | ||
509 | movaps 0x50(%arg1), \TMP1 | ||
510 | AESENC \TMP1, %xmm\index # Round 2 | ||
511 | .endr | ||
512 | .irpc index, \i_seq | ||
513 | movaps 0x60(%arg1), \TMP1 | ||
514 | AESENC \TMP1, %xmm\index # Round 2 | ||
515 | .endr | ||
516 | .irpc index, \i_seq | ||
517 | movaps 0x70(%arg1), \TMP1 | ||
518 | AESENC \TMP1, %xmm\index # Round 2 | ||
519 | .endr | ||
520 | .irpc index, \i_seq | ||
521 | movaps 0x80(%arg1), \TMP1 | ||
522 | AESENC \TMP1, %xmm\index # Round 2 | ||
523 | .endr | ||
524 | .irpc index, \i_seq | ||
525 | movaps 0x90(%arg1), \TMP1 | ||
526 | AESENC \TMP1, %xmm\index # Round 2 | ||
527 | .endr | ||
528 | .irpc index, \i_seq | ||
529 | movaps 0xa0(%arg1), \TMP1 | ||
530 | AESENCLAST \TMP1, %xmm\index # Round 10 | ||
531 | .endr | ||
532 | .irpc index, \i_seq | ||
533 | movdqu (%arg3 , %r11, 1), \TMP1 | ||
534 | pxor \TMP1, %xmm\index | ||
535 | movdqu %xmm\index, (%arg2 , %r11, 1) | ||
536 | # write back plaintext/ciphertext for num_initial_blocks | ||
537 | add $16, %r11 | ||
538 | |||
539 | movdqa SHUF_MASK(%rip), %xmm14 | ||
540 | PSHUFB_XMM %xmm14, %xmm\index | ||
541 | |||
542 | # prepare plaintext/ciphertext for GHASH computation | ||
543 | .endr | ||
544 | .endif | ||
545 | GHASH_MUL %xmm\i, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 | ||
546 | # apply GHASH on num_initial_blocks blocks | ||
547 | |||
548 | .if \i == 5 | ||
549 | pxor %xmm5, %xmm6 | ||
550 | GHASH_MUL %xmm6, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 | ||
551 | pxor %xmm6, %xmm7 | ||
552 | GHASH_MUL %xmm7, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 | ||
553 | pxor %xmm7, %xmm8 | ||
554 | GHASH_MUL %xmm8, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 | ||
555 | .elseif \i == 6 | ||
556 | pxor %xmm6, %xmm7 | ||
557 | GHASH_MUL %xmm7, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 | ||
558 | pxor %xmm7, %xmm8 | ||
559 | GHASH_MUL %xmm8, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 | ||
560 | .elseif \i == 7 | ||
561 | pxor %xmm7, %xmm8 | ||
562 | GHASH_MUL %xmm8, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 | ||
563 | .endif | ||
564 | cmp $64, %r13 | ||
565 | jl _initial_blocks_done\num_initial_blocks\operation | ||
566 | # no need for precomputed values | ||
567 | /* | ||
568 | * | ||
569 | * Precomputations for HashKey parallel with encryption of first 4 blocks. | ||
570 | * Haskey_i_k holds XORed values of the low and high parts of the Haskey_i | ||
571 | */ | ||
572 | paddd ONE(%rip), \XMM0 # INCR Y0 | ||
573 | movdqa \XMM0, \XMM1 | ||
574 | movdqa SHUF_MASK(%rip), %xmm14 | ||
575 | PSHUFB_XMM %xmm14, \XMM1 # perform a 16 byte swap | ||
576 | |||
577 | paddd ONE(%rip), \XMM0 # INCR Y0 | ||
578 | movdqa \XMM0, \XMM2 | ||
579 | movdqa SHUF_MASK(%rip), %xmm14 | ||
580 | PSHUFB_XMM %xmm14, \XMM2 # perform a 16 byte swap | ||
581 | |||
582 | paddd ONE(%rip), \XMM0 # INCR Y0 | ||
583 | movdqa \XMM0, \XMM3 | ||
584 | movdqa SHUF_MASK(%rip), %xmm14 | ||
585 | PSHUFB_XMM %xmm14, \XMM3 # perform a 16 byte swap | ||
586 | |||
587 | paddd ONE(%rip), \XMM0 # INCR Y0 | ||
588 | movdqa \XMM0, \XMM4 | ||
589 | movdqa SHUF_MASK(%rip), %xmm14 | ||
590 | PSHUFB_XMM %xmm14, \XMM4 # perform a 16 byte swap | ||
591 | |||
592 | pxor 16*0(%arg1), \XMM1 | ||
593 | pxor 16*0(%arg1), \XMM2 | ||
594 | pxor 16*0(%arg1), \XMM3 | ||
595 | pxor 16*0(%arg1), \XMM4 | ||
596 | movdqa \TMP3, \TMP5 | ||
597 | pshufd $78, \TMP3, \TMP1 | ||
598 | pxor \TMP3, \TMP1 | ||
599 | movdqa \TMP1, HashKey_k(%rsp) | ||
600 | GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7 | ||
601 | # TMP5 = HashKey^2<<1 (mod poly) | ||
602 | movdqa \TMP5, HashKey_2(%rsp) | ||
603 | # HashKey_2 = HashKey^2<<1 (mod poly) | ||
604 | pshufd $78, \TMP5, \TMP1 | ||
605 | pxor \TMP5, \TMP1 | ||
606 | movdqa \TMP1, HashKey_2_k(%rsp) | ||
607 | .irpc index, 1234 # do 4 rounds | ||
608 | movaps 0x10*\index(%arg1), \TMP1 | ||
609 | AESENC \TMP1, \XMM1 | ||
610 | AESENC \TMP1, \XMM2 | ||
611 | AESENC \TMP1, \XMM3 | ||
612 | AESENC \TMP1, \XMM4 | ||
613 | .endr | ||
614 | GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7 | ||
615 | # TMP5 = HashKey^3<<1 (mod poly) | ||
616 | movdqa \TMP5, HashKey_3(%rsp) | ||
617 | pshufd $78, \TMP5, \TMP1 | ||
618 | pxor \TMP5, \TMP1 | ||
619 | movdqa \TMP1, HashKey_3_k(%rsp) | ||
620 | .irpc index, 56789 # do next 5 rounds | ||
621 | movaps 0x10*\index(%arg1), \TMP1 | ||
622 | AESENC \TMP1, \XMM1 | ||
623 | AESENC \TMP1, \XMM2 | ||
624 | AESENC \TMP1, \XMM3 | ||
625 | AESENC \TMP1, \XMM4 | ||
626 | .endr | ||
627 | GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7 | ||
628 | # TMP5 = HashKey^3<<1 (mod poly) | ||
629 | movdqa \TMP5, HashKey_4(%rsp) | ||
630 | pshufd $78, \TMP5, \TMP1 | ||
631 | pxor \TMP5, \TMP1 | ||
632 | movdqa \TMP1, HashKey_4_k(%rsp) | ||
633 | movaps 0xa0(%arg1), \TMP2 | ||
634 | AESENCLAST \TMP2, \XMM1 | ||
635 | AESENCLAST \TMP2, \XMM2 | ||
636 | AESENCLAST \TMP2, \XMM3 | ||
637 | AESENCLAST \TMP2, \XMM4 | ||
638 | movdqu 16*0(%arg3 , %r11 , 1), \TMP1 | ||
639 | pxor \TMP1, \XMM1 | ||
640 | movdqu 16*1(%arg3 , %r11 , 1), \TMP1 | ||
641 | pxor \TMP1, \XMM2 | ||
642 | movdqu 16*2(%arg3 , %r11 , 1), \TMP1 | ||
643 | pxor \TMP1, \XMM3 | ||
644 | movdqu 16*3(%arg3 , %r11 , 1), \TMP1 | ||
645 | pxor \TMP1, \XMM4 | ||
646 | movdqu \XMM1, 16*0(%arg2 , %r11 , 1) | ||
647 | movdqu \XMM2, 16*1(%arg2 , %r11 , 1) | ||
648 | movdqu \XMM3, 16*2(%arg2 , %r11 , 1) | ||
649 | movdqu \XMM4, 16*3(%arg2 , %r11 , 1) | ||
650 | |||
651 | add $64, %r11 | ||
652 | movdqa SHUF_MASK(%rip), %xmm14 | ||
653 | PSHUFB_XMM %xmm14, \XMM1 # perform a 16 byte swap | ||
654 | pxor \XMMDst, \XMM1 | ||
655 | # combine GHASHed value with the corresponding ciphertext | ||
656 | movdqa SHUF_MASK(%rip), %xmm14 | ||
657 | PSHUFB_XMM %xmm14, \XMM2 # perform a 16 byte swap | ||
658 | movdqa SHUF_MASK(%rip), %xmm14 | ||
659 | PSHUFB_XMM %xmm14, \XMM3 # perform a 16 byte swap | ||
660 | movdqa SHUF_MASK(%rip), %xmm14 | ||
661 | PSHUFB_XMM %xmm14, \XMM4 # perform a 16 byte swap | ||
662 | |||
663 | _initial_blocks_done\num_initial_blocks\operation: | ||
664 | |||
665 | .endm | ||
666 | |||
667 | /* | ||
668 | * encrypt 4 blocks at a time | ||
669 | * ghash the 4 previously encrypted ciphertext blocks | ||
670 | * arg1, %arg2, %arg3 are used as pointers only, not modified | ||
671 | * %r11 is the data offset value | ||
672 | */ | ||
673 | .macro GHASH_4_ENCRYPT_4_PARALLEL_ENC TMP1 TMP2 TMP3 TMP4 TMP5 \ | ||
674 | TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation | ||
675 | |||
676 | movdqa \XMM1, \XMM5 | ||
677 | movdqa \XMM2, \XMM6 | ||
678 | movdqa \XMM3, \XMM7 | ||
679 | movdqa \XMM4, \XMM8 | ||
680 | |||
681 | movdqa SHUF_MASK(%rip), %xmm15 | ||
682 | # multiply TMP5 * HashKey using karatsuba | ||
683 | |||
684 | movdqa \XMM5, \TMP4 | ||
685 | pshufd $78, \XMM5, \TMP6 | ||
686 | pxor \XMM5, \TMP6 | ||
687 | paddd ONE(%rip), \XMM0 # INCR CNT | ||
688 | movdqa HashKey_4(%rsp), \TMP5 | ||
689 | PCLMULQDQ 0x11, \TMP5, \TMP4 # TMP4 = a1*b1 | ||
690 | movdqa \XMM0, \XMM1 | ||
691 | paddd ONE(%rip), \XMM0 # INCR CNT | ||
692 | movdqa \XMM0, \XMM2 | ||
693 | paddd ONE(%rip), \XMM0 # INCR CNT | ||
694 | movdqa \XMM0, \XMM3 | ||
695 | paddd ONE(%rip), \XMM0 # INCR CNT | ||
696 | movdqa \XMM0, \XMM4 | ||
697 | PSHUFB_XMM %xmm15, \XMM1 # perform a 16 byte swap | ||
698 | PCLMULQDQ 0x00, \TMP5, \XMM5 # XMM5 = a0*b0 | ||
699 | PSHUFB_XMM %xmm15, \XMM2 # perform a 16 byte swap | ||
700 | PSHUFB_XMM %xmm15, \XMM3 # perform a 16 byte swap | ||
701 | PSHUFB_XMM %xmm15, \XMM4 # perform a 16 byte swap | ||
702 | |||
703 | pxor (%arg1), \XMM1 | ||
704 | pxor (%arg1), \XMM2 | ||
705 | pxor (%arg1), \XMM3 | ||
706 | pxor (%arg1), \XMM4 | ||
707 | movdqa HashKey_4_k(%rsp), \TMP5 | ||
708 | PCLMULQDQ 0x00, \TMP5, \TMP6 # TMP6 = (a1+a0)*(b1+b0) | ||
709 | movaps 0x10(%arg1), \TMP1 | ||
710 | AESENC \TMP1, \XMM1 # Round 1 | ||
711 | AESENC \TMP1, \XMM2 | ||
712 | AESENC \TMP1, \XMM3 | ||
713 | AESENC \TMP1, \XMM4 | ||
714 | movaps 0x20(%arg1), \TMP1 | ||
715 | AESENC \TMP1, \XMM1 # Round 2 | ||
716 | AESENC \TMP1, \XMM2 | ||
717 | AESENC \TMP1, \XMM3 | ||
718 | AESENC \TMP1, \XMM4 | ||
719 | movdqa \XMM6, \TMP1 | ||
720 | pshufd $78, \XMM6, \TMP2 | ||
721 | pxor \XMM6, \TMP2 | ||
722 | movdqa HashKey_3(%rsp), \TMP5 | ||
723 | PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1 * b1 | ||
724 | movaps 0x30(%arg1), \TMP3 | ||
725 | AESENC \TMP3, \XMM1 # Round 3 | ||
726 | AESENC \TMP3, \XMM2 | ||
727 | AESENC \TMP3, \XMM3 | ||
728 | AESENC \TMP3, \XMM4 | ||
729 | PCLMULQDQ 0x00, \TMP5, \XMM6 # XMM6 = a0*b0 | ||
730 | movaps 0x40(%arg1), \TMP3 | ||
731 | AESENC \TMP3, \XMM1 # Round 4 | ||
732 | AESENC \TMP3, \XMM2 | ||
733 | AESENC \TMP3, \XMM3 | ||
734 | AESENC \TMP3, \XMM4 | ||
735 | movdqa HashKey_3_k(%rsp), \TMP5 | ||
736 | PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0) | ||
737 | movaps 0x50(%arg1), \TMP3 | ||
738 | AESENC \TMP3, \XMM1 # Round 5 | ||
739 | AESENC \TMP3, \XMM2 | ||
740 | AESENC \TMP3, \XMM3 | ||
741 | AESENC \TMP3, \XMM4 | ||
742 | pxor \TMP1, \TMP4 | ||
743 | # accumulate the results in TMP4:XMM5, TMP6 holds the middle part | ||
744 | pxor \XMM6, \XMM5 | ||
745 | pxor \TMP2, \TMP6 | ||
746 | movdqa \XMM7, \TMP1 | ||
747 | pshufd $78, \XMM7, \TMP2 | ||
748 | pxor \XMM7, \TMP2 | ||
749 | movdqa HashKey_2(%rsp ), \TMP5 | ||
750 | |||
751 | # Multiply TMP5 * HashKey using karatsuba | ||
752 | |||
753 | PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1 | ||
754 | movaps 0x60(%arg1), \TMP3 | ||
755 | AESENC \TMP3, \XMM1 # Round 6 | ||
756 | AESENC \TMP3, \XMM2 | ||
757 | AESENC \TMP3, \XMM3 | ||
758 | AESENC \TMP3, \XMM4 | ||
759 | PCLMULQDQ 0x00, \TMP5, \XMM7 # XMM7 = a0*b0 | ||
760 | movaps 0x70(%arg1), \TMP3 | ||
761 | AESENC \TMP3, \XMM1 # Round 7 | ||
762 | AESENC \TMP3, \XMM2 | ||
763 | AESENC \TMP3, \XMM3 | ||
764 | AESENC \TMP3, \XMM4 | ||
765 | movdqa HashKey_2_k(%rsp), \TMP5 | ||
766 | PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0) | ||
767 | movaps 0x80(%arg1), \TMP3 | ||
768 | AESENC \TMP3, \XMM1 # Round 8 | ||
769 | AESENC \TMP3, \XMM2 | ||
770 | AESENC \TMP3, \XMM3 | ||
771 | AESENC \TMP3, \XMM4 | ||
772 | pxor \TMP1, \TMP4 | ||
773 | # accumulate the results in TMP4:XMM5, TMP6 holds the middle part | ||
774 | pxor \XMM7, \XMM5 | ||
775 | pxor \TMP2, \TMP6 | ||
776 | |||
777 | # Multiply XMM8 * HashKey | ||
778 | # XMM8 and TMP5 hold the values for the two operands | ||
779 | |||
780 | movdqa \XMM8, \TMP1 | ||
781 | pshufd $78, \XMM8, \TMP2 | ||
782 | pxor \XMM8, \TMP2 | ||
783 | movdqa HashKey(%rsp), \TMP5 | ||
784 | PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1 | ||
785 | movaps 0x90(%arg1), \TMP3 | ||
786 | AESENC \TMP3, \XMM1 # Round 9 | ||
787 | AESENC \TMP3, \XMM2 | ||
788 | AESENC \TMP3, \XMM3 | ||
789 | AESENC \TMP3, \XMM4 | ||
790 | PCLMULQDQ 0x00, \TMP5, \XMM8 # XMM8 = a0*b0 | ||
791 | movaps 0xa0(%arg1), \TMP3 | ||
792 | AESENCLAST \TMP3, \XMM1 # Round 10 | ||
793 | AESENCLAST \TMP3, \XMM2 | ||
794 | AESENCLAST \TMP3, \XMM3 | ||
795 | AESENCLAST \TMP3, \XMM4 | ||
796 | movdqa HashKey_k(%rsp), \TMP5 | ||
797 | PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0) | ||
798 | movdqu (%arg3,%r11,1), \TMP3 | ||
799 | pxor \TMP3, \XMM1 # Ciphertext/Plaintext XOR EK | ||
800 | movdqu 16(%arg3,%r11,1), \TMP3 | ||
801 | pxor \TMP3, \XMM2 # Ciphertext/Plaintext XOR EK | ||
802 | movdqu 32(%arg3,%r11,1), \TMP3 | ||
803 | pxor \TMP3, \XMM3 # Ciphertext/Plaintext XOR EK | ||
804 | movdqu 48(%arg3,%r11,1), \TMP3 | ||
805 | pxor \TMP3, \XMM4 # Ciphertext/Plaintext XOR EK | ||
806 | movdqu \XMM1, (%arg2,%r11,1) # Write to the ciphertext buffer | ||
807 | movdqu \XMM2, 16(%arg2,%r11,1) # Write to the ciphertext buffer | ||
808 | movdqu \XMM3, 32(%arg2,%r11,1) # Write to the ciphertext buffer | ||
809 | movdqu \XMM4, 48(%arg2,%r11,1) # Write to the ciphertext buffer | ||
810 | PSHUFB_XMM %xmm15, \XMM1 # perform a 16 byte swap | ||
811 | PSHUFB_XMM %xmm15, \XMM2 # perform a 16 byte swap | ||
812 | PSHUFB_XMM %xmm15, \XMM3 # perform a 16 byte swap | ||
813 | PSHUFB_XMM %xmm15, \XMM4 # perform a 16 byte swap | ||
814 | |||
815 | pxor \TMP4, \TMP1 | ||
816 | pxor \XMM8, \XMM5 | ||
817 | pxor \TMP6, \TMP2 | ||
818 | pxor \TMP1, \TMP2 | ||
819 | pxor \XMM5, \TMP2 | ||
820 | movdqa \TMP2, \TMP3 | ||
821 | pslldq $8, \TMP3 # left shift TMP3 2 DWs | ||
822 | psrldq $8, \TMP2 # right shift TMP2 2 DWs | ||
823 | pxor \TMP3, \XMM5 | ||
824 | pxor \TMP2, \TMP1 # accumulate the results in TMP1:XMM5 | ||
825 | |||
826 | # first phase of reduction | ||
827 | |||
828 | movdqa \XMM5, \TMP2 | ||
829 | movdqa \XMM5, \TMP3 | ||
830 | movdqa \XMM5, \TMP4 | ||
831 | # move XMM5 into TMP2, TMP3, TMP4 in order to perform shifts independently | ||
832 | pslld $31, \TMP2 # packed right shift << 31 | ||
833 | pslld $30, \TMP3 # packed right shift << 30 | ||
834 | pslld $25, \TMP4 # packed right shift << 25 | ||
835 | pxor \TMP3, \TMP2 # xor the shifted versions | ||
836 | pxor \TMP4, \TMP2 | ||
837 | movdqa \TMP2, \TMP5 | ||
838 | psrldq $4, \TMP5 # right shift T5 1 DW | ||
839 | pslldq $12, \TMP2 # left shift T2 3 DWs | ||
840 | pxor \TMP2, \XMM5 | ||
841 | |||
842 | # second phase of reduction | ||
843 | |||
844 | movdqa \XMM5,\TMP2 # make 3 copies of XMM5 into TMP2, TMP3, TMP4 | ||
845 | movdqa \XMM5,\TMP3 | ||
846 | movdqa \XMM5,\TMP4 | ||
847 | psrld $1, \TMP2 # packed left shift >>1 | ||
848 | psrld $2, \TMP3 # packed left shift >>2 | ||
849 | psrld $7, \TMP4 # packed left shift >>7 | ||
850 | pxor \TMP3,\TMP2 # xor the shifted versions | ||
851 | pxor \TMP4,\TMP2 | ||
852 | pxor \TMP5, \TMP2 | ||
853 | pxor \TMP2, \XMM5 | ||
854 | pxor \TMP1, \XMM5 # result is in TMP1 | ||
855 | |||
856 | pxor \XMM5, \XMM1 | ||
857 | .endm | ||
858 | |||
859 | /* | ||
860 | * decrypt 4 blocks at a time | ||
861 | * ghash the 4 previously decrypted ciphertext blocks | ||
862 | * arg1, %arg2, %arg3 are used as pointers only, not modified | ||
863 | * %r11 is the data offset value | ||
864 | */ | ||
865 | .macro GHASH_4_ENCRYPT_4_PARALLEL_DEC TMP1 TMP2 TMP3 TMP4 TMP5 \ | ||
866 | TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation | ||
867 | |||
868 | movdqa \XMM1, \XMM5 | ||
869 | movdqa \XMM2, \XMM6 | ||
870 | movdqa \XMM3, \XMM7 | ||
871 | movdqa \XMM4, \XMM8 | ||
872 | |||
873 | movdqa SHUF_MASK(%rip), %xmm15 | ||
874 | # multiply TMP5 * HashKey using karatsuba | ||
875 | |||
876 | movdqa \XMM5, \TMP4 | ||
877 | pshufd $78, \XMM5, \TMP6 | ||
878 | pxor \XMM5, \TMP6 | ||
879 | paddd ONE(%rip), \XMM0 # INCR CNT | ||
880 | movdqa HashKey_4(%rsp), \TMP5 | ||
881 | PCLMULQDQ 0x11, \TMP5, \TMP4 # TMP4 = a1*b1 | ||
882 | movdqa \XMM0, \XMM1 | ||
883 | paddd ONE(%rip), \XMM0 # INCR CNT | ||
884 | movdqa \XMM0, \XMM2 | ||
885 | paddd ONE(%rip), \XMM0 # INCR CNT | ||
886 | movdqa \XMM0, \XMM3 | ||
887 | paddd ONE(%rip), \XMM0 # INCR CNT | ||
888 | movdqa \XMM0, \XMM4 | ||
889 | PSHUFB_XMM %xmm15, \XMM1 # perform a 16 byte swap | ||
890 | PCLMULQDQ 0x00, \TMP5, \XMM5 # XMM5 = a0*b0 | ||
891 | PSHUFB_XMM %xmm15, \XMM2 # perform a 16 byte swap | ||
892 | PSHUFB_XMM %xmm15, \XMM3 # perform a 16 byte swap | ||
893 | PSHUFB_XMM %xmm15, \XMM4 # perform a 16 byte swap | ||
894 | |||
895 | pxor (%arg1), \XMM1 | ||
896 | pxor (%arg1), \XMM2 | ||
897 | pxor (%arg1), \XMM3 | ||
898 | pxor (%arg1), \XMM4 | ||
899 | movdqa HashKey_4_k(%rsp), \TMP5 | ||
900 | PCLMULQDQ 0x00, \TMP5, \TMP6 # TMP6 = (a1+a0)*(b1+b0) | ||
901 | movaps 0x10(%arg1), \TMP1 | ||
902 | AESENC \TMP1, \XMM1 # Round 1 | ||
903 | AESENC \TMP1, \XMM2 | ||
904 | AESENC \TMP1, \XMM3 | ||
905 | AESENC \TMP1, \XMM4 | ||
906 | movaps 0x20(%arg1), \TMP1 | ||
907 | AESENC \TMP1, \XMM1 # Round 2 | ||
908 | AESENC \TMP1, \XMM2 | ||
909 | AESENC \TMP1, \XMM3 | ||
910 | AESENC \TMP1, \XMM4 | ||
911 | movdqa \XMM6, \TMP1 | ||
912 | pshufd $78, \XMM6, \TMP2 | ||
913 | pxor \XMM6, \TMP2 | ||
914 | movdqa HashKey_3(%rsp), \TMP5 | ||
915 | PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1 * b1 | ||
916 | movaps 0x30(%arg1), \TMP3 | ||
917 | AESENC \TMP3, \XMM1 # Round 3 | ||
918 | AESENC \TMP3, \XMM2 | ||
919 | AESENC \TMP3, \XMM3 | ||
920 | AESENC \TMP3, \XMM4 | ||
921 | PCLMULQDQ 0x00, \TMP5, \XMM6 # XMM6 = a0*b0 | ||
922 | movaps 0x40(%arg1), \TMP3 | ||
923 | AESENC \TMP3, \XMM1 # Round 4 | ||
924 | AESENC \TMP3, \XMM2 | ||
925 | AESENC \TMP3, \XMM3 | ||
926 | AESENC \TMP3, \XMM4 | ||
927 | movdqa HashKey_3_k(%rsp), \TMP5 | ||
928 | PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0) | ||
929 | movaps 0x50(%arg1), \TMP3 | ||
930 | AESENC \TMP3, \XMM1 # Round 5 | ||
931 | AESENC \TMP3, \XMM2 | ||
932 | AESENC \TMP3, \XMM3 | ||
933 | AESENC \TMP3, \XMM4 | ||
934 | pxor \TMP1, \TMP4 | ||
935 | # accumulate the results in TMP4:XMM5, TMP6 holds the middle part | ||
936 | pxor \XMM6, \XMM5 | ||
937 | pxor \TMP2, \TMP6 | ||
938 | movdqa \XMM7, \TMP1 | ||
939 | pshufd $78, \XMM7, \TMP2 | ||
940 | pxor \XMM7, \TMP2 | ||
941 | movdqa HashKey_2(%rsp ), \TMP5 | ||
942 | |||
943 | # Multiply TMP5 * HashKey using karatsuba | ||
944 | |||
945 | PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1 | ||
946 | movaps 0x60(%arg1), \TMP3 | ||
947 | AESENC \TMP3, \XMM1 # Round 6 | ||
948 | AESENC \TMP3, \XMM2 | ||
949 | AESENC \TMP3, \XMM3 | ||
950 | AESENC \TMP3, \XMM4 | ||
951 | PCLMULQDQ 0x00, \TMP5, \XMM7 # XMM7 = a0*b0 | ||
952 | movaps 0x70(%arg1), \TMP3 | ||
953 | AESENC \TMP3, \XMM1 # Round 7 | ||
954 | AESENC \TMP3, \XMM2 | ||
955 | AESENC \TMP3, \XMM3 | ||
956 | AESENC \TMP3, \XMM4 | ||
957 | movdqa HashKey_2_k(%rsp), \TMP5 | ||
958 | PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0) | ||
959 | movaps 0x80(%arg1), \TMP3 | ||
960 | AESENC \TMP3, \XMM1 # Round 8 | ||
961 | AESENC \TMP3, \XMM2 | ||
962 | AESENC \TMP3, \XMM3 | ||
963 | AESENC \TMP3, \XMM4 | ||
964 | pxor \TMP1, \TMP4 | ||
965 | # accumulate the results in TMP4:XMM5, TMP6 holds the middle part | ||
966 | pxor \XMM7, \XMM5 | ||
967 | pxor \TMP2, \TMP6 | ||
968 | |||
969 | # Multiply XMM8 * HashKey | ||
970 | # XMM8 and TMP5 hold the values for the two operands | ||
971 | |||
972 | movdqa \XMM8, \TMP1 | ||
973 | pshufd $78, \XMM8, \TMP2 | ||
974 | pxor \XMM8, \TMP2 | ||
975 | movdqa HashKey(%rsp), \TMP5 | ||
976 | PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1 | ||
977 | movaps 0x90(%arg1), \TMP3 | ||
978 | AESENC \TMP3, \XMM1 # Round 9 | ||
979 | AESENC \TMP3, \XMM2 | ||
980 | AESENC \TMP3, \XMM3 | ||
981 | AESENC \TMP3, \XMM4 | ||
982 | PCLMULQDQ 0x00, \TMP5, \XMM8 # XMM8 = a0*b0 | ||
983 | movaps 0xa0(%arg1), \TMP3 | ||
984 | AESENCLAST \TMP3, \XMM1 # Round 10 | ||
985 | AESENCLAST \TMP3, \XMM2 | ||
986 | AESENCLAST \TMP3, \XMM3 | ||
987 | AESENCLAST \TMP3, \XMM4 | ||
988 | movdqa HashKey_k(%rsp), \TMP5 | ||
989 | PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0) | ||
990 | movdqu (%arg3,%r11,1), \TMP3 | ||
991 | pxor \TMP3, \XMM1 # Ciphertext/Plaintext XOR EK | ||
992 | movdqu \XMM1, (%arg2,%r11,1) # Write to plaintext buffer | ||
993 | movdqa \TMP3, \XMM1 | ||
994 | movdqu 16(%arg3,%r11,1), \TMP3 | ||
995 | pxor \TMP3, \XMM2 # Ciphertext/Plaintext XOR EK | ||
996 | movdqu \XMM2, 16(%arg2,%r11,1) # Write to plaintext buffer | ||
997 | movdqa \TMP3, \XMM2 | ||
998 | movdqu 32(%arg3,%r11,1), \TMP3 | ||
999 | pxor \TMP3, \XMM3 # Ciphertext/Plaintext XOR EK | ||
1000 | movdqu \XMM3, 32(%arg2,%r11,1) # Write to plaintext buffer | ||
1001 | movdqa \TMP3, \XMM3 | ||
1002 | movdqu 48(%arg3,%r11,1), \TMP3 | ||
1003 | pxor \TMP3, \XMM4 # Ciphertext/Plaintext XOR EK | ||
1004 | movdqu \XMM4, 48(%arg2,%r11,1) # Write to plaintext buffer | ||
1005 | movdqa \TMP3, \XMM4 | ||
1006 | PSHUFB_XMM %xmm15, \XMM1 # perform a 16 byte swap | ||
1007 | PSHUFB_XMM %xmm15, \XMM2 # perform a 16 byte swap | ||
1008 | PSHUFB_XMM %xmm15, \XMM3 # perform a 16 byte swap | ||
1009 | PSHUFB_XMM %xmm15, \XMM4 # perform a 16 byte swap | ||
1010 | |||
1011 | pxor \TMP4, \TMP1 | ||
1012 | pxor \XMM8, \XMM5 | ||
1013 | pxor \TMP6, \TMP2 | ||
1014 | pxor \TMP1, \TMP2 | ||
1015 | pxor \XMM5, \TMP2 | ||
1016 | movdqa \TMP2, \TMP3 | ||
1017 | pslldq $8, \TMP3 # left shift TMP3 2 DWs | ||
1018 | psrldq $8, \TMP2 # right shift TMP2 2 DWs | ||
1019 | pxor \TMP3, \XMM5 | ||
1020 | pxor \TMP2, \TMP1 # accumulate the results in TMP1:XMM5 | ||
1021 | |||
1022 | # first phase of reduction | ||
1023 | |||
1024 | movdqa \XMM5, \TMP2 | ||
1025 | movdqa \XMM5, \TMP3 | ||
1026 | movdqa \XMM5, \TMP4 | ||
1027 | # move XMM5 into TMP2, TMP3, TMP4 in order to perform shifts independently | ||
1028 | pslld $31, \TMP2 # packed right shift << 31 | ||
1029 | pslld $30, \TMP3 # packed right shift << 30 | ||
1030 | pslld $25, \TMP4 # packed right shift << 25 | ||
1031 | pxor \TMP3, \TMP2 # xor the shifted versions | ||
1032 | pxor \TMP4, \TMP2 | ||
1033 | movdqa \TMP2, \TMP5 | ||
1034 | psrldq $4, \TMP5 # right shift T5 1 DW | ||
1035 | pslldq $12, \TMP2 # left shift T2 3 DWs | ||
1036 | pxor \TMP2, \XMM5 | ||
1037 | |||
1038 | # second phase of reduction | ||
1039 | |||
1040 | movdqa \XMM5,\TMP2 # make 3 copies of XMM5 into TMP2, TMP3, TMP4 | ||
1041 | movdqa \XMM5,\TMP3 | ||
1042 | movdqa \XMM5,\TMP4 | ||
1043 | psrld $1, \TMP2 # packed left shift >>1 | ||
1044 | psrld $2, \TMP3 # packed left shift >>2 | ||
1045 | psrld $7, \TMP4 # packed left shift >>7 | ||
1046 | pxor \TMP3,\TMP2 # xor the shifted versions | ||
1047 | pxor \TMP4,\TMP2 | ||
1048 | pxor \TMP5, \TMP2 | ||
1049 | pxor \TMP2, \XMM5 | ||
1050 | pxor \TMP1, \XMM5 # result is in TMP1 | ||
1051 | |||
1052 | pxor \XMM5, \XMM1 | ||
1053 | .endm | ||
1054 | |||
1055 | /* GHASH the last 4 ciphertext blocks. */ | ||
1056 | .macro GHASH_LAST_4 TMP1 TMP2 TMP3 TMP4 TMP5 TMP6 \ | ||
1057 | TMP7 XMM1 XMM2 XMM3 XMM4 XMMDst | ||
1058 | |||
1059 | # Multiply TMP6 * HashKey (using Karatsuba) | ||
1060 | |||
1061 | movdqa \XMM1, \TMP6 | ||
1062 | pshufd $78, \XMM1, \TMP2 | ||
1063 | pxor \XMM1, \TMP2 | ||
1064 | movdqa HashKey_4(%rsp), \TMP5 | ||
1065 | PCLMULQDQ 0x11, \TMP5, \TMP6 # TMP6 = a1*b1 | ||
1066 | PCLMULQDQ 0x00, \TMP5, \XMM1 # XMM1 = a0*b0 | ||
1067 | movdqa HashKey_4_k(%rsp), \TMP4 | ||
1068 | PCLMULQDQ 0x00, \TMP4, \TMP2 # TMP2 = (a1+a0)*(b1+b0) | ||
1069 | movdqa \XMM1, \XMMDst | ||
1070 | movdqa \TMP2, \XMM1 # result in TMP6, XMMDst, XMM1 | ||
1071 | |||
1072 | # Multiply TMP1 * HashKey (using Karatsuba) | ||
1073 | |||
1074 | movdqa \XMM2, \TMP1 | ||
1075 | pshufd $78, \XMM2, \TMP2 | ||
1076 | pxor \XMM2, \TMP2 | ||
1077 | movdqa HashKey_3(%rsp), \TMP5 | ||
1078 | PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1 | ||
1079 | PCLMULQDQ 0x00, \TMP5, \XMM2 # XMM2 = a0*b0 | ||
1080 | movdqa HashKey_3_k(%rsp), \TMP4 | ||
1081 | PCLMULQDQ 0x00, \TMP4, \TMP2 # TMP2 = (a1+a0)*(b1+b0) | ||
1082 | pxor \TMP1, \TMP6 | ||
1083 | pxor \XMM2, \XMMDst | ||
1084 | pxor \TMP2, \XMM1 | ||
1085 | # results accumulated in TMP6, XMMDst, XMM1 | ||
1086 | |||
1087 | # Multiply TMP1 * HashKey (using Karatsuba) | ||
1088 | |||
1089 | movdqa \XMM3, \TMP1 | ||
1090 | pshufd $78, \XMM3, \TMP2 | ||
1091 | pxor \XMM3, \TMP2 | ||
1092 | movdqa HashKey_2(%rsp), \TMP5 | ||
1093 | PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1 | ||
1094 | PCLMULQDQ 0x00, \TMP5, \XMM3 # XMM3 = a0*b0 | ||
1095 | movdqa HashKey_2_k(%rsp), \TMP4 | ||
1096 | PCLMULQDQ 0x00, \TMP4, \TMP2 # TMP2 = (a1+a0)*(b1+b0) | ||
1097 | pxor \TMP1, \TMP6 | ||
1098 | pxor \XMM3, \XMMDst | ||
1099 | pxor \TMP2, \XMM1 # results accumulated in TMP6, XMMDst, XMM1 | ||
1100 | |||
1101 | # Multiply TMP1 * HashKey (using Karatsuba) | ||
1102 | movdqa \XMM4, \TMP1 | ||
1103 | pshufd $78, \XMM4, \TMP2 | ||
1104 | pxor \XMM4, \TMP2 | ||
1105 | movdqa HashKey(%rsp), \TMP5 | ||
1106 | PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1 | ||
1107 | PCLMULQDQ 0x00, \TMP5, \XMM4 # XMM4 = a0*b0 | ||
1108 | movdqa HashKey_k(%rsp), \TMP4 | ||
1109 | PCLMULQDQ 0x00, \TMP4, \TMP2 # TMP2 = (a1+a0)*(b1+b0) | ||
1110 | pxor \TMP1, \TMP6 | ||
1111 | pxor \XMM4, \XMMDst | ||
1112 | pxor \XMM1, \TMP2 | ||
1113 | pxor \TMP6, \TMP2 | ||
1114 | pxor \XMMDst, \TMP2 | ||
1115 | # middle section of the temp results combined as in karatsuba algorithm | ||
1116 | movdqa \TMP2, \TMP4 | ||
1117 | pslldq $8, \TMP4 # left shift TMP4 2 DWs | ||
1118 | psrldq $8, \TMP2 # right shift TMP2 2 DWs | ||
1119 | pxor \TMP4, \XMMDst | ||
1120 | pxor \TMP2, \TMP6 | ||
1121 | # TMP6:XMMDst holds the result of the accumulated carry-less multiplications | ||
1122 | # first phase of the reduction | ||
1123 | movdqa \XMMDst, \TMP2 | ||
1124 | movdqa \XMMDst, \TMP3 | ||
1125 | movdqa \XMMDst, \TMP4 | ||
1126 | # move XMMDst into TMP2, TMP3, TMP4 in order to perform 3 shifts independently | ||
1127 | pslld $31, \TMP2 # packed right shifting << 31 | ||
1128 | pslld $30, \TMP3 # packed right shifting << 30 | ||
1129 | pslld $25, \TMP4 # packed right shifting << 25 | ||
1130 | pxor \TMP3, \TMP2 # xor the shifted versions | ||
1131 | pxor \TMP4, \TMP2 | ||
1132 | movdqa \TMP2, \TMP7 | ||
1133 | psrldq $4, \TMP7 # right shift TMP7 1 DW | ||
1134 | pslldq $12, \TMP2 # left shift TMP2 3 DWs | ||
1135 | pxor \TMP2, \XMMDst | ||
1136 | |||
1137 | # second phase of the reduction | ||
1138 | movdqa \XMMDst, \TMP2 | ||
1139 | # make 3 copies of XMMDst for doing 3 shift operations | ||
1140 | movdqa \XMMDst, \TMP3 | ||
1141 | movdqa \XMMDst, \TMP4 | ||
1142 | psrld $1, \TMP2 # packed left shift >> 1 | ||
1143 | psrld $2, \TMP3 # packed left shift >> 2 | ||
1144 | psrld $7, \TMP4 # packed left shift >> 7 | ||
1145 | pxor \TMP3, \TMP2 # xor the shifted versions | ||
1146 | pxor \TMP4, \TMP2 | ||
1147 | pxor \TMP7, \TMP2 | ||
1148 | pxor \TMP2, \XMMDst | ||
1149 | pxor \TMP6, \XMMDst # reduced result is in XMMDst | ||
1150 | .endm | ||
1151 | |||
1152 | /* Encryption of a single block done*/ | ||
1153 | .macro ENCRYPT_SINGLE_BLOCK XMM0 TMP1 | ||
1154 | |||
1155 | pxor (%arg1), \XMM0 | ||
1156 | movaps 16(%arg1), \TMP1 | ||
1157 | AESENC \TMP1, \XMM0 | ||
1158 | movaps 32(%arg1), \TMP1 | ||
1159 | AESENC \TMP1, \XMM0 | ||
1160 | movaps 48(%arg1), \TMP1 | ||
1161 | AESENC \TMP1, \XMM0 | ||
1162 | movaps 64(%arg1), \TMP1 | ||
1163 | AESENC \TMP1, \XMM0 | ||
1164 | movaps 80(%arg1), \TMP1 | ||
1165 | AESENC \TMP1, \XMM0 | ||
1166 | movaps 96(%arg1), \TMP1 | ||
1167 | AESENC \TMP1, \XMM0 | ||
1168 | movaps 112(%arg1), \TMP1 | ||
1169 | AESENC \TMP1, \XMM0 | ||
1170 | movaps 128(%arg1), \TMP1 | ||
1171 | AESENC \TMP1, \XMM0 | ||
1172 | movaps 144(%arg1), \TMP1 | ||
1173 | AESENC \TMP1, \XMM0 | ||
1174 | movaps 160(%arg1), \TMP1 | ||
1175 | AESENCLAST \TMP1, \XMM0 | ||
1176 | .endm | ||
1177 | |||
1178 | |||
1179 | /***************************************************************************** | ||
1180 | * void aesni_gcm_dec(void *aes_ctx, // AES Key schedule. Starts on a 16 byte boundary. | ||
1181 | * u8 *out, // Plaintext output. Encrypt in-place is allowed. | ||
1182 | * const u8 *in, // Ciphertext input | ||
1183 | * u64 plaintext_len, // Length of data in bytes for decryption. | ||
1184 | * u8 *iv, // Pre-counter block j0: 4 byte salt (from Security Association) | ||
1185 | * // concatenated with 8 byte Initialisation Vector (from IPSec ESP Payload) | ||
1186 | * // concatenated with 0x00000001. 16-byte aligned pointer. | ||
1187 | * u8 *hash_subkey, // H, the Hash sub key input. Data starts on a 16-byte boundary. | ||
1188 | * const u8 *aad, // Additional Authentication Data (AAD) | ||
1189 | * u64 aad_len, // Length of AAD in bytes. With RFC4106 this is going to be 8 or 12 bytes | ||
1190 | * u8 *auth_tag, // Authenticated Tag output. The driver will compare this to the | ||
1191 | * // given authentication tag and only return the plaintext if they match. | ||
1192 | * u64 auth_tag_len); // Authenticated Tag Length in bytes. Valid values are 16 | ||
1193 | * // (most likely), 12 or 8. | ||
1194 | * | ||
1195 | * Assumptions: | ||
1196 | * | ||
1197 | * keys: | ||
1198 | * keys are pre-expanded and aligned to 16 bytes. we are using the first | ||
1199 | * set of 11 keys in the data structure void *aes_ctx | ||
1200 | * | ||
1201 | * iv: | ||
1202 | * 0 1 2 3 | ||
1203 | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||
1204 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
1205 | * | Salt (From the SA) | | ||
1206 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
1207 | * | Initialization Vector | | ||
1208 | * | (This is the sequence number from IPSec header) | | ||
1209 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
1210 | * | 0x1 | | ||
1211 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
1212 | * | ||
1213 | * | ||
1214 | * | ||
1215 | * AAD: | ||
1216 | * AAD padded to 128 bits with 0 | ||
1217 | * for example, assume AAD is a u32 vector | ||
1218 | * | ||
1219 | * if AAD is 8 bytes: | ||
1220 | * AAD[3] = {A0, A1}; | ||
1221 | * padded AAD in xmm register = {A1 A0 0 0} | ||
1222 | * | ||
1223 | * 0 1 2 3 | ||
1224 | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||
1225 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
1226 | * | SPI (A1) | | ||
1227 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
1228 | * | 32-bit Sequence Number (A0) | | ||
1229 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
1230 | * | 0x0 | | ||
1231 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
1232 | * | ||
1233 | * AAD Format with 32-bit Sequence Number | ||
1234 | * | ||
1235 | * if AAD is 12 bytes: | ||
1236 | * AAD[3] = {A0, A1, A2}; | ||
1237 | * padded AAD in xmm register = {A2 A1 A0 0} | ||
1238 | * | ||
1239 | * 0 1 2 3 | ||
1240 | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||
1241 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
1242 | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||
1243 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
1244 | * | SPI (A2) | | ||
1245 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
1246 | * | 64-bit Extended Sequence Number {A1,A0} | | ||
1247 | * | | | ||
1248 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
1249 | * | 0x0 | | ||
1250 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
1251 | * | ||
1252 | * AAD Format with 64-bit Extended Sequence Number | ||
1253 | * | ||
1254 | * aadLen: | ||
1255 | * from the definition of the spec, aadLen can only be 8 or 12 bytes. | ||
1256 | * The code supports 16 too but for other sizes, the code will fail. | ||
1257 | * | ||
1258 | * TLen: | ||
1259 | * from the definition of the spec, TLen can only be 8, 12 or 16 bytes. | ||
1260 | * For other sizes, the code will fail. | ||
1261 | * | ||
1262 | * poly = x^128 + x^127 + x^126 + x^121 + 1 | ||
1263 | * | ||
1264 | *****************************************************************************/ | ||
1265 | |||
1266 | ENTRY(aesni_gcm_dec) | ||
1267 | push %r12 | ||
1268 | push %r13 | ||
1269 | push %r14 | ||
1270 | mov %rsp, %r14 | ||
1271 | /* | ||
1272 | * states of %xmm registers %xmm6:%xmm15 not saved | ||
1273 | * all %xmm registers are clobbered | ||
1274 | */ | ||
1275 | sub $VARIABLE_OFFSET, %rsp | ||
1276 | and $~63, %rsp # align rsp to 64 bytes | ||
1277 | mov %arg6, %r12 | ||
1278 | movdqu (%r12), %xmm13 # %xmm13 = HashKey | ||
1279 | movdqa SHUF_MASK(%rip), %xmm2 | ||
1280 | PSHUFB_XMM %xmm2, %xmm13 | ||
1281 | |||
1282 | |||
1283 | # Precompute HashKey<<1 (mod poly) from the hash key (required for GHASH) | ||
1284 | |||
1285 | movdqa %xmm13, %xmm2 | ||
1286 | psllq $1, %xmm13 | ||
1287 | psrlq $63, %xmm2 | ||
1288 | movdqa %xmm2, %xmm1 | ||
1289 | pslldq $8, %xmm2 | ||
1290 | psrldq $8, %xmm1 | ||
1291 | por %xmm2, %xmm13 | ||
1292 | |||
1293 | # Reduction | ||
1294 | |||
1295 | pshufd $0x24, %xmm1, %xmm2 | ||
1296 | pcmpeqd TWOONE(%rip), %xmm2 | ||
1297 | pand POLY(%rip), %xmm2 | ||
1298 | pxor %xmm2, %xmm13 # %xmm13 holds the HashKey<<1 (mod poly) | ||
1299 | |||
1300 | |||
1301 | # Decrypt first few blocks | ||
1302 | |||
1303 | movdqa %xmm13, HashKey(%rsp) # store HashKey<<1 (mod poly) | ||
1304 | mov %arg4, %r13 # save the number of bytes of plaintext/ciphertext | ||
1305 | and $-16, %r13 # %r13 = %r13 - (%r13 mod 16) | ||
1306 | mov %r13, %r12 | ||
1307 | and $(3<<4), %r12 | ||
1308 | jz _initial_num_blocks_is_0_decrypt | ||
1309 | cmp $(2<<4), %r12 | ||
1310 | jb _initial_num_blocks_is_1_decrypt | ||
1311 | je _initial_num_blocks_is_2_decrypt | ||
1312 | _initial_num_blocks_is_3_decrypt: | ||
1313 | INITIAL_BLOCKS_DEC 3, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ | ||
1314 | %xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 5, 678, dec | ||
1315 | sub $48, %r13 | ||
1316 | jmp _initial_blocks_decrypted | ||
1317 | _initial_num_blocks_is_2_decrypt: | ||
1318 | INITIAL_BLOCKS_DEC 2, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ | ||
1319 | %xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 6, 78, dec | ||
1320 | sub $32, %r13 | ||
1321 | jmp _initial_blocks_decrypted | ||
1322 | _initial_num_blocks_is_1_decrypt: | ||
1323 | INITIAL_BLOCKS_DEC 1, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ | ||
1324 | %xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 7, 8, dec | ||
1325 | sub $16, %r13 | ||
1326 | jmp _initial_blocks_decrypted | ||
1327 | _initial_num_blocks_is_0_decrypt: | ||
1328 | INITIAL_BLOCKS_DEC 0, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ | ||
1329 | %xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 8, 0, dec | ||
1330 | _initial_blocks_decrypted: | ||
1331 | cmp $0, %r13 | ||
1332 | je _zero_cipher_left_decrypt | ||
1333 | sub $64, %r13 | ||
1334 | je _four_cipher_left_decrypt | ||
1335 | _decrypt_by_4: | ||
1336 | GHASH_4_ENCRYPT_4_PARALLEL_DEC %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, \ | ||
1337 | %xmm14, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8, dec | ||
1338 | add $64, %r11 | ||
1339 | sub $64, %r13 | ||
1340 | jne _decrypt_by_4 | ||
1341 | _four_cipher_left_decrypt: | ||
1342 | GHASH_LAST_4 %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14, \ | ||
1343 | %xmm15, %xmm1, %xmm2, %xmm3, %xmm4, %xmm8 | ||
1344 | _zero_cipher_left_decrypt: | ||
1345 | mov %arg4, %r13 | ||
1346 | and $15, %r13 # %r13 = arg4 (mod 16) | ||
1347 | je _multiple_of_16_bytes_decrypt | ||
1348 | |||
1349 | # Handle the last <16 byte block seperately | ||
1350 | |||
1351 | paddd ONE(%rip), %xmm0 # increment CNT to get Yn | ||
1352 | movdqa SHUF_MASK(%rip), %xmm10 | ||
1353 | PSHUFB_XMM %xmm10, %xmm0 | ||
1354 | |||
1355 | ENCRYPT_SINGLE_BLOCK %xmm0, %xmm1 # E(K, Yn) | ||
1356 | sub $16, %r11 | ||
1357 | add %r13, %r11 | ||
1358 | movdqu (%arg3,%r11,1), %xmm1 # recieve the last <16 byte block | ||
1359 | lea SHIFT_MASK+16(%rip), %r12 | ||
1360 | sub %r13, %r12 | ||
1361 | # adjust the shuffle mask pointer to be able to shift 16-%r13 bytes | ||
1362 | # (%r13 is the number of bytes in plaintext mod 16) | ||
1363 | movdqu (%r12), %xmm2 # get the appropriate shuffle mask | ||
1364 | PSHUFB_XMM %xmm2, %xmm1 # right shift 16-%r13 butes | ||
1365 | |||
1366 | movdqa %xmm1, %xmm2 | ||
1367 | pxor %xmm1, %xmm0 # Ciphertext XOR E(K, Yn) | ||
1368 | movdqu ALL_F-SHIFT_MASK(%r12), %xmm1 | ||
1369 | # get the appropriate mask to mask out top 16-%r13 bytes of %xmm0 | ||
1370 | pand %xmm1, %xmm0 # mask out top 16-%r13 bytes of %xmm0 | ||
1371 | pand %xmm1, %xmm2 | ||
1372 | movdqa SHUF_MASK(%rip), %xmm10 | ||
1373 | PSHUFB_XMM %xmm10 ,%xmm2 | ||
1374 | |||
1375 | pxor %xmm2, %xmm8 | ||
1376 | GHASH_MUL %xmm8, %xmm13, %xmm9, %xmm10, %xmm11, %xmm5, %xmm6 | ||
1377 | # GHASH computation for the last <16 byte block | ||
1378 | sub %r13, %r11 | ||
1379 | add $16, %r11 | ||
1380 | |||
1381 | # output %r13 bytes | ||
1382 | MOVQ_R64_XMM %xmm0, %rax | ||
1383 | cmp $8, %r13 | ||
1384 | jle _less_than_8_bytes_left_decrypt | ||
1385 | mov %rax, (%arg2 , %r11, 1) | ||
1386 | add $8, %r11 | ||
1387 | psrldq $8, %xmm0 | ||
1388 | MOVQ_R64_XMM %xmm0, %rax | ||
1389 | sub $8, %r13 | ||
1390 | _less_than_8_bytes_left_decrypt: | ||
1391 | mov %al, (%arg2, %r11, 1) | ||
1392 | add $1, %r11 | ||
1393 | shr $8, %rax | ||
1394 | sub $1, %r13 | ||
1395 | jne _less_than_8_bytes_left_decrypt | ||
1396 | _multiple_of_16_bytes_decrypt: | ||
1397 | mov arg8, %r12 # %r13 = aadLen (number of bytes) | ||
1398 | shl $3, %r12 # convert into number of bits | ||
1399 | movd %r12d, %xmm15 # len(A) in %xmm15 | ||
1400 | shl $3, %arg4 # len(C) in bits (*128) | ||
1401 | MOVQ_R64_XMM %arg4, %xmm1 | ||
1402 | pslldq $8, %xmm15 # %xmm15 = len(A)||0x0000000000000000 | ||
1403 | pxor %xmm1, %xmm15 # %xmm15 = len(A)||len(C) | ||
1404 | pxor %xmm15, %xmm8 | ||
1405 | GHASH_MUL %xmm8, %xmm13, %xmm9, %xmm10, %xmm11, %xmm5, %xmm6 | ||
1406 | # final GHASH computation | ||
1407 | movdqa SHUF_MASK(%rip), %xmm10 | ||
1408 | PSHUFB_XMM %xmm10, %xmm8 | ||
1409 | |||
1410 | mov %arg5, %rax # %rax = *Y0 | ||
1411 | movdqu (%rax), %xmm0 # %xmm0 = Y0 | ||
1412 | ENCRYPT_SINGLE_BLOCK %xmm0, %xmm1 # E(K, Y0) | ||
1413 | pxor %xmm8, %xmm0 | ||
1414 | _return_T_decrypt: | ||
1415 | mov arg9, %r10 # %r10 = authTag | ||
1416 | mov arg10, %r11 # %r11 = auth_tag_len | ||
1417 | cmp $16, %r11 | ||
1418 | je _T_16_decrypt | ||
1419 | cmp $12, %r11 | ||
1420 | je _T_12_decrypt | ||
1421 | _T_8_decrypt: | ||
1422 | MOVQ_R64_XMM %xmm0, %rax | ||
1423 | mov %rax, (%r10) | ||
1424 | jmp _return_T_done_decrypt | ||
1425 | _T_12_decrypt: | ||
1426 | MOVQ_R64_XMM %xmm0, %rax | ||
1427 | mov %rax, (%r10) | ||
1428 | psrldq $8, %xmm0 | ||
1429 | movd %xmm0, %eax | ||
1430 | mov %eax, 8(%r10) | ||
1431 | jmp _return_T_done_decrypt | ||
1432 | _T_16_decrypt: | ||
1433 | movdqu %xmm0, (%r10) | ||
1434 | _return_T_done_decrypt: | ||
1435 | mov %r14, %rsp | ||
1436 | pop %r14 | ||
1437 | pop %r13 | ||
1438 | pop %r12 | ||
1439 | ret | ||
1440 | |||
1441 | |||
1442 | /***************************************************************************** | ||
1443 | * void aesni_gcm_enc(void *aes_ctx, // AES Key schedule. Starts on a 16 byte boundary. | ||
1444 | * u8 *out, // Ciphertext output. Encrypt in-place is allowed. | ||
1445 | * const u8 *in, // Plaintext input | ||
1446 | * u64 plaintext_len, // Length of data in bytes for encryption. | ||
1447 | * u8 *iv, // Pre-counter block j0: 4 byte salt (from Security Association) | ||
1448 | * // concatenated with 8 byte Initialisation Vector (from IPSec ESP Payload) | ||
1449 | * // concatenated with 0x00000001. 16-byte aligned pointer. | ||
1450 | * u8 *hash_subkey, // H, the Hash sub key input. Data starts on a 16-byte boundary. | ||
1451 | * const u8 *aad, // Additional Authentication Data (AAD) | ||
1452 | * u64 aad_len, // Length of AAD in bytes. With RFC4106 this is going to be 8 or 12 bytes | ||
1453 | * u8 *auth_tag, // Authenticated Tag output. | ||
1454 | * u64 auth_tag_len); // Authenticated Tag Length in bytes. Valid values are 16 (most likely), | ||
1455 | * // 12 or 8. | ||
1456 | * | ||
1457 | * Assumptions: | ||
1458 | * | ||
1459 | * keys: | ||
1460 | * keys are pre-expanded and aligned to 16 bytes. we are using the | ||
1461 | * first set of 11 keys in the data structure void *aes_ctx | ||
1462 | * | ||
1463 | * | ||
1464 | * iv: | ||
1465 | * 0 1 2 3 | ||
1466 | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||
1467 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
1468 | * | Salt (From the SA) | | ||
1469 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
1470 | * | Initialization Vector | | ||
1471 | * | (This is the sequence number from IPSec header) | | ||
1472 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
1473 | * | 0x1 | | ||
1474 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
1475 | * | ||
1476 | * | ||
1477 | * | ||
1478 | * AAD: | ||
1479 | * AAD padded to 128 bits with 0 | ||
1480 | * for example, assume AAD is a u32 vector | ||
1481 | * | ||
1482 | * if AAD is 8 bytes: | ||
1483 | * AAD[3] = {A0, A1}; | ||
1484 | * padded AAD in xmm register = {A1 A0 0 0} | ||
1485 | * | ||
1486 | * 0 1 2 3 | ||
1487 | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||
1488 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
1489 | * | SPI (A1) | | ||
1490 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
1491 | * | 32-bit Sequence Number (A0) | | ||
1492 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
1493 | * | 0x0 | | ||
1494 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
1495 | * | ||
1496 | * AAD Format with 32-bit Sequence Number | ||
1497 | * | ||
1498 | * if AAD is 12 bytes: | ||
1499 | * AAD[3] = {A0, A1, A2}; | ||
1500 | * padded AAD in xmm register = {A2 A1 A0 0} | ||
1501 | * | ||
1502 | * 0 1 2 3 | ||
1503 | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||
1504 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
1505 | * | SPI (A2) | | ||
1506 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
1507 | * | 64-bit Extended Sequence Number {A1,A0} | | ||
1508 | * | | | ||
1509 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
1510 | * | 0x0 | | ||
1511 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
1512 | * | ||
1513 | * AAD Format with 64-bit Extended Sequence Number | ||
1514 | * | ||
1515 | * aadLen: | ||
1516 | * from the definition of the spec, aadLen can only be 8 or 12 bytes. | ||
1517 | * The code supports 16 too but for other sizes, the code will fail. | ||
1518 | * | ||
1519 | * TLen: | ||
1520 | * from the definition of the spec, TLen can only be 8, 12 or 16 bytes. | ||
1521 | * For other sizes, the code will fail. | ||
1522 | * | ||
1523 | * poly = x^128 + x^127 + x^126 + x^121 + 1 | ||
1524 | ***************************************************************************/ | ||
1525 | ENTRY(aesni_gcm_enc) | ||
1526 | push %r12 | ||
1527 | push %r13 | ||
1528 | push %r14 | ||
1529 | mov %rsp, %r14 | ||
1530 | # | ||
1531 | # states of %xmm registers %xmm6:%xmm15 not saved | ||
1532 | # all %xmm registers are clobbered | ||
1533 | # | ||
1534 | sub $VARIABLE_OFFSET, %rsp | ||
1535 | and $~63, %rsp | ||
1536 | mov %arg6, %r12 | ||
1537 | movdqu (%r12), %xmm13 | ||
1538 | movdqa SHUF_MASK(%rip), %xmm2 | ||
1539 | PSHUFB_XMM %xmm2, %xmm13 | ||
1540 | |||
1541 | |||
1542 | # precompute HashKey<<1 mod poly from the HashKey (required for GHASH) | ||
1543 | |||
1544 | movdqa %xmm13, %xmm2 | ||
1545 | psllq $1, %xmm13 | ||
1546 | psrlq $63, %xmm2 | ||
1547 | movdqa %xmm2, %xmm1 | ||
1548 | pslldq $8, %xmm2 | ||
1549 | psrldq $8, %xmm1 | ||
1550 | por %xmm2, %xmm13 | ||
1551 | |||
1552 | # reduce HashKey<<1 | ||
1553 | |||
1554 | pshufd $0x24, %xmm1, %xmm2 | ||
1555 | pcmpeqd TWOONE(%rip), %xmm2 | ||
1556 | pand POLY(%rip), %xmm2 | ||
1557 | pxor %xmm2, %xmm13 | ||
1558 | movdqa %xmm13, HashKey(%rsp) | ||
1559 | mov %arg4, %r13 # %xmm13 holds HashKey<<1 (mod poly) | ||
1560 | and $-16, %r13 | ||
1561 | mov %r13, %r12 | ||
1562 | |||
1563 | # Encrypt first few blocks | ||
1564 | |||
1565 | and $(3<<4), %r12 | ||
1566 | jz _initial_num_blocks_is_0_encrypt | ||
1567 | cmp $(2<<4), %r12 | ||
1568 | jb _initial_num_blocks_is_1_encrypt | ||
1569 | je _initial_num_blocks_is_2_encrypt | ||
1570 | _initial_num_blocks_is_3_encrypt: | ||
1571 | INITIAL_BLOCKS_ENC 3, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ | ||
1572 | %xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 5, 678, enc | ||
1573 | sub $48, %r13 | ||
1574 | jmp _initial_blocks_encrypted | ||
1575 | _initial_num_blocks_is_2_encrypt: | ||
1576 | INITIAL_BLOCKS_ENC 2, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ | ||
1577 | %xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 6, 78, enc | ||
1578 | sub $32, %r13 | ||
1579 | jmp _initial_blocks_encrypted | ||
1580 | _initial_num_blocks_is_1_encrypt: | ||
1581 | INITIAL_BLOCKS_ENC 1, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ | ||
1582 | %xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 7, 8, enc | ||
1583 | sub $16, %r13 | ||
1584 | jmp _initial_blocks_encrypted | ||
1585 | _initial_num_blocks_is_0_encrypt: | ||
1586 | INITIAL_BLOCKS_ENC 0, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ | ||
1587 | %xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 8, 0, enc | ||
1588 | _initial_blocks_encrypted: | ||
1589 | |||
1590 | # Main loop - Encrypt remaining blocks | ||
1591 | |||
1592 | cmp $0, %r13 | ||
1593 | je _zero_cipher_left_encrypt | ||
1594 | sub $64, %r13 | ||
1595 | je _four_cipher_left_encrypt | ||
1596 | _encrypt_by_4_encrypt: | ||
1597 | GHASH_4_ENCRYPT_4_PARALLEL_ENC %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, \ | ||
1598 | %xmm14, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8, enc | ||
1599 | add $64, %r11 | ||
1600 | sub $64, %r13 | ||
1601 | jne _encrypt_by_4_encrypt | ||
1602 | _four_cipher_left_encrypt: | ||
1603 | GHASH_LAST_4 %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14, \ | ||
1604 | %xmm15, %xmm1, %xmm2, %xmm3, %xmm4, %xmm8 | ||
1605 | _zero_cipher_left_encrypt: | ||
1606 | mov %arg4, %r13 | ||
1607 | and $15, %r13 # %r13 = arg4 (mod 16) | ||
1608 | je _multiple_of_16_bytes_encrypt | ||
1609 | |||
1610 | # Handle the last <16 Byte block seperately | ||
1611 | paddd ONE(%rip), %xmm0 # INCR CNT to get Yn | ||
1612 | movdqa SHUF_MASK(%rip), %xmm10 | ||
1613 | PSHUFB_XMM %xmm10, %xmm0 | ||
1614 | |||
1615 | ENCRYPT_SINGLE_BLOCK %xmm0, %xmm1 # Encrypt(K, Yn) | ||
1616 | sub $16, %r11 | ||
1617 | add %r13, %r11 | ||
1618 | movdqu (%arg3,%r11,1), %xmm1 # receive the last <16 byte blocks | ||
1619 | lea SHIFT_MASK+16(%rip), %r12 | ||
1620 | sub %r13, %r12 | ||
1621 | # adjust the shuffle mask pointer to be able to shift 16-r13 bytes | ||
1622 | # (%r13 is the number of bytes in plaintext mod 16) | ||
1623 | movdqu (%r12), %xmm2 # get the appropriate shuffle mask | ||
1624 | PSHUFB_XMM %xmm2, %xmm1 # shift right 16-r13 byte | ||
1625 | pxor %xmm1, %xmm0 # Plaintext XOR Encrypt(K, Yn) | ||
1626 | movdqu ALL_F-SHIFT_MASK(%r12), %xmm1 | ||
1627 | # get the appropriate mask to mask out top 16-r13 bytes of xmm0 | ||
1628 | pand %xmm1, %xmm0 # mask out top 16-r13 bytes of xmm0 | ||
1629 | movdqa SHUF_MASK(%rip), %xmm10 | ||
1630 | PSHUFB_XMM %xmm10,%xmm0 | ||
1631 | |||
1632 | pxor %xmm0, %xmm8 | ||
1633 | GHASH_MUL %xmm8, %xmm13, %xmm9, %xmm10, %xmm11, %xmm5, %xmm6 | ||
1634 | # GHASH computation for the last <16 byte block | ||
1635 | sub %r13, %r11 | ||
1636 | add $16, %r11 | ||
1637 | PSHUFB_XMM %xmm10, %xmm1 | ||
1638 | |||
1639 | # shuffle xmm0 back to output as ciphertext | ||
1640 | |||
1641 | # Output %r13 bytes | ||
1642 | MOVQ_R64_XMM %xmm0, %rax | ||
1643 | cmp $8, %r13 | ||
1644 | jle _less_than_8_bytes_left_encrypt | ||
1645 | mov %rax, (%arg2 , %r11, 1) | ||
1646 | add $8, %r11 | ||
1647 | psrldq $8, %xmm0 | ||
1648 | MOVQ_R64_XMM %xmm0, %rax | ||
1649 | sub $8, %r13 | ||
1650 | _less_than_8_bytes_left_encrypt: | ||
1651 | mov %al, (%arg2, %r11, 1) | ||
1652 | add $1, %r11 | ||
1653 | shr $8, %rax | ||
1654 | sub $1, %r13 | ||
1655 | jne _less_than_8_bytes_left_encrypt | ||
1656 | _multiple_of_16_bytes_encrypt: | ||
1657 | mov arg8, %r12 # %r12 = addLen (number of bytes) | ||
1658 | shl $3, %r12 | ||
1659 | movd %r12d, %xmm15 # len(A) in %xmm15 | ||
1660 | shl $3, %arg4 # len(C) in bits (*128) | ||
1661 | MOVQ_R64_XMM %arg4, %xmm1 | ||
1662 | pslldq $8, %xmm15 # %xmm15 = len(A)||0x0000000000000000 | ||
1663 | pxor %xmm1, %xmm15 # %xmm15 = len(A)||len(C) | ||
1664 | pxor %xmm15, %xmm8 | ||
1665 | GHASH_MUL %xmm8, %xmm13, %xmm9, %xmm10, %xmm11, %xmm5, %xmm6 | ||
1666 | # final GHASH computation | ||
1667 | movdqa SHUF_MASK(%rip), %xmm10 | ||
1668 | PSHUFB_XMM %xmm10, %xmm8 # perform a 16 byte swap | ||
1669 | |||
1670 | mov %arg5, %rax # %rax = *Y0 | ||
1671 | movdqu (%rax), %xmm0 # %xmm0 = Y0 | ||
1672 | ENCRYPT_SINGLE_BLOCK %xmm0, %xmm15 # Encrypt(K, Y0) | ||
1673 | pxor %xmm8, %xmm0 | ||
1674 | _return_T_encrypt: | ||
1675 | mov arg9, %r10 # %r10 = authTag | ||
1676 | mov arg10, %r11 # %r11 = auth_tag_len | ||
1677 | cmp $16, %r11 | ||
1678 | je _T_16_encrypt | ||
1679 | cmp $12, %r11 | ||
1680 | je _T_12_encrypt | ||
1681 | _T_8_encrypt: | ||
1682 | MOVQ_R64_XMM %xmm0, %rax | ||
1683 | mov %rax, (%r10) | ||
1684 | jmp _return_T_done_encrypt | ||
1685 | _T_12_encrypt: | ||
1686 | MOVQ_R64_XMM %xmm0, %rax | ||
1687 | mov %rax, (%r10) | ||
1688 | psrldq $8, %xmm0 | ||
1689 | movd %xmm0, %eax | ||
1690 | mov %eax, 8(%r10) | ||
1691 | jmp _return_T_done_encrypt | ||
1692 | _T_16_encrypt: | ||
1693 | movdqu %xmm0, (%r10) | ||
1694 | _return_T_done_encrypt: | ||
1695 | mov %r14, %rsp | ||
1696 | pop %r14 | ||
1697 | pop %r13 | ||
1698 | pop %r12 | ||
1699 | ret | ||
1700 | |||
1701 | #endif | ||
1702 | |||
49 | 1703 | ||
50 | _key_expansion_128: | 1704 | _key_expansion_128: |
51 | _key_expansion_256a: | 1705 | _key_expansion_256a: |
@@ -55,10 +1709,11 @@ _key_expansion_256a: | |||
55 | shufps $0b10001100, %xmm0, %xmm4 | 1709 | shufps $0b10001100, %xmm0, %xmm4 |
56 | pxor %xmm4, %xmm0 | 1710 | pxor %xmm4, %xmm0 |
57 | pxor %xmm1, %xmm0 | 1711 | pxor %xmm1, %xmm0 |
58 | movaps %xmm0, (%rcx) | 1712 | movaps %xmm0, (TKEYP) |
59 | add $0x10, %rcx | 1713 | add $0x10, TKEYP |
60 | ret | 1714 | ret |
61 | 1715 | ||
1716 | .align 4 | ||
62 | _key_expansion_192a: | 1717 | _key_expansion_192a: |
63 | pshufd $0b01010101, %xmm1, %xmm1 | 1718 | pshufd $0b01010101, %xmm1, %xmm1 |
64 | shufps $0b00010000, %xmm0, %xmm4 | 1719 | shufps $0b00010000, %xmm0, %xmm4 |
@@ -76,12 +1731,13 @@ _key_expansion_192a: | |||
76 | 1731 | ||
77 | movaps %xmm0, %xmm1 | 1732 | movaps %xmm0, %xmm1 |
78 | shufps $0b01000100, %xmm0, %xmm6 | 1733 | shufps $0b01000100, %xmm0, %xmm6 |
79 | movaps %xmm6, (%rcx) | 1734 | movaps %xmm6, (TKEYP) |
80 | shufps $0b01001110, %xmm2, %xmm1 | 1735 | shufps $0b01001110, %xmm2, %xmm1 |
81 | movaps %xmm1, 16(%rcx) | 1736 | movaps %xmm1, 0x10(TKEYP) |
82 | add $0x20, %rcx | 1737 | add $0x20, TKEYP |
83 | ret | 1738 | ret |
84 | 1739 | ||
1740 | .align 4 | ||
85 | _key_expansion_192b: | 1741 | _key_expansion_192b: |
86 | pshufd $0b01010101, %xmm1, %xmm1 | 1742 | pshufd $0b01010101, %xmm1, %xmm1 |
87 | shufps $0b00010000, %xmm0, %xmm4 | 1743 | shufps $0b00010000, %xmm0, %xmm4 |
@@ -96,10 +1752,11 @@ _key_expansion_192b: | |||
96 | pxor %xmm3, %xmm2 | 1752 | pxor %xmm3, %xmm2 |
97 | pxor %xmm5, %xmm2 | 1753 | pxor %xmm5, %xmm2 |
98 | 1754 | ||
99 | movaps %xmm0, (%rcx) | 1755 | movaps %xmm0, (TKEYP) |
100 | add $0x10, %rcx | 1756 | add $0x10, TKEYP |
101 | ret | 1757 | ret |
102 | 1758 | ||
1759 | .align 4 | ||
103 | _key_expansion_256b: | 1760 | _key_expansion_256b: |
104 | pshufd $0b10101010, %xmm1, %xmm1 | 1761 | pshufd $0b10101010, %xmm1, %xmm1 |
105 | shufps $0b00010000, %xmm2, %xmm4 | 1762 | shufps $0b00010000, %xmm2, %xmm4 |
@@ -107,8 +1764,8 @@ _key_expansion_256b: | |||
107 | shufps $0b10001100, %xmm2, %xmm4 | 1764 | shufps $0b10001100, %xmm2, %xmm4 |
108 | pxor %xmm4, %xmm2 | 1765 | pxor %xmm4, %xmm2 |
109 | pxor %xmm1, %xmm2 | 1766 | pxor %xmm1, %xmm2 |
110 | movaps %xmm2, (%rcx) | 1767 | movaps %xmm2, (TKEYP) |
111 | add $0x10, %rcx | 1768 | add $0x10, TKEYP |
112 | ret | 1769 | ret |
113 | 1770 | ||
114 | /* | 1771 | /* |
@@ -116,17 +1773,23 @@ _key_expansion_256b: | |||
116 | * unsigned int key_len) | 1773 | * unsigned int key_len) |
117 | */ | 1774 | */ |
118 | ENTRY(aesni_set_key) | 1775 | ENTRY(aesni_set_key) |
119 | movups (%rsi), %xmm0 # user key (first 16 bytes) | 1776 | #ifndef __x86_64__ |
120 | movaps %xmm0, (%rdi) | 1777 | pushl KEYP |
121 | lea 0x10(%rdi), %rcx # key addr | 1778 | movl 8(%esp), KEYP # ctx |
122 | movl %edx, 480(%rdi) | 1779 | movl 12(%esp), UKEYP # in_key |
1780 | movl 16(%esp), %edx # key_len | ||
1781 | #endif | ||
1782 | movups (UKEYP), %xmm0 # user key (first 16 bytes) | ||
1783 | movaps %xmm0, (KEYP) | ||
1784 | lea 0x10(KEYP), TKEYP # key addr | ||
1785 | movl %edx, 480(KEYP) | ||
123 | pxor %xmm4, %xmm4 # xmm4 is assumed 0 in _key_expansion_x | 1786 | pxor %xmm4, %xmm4 # xmm4 is assumed 0 in _key_expansion_x |
124 | cmp $24, %dl | 1787 | cmp $24, %dl |
125 | jb .Lenc_key128 | 1788 | jb .Lenc_key128 |
126 | je .Lenc_key192 | 1789 | je .Lenc_key192 |
127 | movups 0x10(%rsi), %xmm2 # other user key | 1790 | movups 0x10(UKEYP), %xmm2 # other user key |
128 | movaps %xmm2, (%rcx) | 1791 | movaps %xmm2, (TKEYP) |
129 | add $0x10, %rcx | 1792 | add $0x10, TKEYP |
130 | AESKEYGENASSIST 0x1 %xmm2 %xmm1 # round 1 | 1793 | AESKEYGENASSIST 0x1 %xmm2 %xmm1 # round 1 |
131 | call _key_expansion_256a | 1794 | call _key_expansion_256a |
132 | AESKEYGENASSIST 0x1 %xmm0 %xmm1 | 1795 | AESKEYGENASSIST 0x1 %xmm0 %xmm1 |
@@ -155,7 +1818,7 @@ ENTRY(aesni_set_key) | |||
155 | call _key_expansion_256a | 1818 | call _key_expansion_256a |
156 | jmp .Ldec_key | 1819 | jmp .Ldec_key |
157 | .Lenc_key192: | 1820 | .Lenc_key192: |
158 | movq 0x10(%rsi), %xmm2 # other user key | 1821 | movq 0x10(UKEYP), %xmm2 # other user key |
159 | AESKEYGENASSIST 0x1 %xmm2 %xmm1 # round 1 | 1822 | AESKEYGENASSIST 0x1 %xmm2 %xmm1 # round 1 |
160 | call _key_expansion_192a | 1823 | call _key_expansion_192a |
161 | AESKEYGENASSIST 0x2 %xmm2 %xmm1 # round 2 | 1824 | AESKEYGENASSIST 0x2 %xmm2 %xmm1 # round 2 |
@@ -195,33 +1858,47 @@ ENTRY(aesni_set_key) | |||
195 | AESKEYGENASSIST 0x36 %xmm0 %xmm1 # round 10 | 1858 | AESKEYGENASSIST 0x36 %xmm0 %xmm1 # round 10 |
196 | call _key_expansion_128 | 1859 | call _key_expansion_128 |
197 | .Ldec_key: | 1860 | .Ldec_key: |
198 | sub $0x10, %rcx | 1861 | sub $0x10, TKEYP |
199 | movaps (%rdi), %xmm0 | 1862 | movaps (KEYP), %xmm0 |
200 | movaps (%rcx), %xmm1 | 1863 | movaps (TKEYP), %xmm1 |
201 | movaps %xmm0, 240(%rcx) | 1864 | movaps %xmm0, 240(TKEYP) |
202 | movaps %xmm1, 240(%rdi) | 1865 | movaps %xmm1, 240(KEYP) |
203 | add $0x10, %rdi | 1866 | add $0x10, KEYP |
204 | lea 240-16(%rcx), %rsi | 1867 | lea 240-16(TKEYP), UKEYP |
205 | .align 4 | 1868 | .align 4 |
206 | .Ldec_key_loop: | 1869 | .Ldec_key_loop: |
207 | movaps (%rdi), %xmm0 | 1870 | movaps (KEYP), %xmm0 |
208 | AESIMC %xmm0 %xmm1 | 1871 | AESIMC %xmm0 %xmm1 |
209 | movaps %xmm1, (%rsi) | 1872 | movaps %xmm1, (UKEYP) |
210 | add $0x10, %rdi | 1873 | add $0x10, KEYP |
211 | sub $0x10, %rsi | 1874 | sub $0x10, UKEYP |
212 | cmp %rcx, %rdi | 1875 | cmp TKEYP, KEYP |
213 | jb .Ldec_key_loop | 1876 | jb .Ldec_key_loop |
214 | xor %rax, %rax | 1877 | xor AREG, AREG |
1878 | #ifndef __x86_64__ | ||
1879 | popl KEYP | ||
1880 | #endif | ||
215 | ret | 1881 | ret |
216 | 1882 | ||
217 | /* | 1883 | /* |
218 | * void aesni_enc(struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src) | 1884 | * void aesni_enc(struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src) |
219 | */ | 1885 | */ |
220 | ENTRY(aesni_enc) | 1886 | ENTRY(aesni_enc) |
1887 | #ifndef __x86_64__ | ||
1888 | pushl KEYP | ||
1889 | pushl KLEN | ||
1890 | movl 12(%esp), KEYP | ||
1891 | movl 16(%esp), OUTP | ||
1892 | movl 20(%esp), INP | ||
1893 | #endif | ||
221 | movl 480(KEYP), KLEN # key length | 1894 | movl 480(KEYP), KLEN # key length |
222 | movups (INP), STATE # input | 1895 | movups (INP), STATE # input |
223 | call _aesni_enc1 | 1896 | call _aesni_enc1 |
224 | movups STATE, (OUTP) # output | 1897 | movups STATE, (OUTP) # output |
1898 | #ifndef __x86_64__ | ||
1899 | popl KLEN | ||
1900 | popl KEYP | ||
1901 | #endif | ||
225 | ret | 1902 | ret |
226 | 1903 | ||
227 | /* | 1904 | /* |
@@ -236,6 +1913,7 @@ ENTRY(aesni_enc) | |||
236 | * KEY | 1913 | * KEY |
237 | * TKEYP (T1) | 1914 | * TKEYP (T1) |
238 | */ | 1915 | */ |
1916 | .align 4 | ||
239 | _aesni_enc1: | 1917 | _aesni_enc1: |
240 | movaps (KEYP), KEY # key | 1918 | movaps (KEYP), KEY # key |
241 | mov KEYP, TKEYP | 1919 | mov KEYP, TKEYP |
@@ -298,6 +1976,7 @@ _aesni_enc1: | |||
298 | * KEY | 1976 | * KEY |
299 | * TKEYP (T1) | 1977 | * TKEYP (T1) |
300 | */ | 1978 | */ |
1979 | .align 4 | ||
301 | _aesni_enc4: | 1980 | _aesni_enc4: |
302 | movaps (KEYP), KEY # key | 1981 | movaps (KEYP), KEY # key |
303 | mov KEYP, TKEYP | 1982 | mov KEYP, TKEYP |
@@ -391,11 +2070,22 @@ _aesni_enc4: | |||
391 | * void aesni_dec (struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src) | 2070 | * void aesni_dec (struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src) |
392 | */ | 2071 | */ |
393 | ENTRY(aesni_dec) | 2072 | ENTRY(aesni_dec) |
2073 | #ifndef __x86_64__ | ||
2074 | pushl KEYP | ||
2075 | pushl KLEN | ||
2076 | movl 12(%esp), KEYP | ||
2077 | movl 16(%esp), OUTP | ||
2078 | movl 20(%esp), INP | ||
2079 | #endif | ||
394 | mov 480(KEYP), KLEN # key length | 2080 | mov 480(KEYP), KLEN # key length |
395 | add $240, KEYP | 2081 | add $240, KEYP |
396 | movups (INP), STATE # input | 2082 | movups (INP), STATE # input |
397 | call _aesni_dec1 | 2083 | call _aesni_dec1 |
398 | movups STATE, (OUTP) #output | 2084 | movups STATE, (OUTP) #output |
2085 | #ifndef __x86_64__ | ||
2086 | popl KLEN | ||
2087 | popl KEYP | ||
2088 | #endif | ||
399 | ret | 2089 | ret |
400 | 2090 | ||
401 | /* | 2091 | /* |
@@ -410,6 +2100,7 @@ ENTRY(aesni_dec) | |||
410 | * KEY | 2100 | * KEY |
411 | * TKEYP (T1) | 2101 | * TKEYP (T1) |
412 | */ | 2102 | */ |
2103 | .align 4 | ||
413 | _aesni_dec1: | 2104 | _aesni_dec1: |
414 | movaps (KEYP), KEY # key | 2105 | movaps (KEYP), KEY # key |
415 | mov KEYP, TKEYP | 2106 | mov KEYP, TKEYP |
@@ -472,6 +2163,7 @@ _aesni_dec1: | |||
472 | * KEY | 2163 | * KEY |
473 | * TKEYP (T1) | 2164 | * TKEYP (T1) |
474 | */ | 2165 | */ |
2166 | .align 4 | ||
475 | _aesni_dec4: | 2167 | _aesni_dec4: |
476 | movaps (KEYP), KEY # key | 2168 | movaps (KEYP), KEY # key |
477 | mov KEYP, TKEYP | 2169 | mov KEYP, TKEYP |
@@ -566,6 +2258,15 @@ _aesni_dec4: | |||
566 | * size_t len) | 2258 | * size_t len) |
567 | */ | 2259 | */ |
568 | ENTRY(aesni_ecb_enc) | 2260 | ENTRY(aesni_ecb_enc) |
2261 | #ifndef __x86_64__ | ||
2262 | pushl LEN | ||
2263 | pushl KEYP | ||
2264 | pushl KLEN | ||
2265 | movl 16(%esp), KEYP | ||
2266 | movl 20(%esp), OUTP | ||
2267 | movl 24(%esp), INP | ||
2268 | movl 28(%esp), LEN | ||
2269 | #endif | ||
569 | test LEN, LEN # check length | 2270 | test LEN, LEN # check length |
570 | jz .Lecb_enc_ret | 2271 | jz .Lecb_enc_ret |
571 | mov 480(KEYP), KLEN | 2272 | mov 480(KEYP), KLEN |
@@ -602,6 +2303,11 @@ ENTRY(aesni_ecb_enc) | |||
602 | cmp $16, LEN | 2303 | cmp $16, LEN |
603 | jge .Lecb_enc_loop1 | 2304 | jge .Lecb_enc_loop1 |
604 | .Lecb_enc_ret: | 2305 | .Lecb_enc_ret: |
2306 | #ifndef __x86_64__ | ||
2307 | popl KLEN | ||
2308 | popl KEYP | ||
2309 | popl LEN | ||
2310 | #endif | ||
605 | ret | 2311 | ret |
606 | 2312 | ||
607 | /* | 2313 | /* |
@@ -609,6 +2315,15 @@ ENTRY(aesni_ecb_enc) | |||
609 | * size_t len); | 2315 | * size_t len); |
610 | */ | 2316 | */ |
611 | ENTRY(aesni_ecb_dec) | 2317 | ENTRY(aesni_ecb_dec) |
2318 | #ifndef __x86_64__ | ||
2319 | pushl LEN | ||
2320 | pushl KEYP | ||
2321 | pushl KLEN | ||
2322 | movl 16(%esp), KEYP | ||
2323 | movl 20(%esp), OUTP | ||
2324 | movl 24(%esp), INP | ||
2325 | movl 28(%esp), LEN | ||
2326 | #endif | ||
612 | test LEN, LEN | 2327 | test LEN, LEN |
613 | jz .Lecb_dec_ret | 2328 | jz .Lecb_dec_ret |
614 | mov 480(KEYP), KLEN | 2329 | mov 480(KEYP), KLEN |
@@ -646,6 +2361,11 @@ ENTRY(aesni_ecb_dec) | |||
646 | cmp $16, LEN | 2361 | cmp $16, LEN |
647 | jge .Lecb_dec_loop1 | 2362 | jge .Lecb_dec_loop1 |
648 | .Lecb_dec_ret: | 2363 | .Lecb_dec_ret: |
2364 | #ifndef __x86_64__ | ||
2365 | popl KLEN | ||
2366 | popl KEYP | ||
2367 | popl LEN | ||
2368 | #endif | ||
649 | ret | 2369 | ret |
650 | 2370 | ||
651 | /* | 2371 | /* |
@@ -653,6 +2373,17 @@ ENTRY(aesni_ecb_dec) | |||
653 | * size_t len, u8 *iv) | 2373 | * size_t len, u8 *iv) |
654 | */ | 2374 | */ |
655 | ENTRY(aesni_cbc_enc) | 2375 | ENTRY(aesni_cbc_enc) |
2376 | #ifndef __x86_64__ | ||
2377 | pushl IVP | ||
2378 | pushl LEN | ||
2379 | pushl KEYP | ||
2380 | pushl KLEN | ||
2381 | movl 20(%esp), KEYP | ||
2382 | movl 24(%esp), OUTP | ||
2383 | movl 28(%esp), INP | ||
2384 | movl 32(%esp), LEN | ||
2385 | movl 36(%esp), IVP | ||
2386 | #endif | ||
656 | cmp $16, LEN | 2387 | cmp $16, LEN |
657 | jb .Lcbc_enc_ret | 2388 | jb .Lcbc_enc_ret |
658 | mov 480(KEYP), KLEN | 2389 | mov 480(KEYP), KLEN |
@@ -670,6 +2401,12 @@ ENTRY(aesni_cbc_enc) | |||
670 | jge .Lcbc_enc_loop | 2401 | jge .Lcbc_enc_loop |
671 | movups STATE, (IVP) | 2402 | movups STATE, (IVP) |
672 | .Lcbc_enc_ret: | 2403 | .Lcbc_enc_ret: |
2404 | #ifndef __x86_64__ | ||
2405 | popl KLEN | ||
2406 | popl KEYP | ||
2407 | popl LEN | ||
2408 | popl IVP | ||
2409 | #endif | ||
673 | ret | 2410 | ret |
674 | 2411 | ||
675 | /* | 2412 | /* |
@@ -677,6 +2414,17 @@ ENTRY(aesni_cbc_enc) | |||
677 | * size_t len, u8 *iv) | 2414 | * size_t len, u8 *iv) |
678 | */ | 2415 | */ |
679 | ENTRY(aesni_cbc_dec) | 2416 | ENTRY(aesni_cbc_dec) |
2417 | #ifndef __x86_64__ | ||
2418 | pushl IVP | ||
2419 | pushl LEN | ||
2420 | pushl KEYP | ||
2421 | pushl KLEN | ||
2422 | movl 20(%esp), KEYP | ||
2423 | movl 24(%esp), OUTP | ||
2424 | movl 28(%esp), INP | ||
2425 | movl 32(%esp), LEN | ||
2426 | movl 36(%esp), IVP | ||
2427 | #endif | ||
680 | cmp $16, LEN | 2428 | cmp $16, LEN |
681 | jb .Lcbc_dec_just_ret | 2429 | jb .Lcbc_dec_just_ret |
682 | mov 480(KEYP), KLEN | 2430 | mov 480(KEYP), KLEN |
@@ -690,16 +2438,30 @@ ENTRY(aesni_cbc_dec) | |||
690 | movaps IN1, STATE1 | 2438 | movaps IN1, STATE1 |
691 | movups 0x10(INP), IN2 | 2439 | movups 0x10(INP), IN2 |
692 | movaps IN2, STATE2 | 2440 | movaps IN2, STATE2 |
2441 | #ifdef __x86_64__ | ||
693 | movups 0x20(INP), IN3 | 2442 | movups 0x20(INP), IN3 |
694 | movaps IN3, STATE3 | 2443 | movaps IN3, STATE3 |
695 | movups 0x30(INP), IN4 | 2444 | movups 0x30(INP), IN4 |
696 | movaps IN4, STATE4 | 2445 | movaps IN4, STATE4 |
2446 | #else | ||
2447 | movups 0x20(INP), IN1 | ||
2448 | movaps IN1, STATE3 | ||
2449 | movups 0x30(INP), IN2 | ||
2450 | movaps IN2, STATE4 | ||
2451 | #endif | ||
697 | call _aesni_dec4 | 2452 | call _aesni_dec4 |
698 | pxor IV, STATE1 | 2453 | pxor IV, STATE1 |
2454 | #ifdef __x86_64__ | ||
699 | pxor IN1, STATE2 | 2455 | pxor IN1, STATE2 |
700 | pxor IN2, STATE3 | 2456 | pxor IN2, STATE3 |
701 | pxor IN3, STATE4 | 2457 | pxor IN3, STATE4 |
702 | movaps IN4, IV | 2458 | movaps IN4, IV |
2459 | #else | ||
2460 | pxor (INP), STATE2 | ||
2461 | pxor 0x10(INP), STATE3 | ||
2462 | pxor IN1, STATE4 | ||
2463 | movaps IN2, IV | ||
2464 | #endif | ||
703 | movups STATE1, (OUTP) | 2465 | movups STATE1, (OUTP) |
704 | movups STATE2, 0x10(OUTP) | 2466 | movups STATE2, 0x10(OUTP) |
705 | movups STATE3, 0x20(OUTP) | 2467 | movups STATE3, 0x20(OUTP) |
@@ -727,8 +2489,15 @@ ENTRY(aesni_cbc_dec) | |||
727 | .Lcbc_dec_ret: | 2489 | .Lcbc_dec_ret: |
728 | movups IV, (IVP) | 2490 | movups IV, (IVP) |
729 | .Lcbc_dec_just_ret: | 2491 | .Lcbc_dec_just_ret: |
2492 | #ifndef __x86_64__ | ||
2493 | popl KLEN | ||
2494 | popl KEYP | ||
2495 | popl LEN | ||
2496 | popl IVP | ||
2497 | #endif | ||
730 | ret | 2498 | ret |
731 | 2499 | ||
2500 | #ifdef __x86_64__ | ||
732 | .align 16 | 2501 | .align 16 |
733 | .Lbswap_mask: | 2502 | .Lbswap_mask: |
734 | .byte 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 | 2503 | .byte 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 |
@@ -744,6 +2513,7 @@ ENTRY(aesni_cbc_dec) | |||
744 | * INC: == 1, in little endian | 2513 | * INC: == 1, in little endian |
745 | * BSWAP_MASK == endian swapping mask | 2514 | * BSWAP_MASK == endian swapping mask |
746 | */ | 2515 | */ |
2516 | .align 4 | ||
747 | _aesni_inc_init: | 2517 | _aesni_inc_init: |
748 | movaps .Lbswap_mask, BSWAP_MASK | 2518 | movaps .Lbswap_mask, BSWAP_MASK |
749 | movaps IV, CTR | 2519 | movaps IV, CTR |
@@ -768,6 +2538,7 @@ _aesni_inc_init: | |||
768 | * CTR: == output IV, in little endian | 2538 | * CTR: == output IV, in little endian |
769 | * TCTR_LOW: == lower qword of CTR | 2539 | * TCTR_LOW: == lower qword of CTR |
770 | */ | 2540 | */ |
2541 | .align 4 | ||
771 | _aesni_inc: | 2542 | _aesni_inc: |
772 | paddq INC, CTR | 2543 | paddq INC, CTR |
773 | add $1, TCTR_LOW | 2544 | add $1, TCTR_LOW |
@@ -839,3 +2610,4 @@ ENTRY(aesni_ctr_enc) | |||
839 | movups IV, (IVP) | 2610 | movups IV, (IVP) |
840 | .Lctr_enc_just_ret: | 2611 | .Lctr_enc_just_ret: |
841 | ret | 2612 | ret |
2613 | #endif | ||
diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c index 2cb3dcc4490a..e1e60c7d5813 100644 --- a/arch/x86/crypto/aesni-intel_glue.c +++ b/arch/x86/crypto/aesni-intel_glue.c | |||
@@ -5,6 +5,14 @@ | |||
5 | * Copyright (C) 2008, Intel Corp. | 5 | * Copyright (C) 2008, Intel Corp. |
6 | * Author: Huang Ying <ying.huang@intel.com> | 6 | * Author: Huang Ying <ying.huang@intel.com> |
7 | * | 7 | * |
8 | * Added RFC4106 AES-GCM support for 128-bit keys under the AEAD | ||
9 | * interface for 64-bit kernels. | ||
10 | * Authors: Adrian Hoban <adrian.hoban@intel.com> | ||
11 | * Gabriele Paoloni <gabriele.paoloni@intel.com> | ||
12 | * Tadeusz Struk (tadeusz.struk@intel.com) | ||
13 | * Aidan O'Mahony (aidan.o.mahony@intel.com) | ||
14 | * Copyright (c) 2010, Intel Corporation. | ||
15 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | 16 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 17 | * it under the terms of the GNU General Public License as published by |
10 | * the Free Software Foundation; either version 2 of the License, or | 18 | * the Free Software Foundation; either version 2 of the License, or |
@@ -21,6 +29,10 @@ | |||
21 | #include <crypto/ctr.h> | 29 | #include <crypto/ctr.h> |
22 | #include <asm/i387.h> | 30 | #include <asm/i387.h> |
23 | #include <asm/aes.h> | 31 | #include <asm/aes.h> |
32 | #include <crypto/scatterwalk.h> | ||
33 | #include <crypto/internal/aead.h> | ||
34 | #include <linux/workqueue.h> | ||
35 | #include <linux/spinlock.h> | ||
24 | 36 | ||
25 | #if defined(CONFIG_CRYPTO_CTR) || defined(CONFIG_CRYPTO_CTR_MODULE) | 37 | #if defined(CONFIG_CRYPTO_CTR) || defined(CONFIG_CRYPTO_CTR_MODULE) |
26 | #define HAS_CTR | 38 | #define HAS_CTR |
@@ -42,8 +54,31 @@ struct async_aes_ctx { | |||
42 | struct cryptd_ablkcipher *cryptd_tfm; | 54 | struct cryptd_ablkcipher *cryptd_tfm; |
43 | }; | 55 | }; |
44 | 56 | ||
45 | #define AESNI_ALIGN 16 | 57 | /* This data is stored at the end of the crypto_tfm struct. |
58 | * It's a type of per "session" data storage location. | ||
59 | * This needs to be 16 byte aligned. | ||
60 | */ | ||
61 | struct aesni_rfc4106_gcm_ctx { | ||
62 | u8 hash_subkey[16]; | ||
63 | struct crypto_aes_ctx aes_key_expanded; | ||
64 | u8 nonce[4]; | ||
65 | struct cryptd_aead *cryptd_tfm; | ||
66 | }; | ||
67 | |||
68 | struct aesni_gcm_set_hash_subkey_result { | ||
69 | int err; | ||
70 | struct completion completion; | ||
71 | }; | ||
72 | |||
73 | struct aesni_hash_subkey_req_data { | ||
74 | u8 iv[16]; | ||
75 | struct aesni_gcm_set_hash_subkey_result result; | ||
76 | struct scatterlist sg; | ||
77 | }; | ||
78 | |||
79 | #define AESNI_ALIGN (16) | ||
46 | #define AES_BLOCK_MASK (~(AES_BLOCK_SIZE-1)) | 80 | #define AES_BLOCK_MASK (~(AES_BLOCK_SIZE-1)) |
81 | #define RFC4106_HASH_SUBKEY_SIZE 16 | ||
47 | 82 | ||
48 | asmlinkage int aesni_set_key(struct crypto_aes_ctx *ctx, const u8 *in_key, | 83 | asmlinkage int aesni_set_key(struct crypto_aes_ctx *ctx, const u8 *in_key, |
49 | unsigned int key_len); | 84 | unsigned int key_len); |
@@ -59,9 +94,62 @@ asmlinkage void aesni_cbc_enc(struct crypto_aes_ctx *ctx, u8 *out, | |||
59 | const u8 *in, unsigned int len, u8 *iv); | 94 | const u8 *in, unsigned int len, u8 *iv); |
60 | asmlinkage void aesni_cbc_dec(struct crypto_aes_ctx *ctx, u8 *out, | 95 | asmlinkage void aesni_cbc_dec(struct crypto_aes_ctx *ctx, u8 *out, |
61 | const u8 *in, unsigned int len, u8 *iv); | 96 | const u8 *in, unsigned int len, u8 *iv); |
97 | #ifdef CONFIG_X86_64 | ||
62 | asmlinkage void aesni_ctr_enc(struct crypto_aes_ctx *ctx, u8 *out, | 98 | asmlinkage void aesni_ctr_enc(struct crypto_aes_ctx *ctx, u8 *out, |
63 | const u8 *in, unsigned int len, u8 *iv); | 99 | const u8 *in, unsigned int len, u8 *iv); |
64 | 100 | ||
101 | /* asmlinkage void aesni_gcm_enc() | ||
102 | * void *ctx, AES Key schedule. Starts on a 16 byte boundary. | ||
103 | * u8 *out, Ciphertext output. Encrypt in-place is allowed. | ||
104 | * const u8 *in, Plaintext input | ||
105 | * unsigned long plaintext_len, Length of data in bytes for encryption. | ||
106 | * u8 *iv, Pre-counter block j0: 4 byte salt (from Security Association) | ||
107 | * concatenated with 8 byte Initialisation Vector (from IPSec ESP | ||
108 | * Payload) concatenated with 0x00000001. 16-byte aligned pointer. | ||
109 | * u8 *hash_subkey, the Hash sub key input. Data starts on a 16-byte boundary. | ||
110 | * const u8 *aad, Additional Authentication Data (AAD) | ||
111 | * unsigned long aad_len, Length of AAD in bytes. With RFC4106 this | ||
112 | * is going to be 8 or 12 bytes | ||
113 | * u8 *auth_tag, Authenticated Tag output. | ||
114 | * unsigned long auth_tag_len), Authenticated Tag Length in bytes. | ||
115 | * Valid values are 16 (most likely), 12 or 8. | ||
116 | */ | ||
117 | asmlinkage void aesni_gcm_enc(void *ctx, u8 *out, | ||
118 | const u8 *in, unsigned long plaintext_len, u8 *iv, | ||
119 | u8 *hash_subkey, const u8 *aad, unsigned long aad_len, | ||
120 | u8 *auth_tag, unsigned long auth_tag_len); | ||
121 | |||
122 | /* asmlinkage void aesni_gcm_dec() | ||
123 | * void *ctx, AES Key schedule. Starts on a 16 byte boundary. | ||
124 | * u8 *out, Plaintext output. Decrypt in-place is allowed. | ||
125 | * const u8 *in, Ciphertext input | ||
126 | * unsigned long ciphertext_len, Length of data in bytes for decryption. | ||
127 | * u8 *iv, Pre-counter block j0: 4 byte salt (from Security Association) | ||
128 | * concatenated with 8 byte Initialisation Vector (from IPSec ESP | ||
129 | * Payload) concatenated with 0x00000001. 16-byte aligned pointer. | ||
130 | * u8 *hash_subkey, the Hash sub key input. Data starts on a 16-byte boundary. | ||
131 | * const u8 *aad, Additional Authentication Data (AAD) | ||
132 | * unsigned long aad_len, Length of AAD in bytes. With RFC4106 this is going | ||
133 | * to be 8 or 12 bytes | ||
134 | * u8 *auth_tag, Authenticated Tag output. | ||
135 | * unsigned long auth_tag_len) Authenticated Tag Length in bytes. | ||
136 | * Valid values are 16 (most likely), 12 or 8. | ||
137 | */ | ||
138 | asmlinkage void aesni_gcm_dec(void *ctx, u8 *out, | ||
139 | const u8 *in, unsigned long ciphertext_len, u8 *iv, | ||
140 | u8 *hash_subkey, const u8 *aad, unsigned long aad_len, | ||
141 | u8 *auth_tag, unsigned long auth_tag_len); | ||
142 | |||
143 | static inline struct | ||
144 | aesni_rfc4106_gcm_ctx *aesni_rfc4106_gcm_ctx_get(struct crypto_aead *tfm) | ||
145 | { | ||
146 | return | ||
147 | (struct aesni_rfc4106_gcm_ctx *) | ||
148 | PTR_ALIGN((u8 *) | ||
149 | crypto_tfm_ctx(crypto_aead_tfm(tfm)), AESNI_ALIGN); | ||
150 | } | ||
151 | #endif | ||
152 | |||
65 | static inline struct crypto_aes_ctx *aes_ctx(void *raw_ctx) | 153 | static inline struct crypto_aes_ctx *aes_ctx(void *raw_ctx) |
66 | { | 154 | { |
67 | unsigned long addr = (unsigned long)raw_ctx; | 155 | unsigned long addr = (unsigned long)raw_ctx; |
@@ -324,6 +412,7 @@ static struct crypto_alg blk_cbc_alg = { | |||
324 | }, | 412 | }, |
325 | }; | 413 | }; |
326 | 414 | ||
415 | #ifdef CONFIG_X86_64 | ||
327 | static void ctr_crypt_final(struct crypto_aes_ctx *ctx, | 416 | static void ctr_crypt_final(struct crypto_aes_ctx *ctx, |
328 | struct blkcipher_walk *walk) | 417 | struct blkcipher_walk *walk) |
329 | { | 418 | { |
@@ -389,6 +478,7 @@ static struct crypto_alg blk_ctr_alg = { | |||
389 | }, | 478 | }, |
390 | }, | 479 | }, |
391 | }; | 480 | }; |
481 | #endif | ||
392 | 482 | ||
393 | static int ablk_set_key(struct crypto_ablkcipher *tfm, const u8 *key, | 483 | static int ablk_set_key(struct crypto_ablkcipher *tfm, const u8 *key, |
394 | unsigned int key_len) | 484 | unsigned int key_len) |
@@ -536,6 +626,7 @@ static struct crypto_alg ablk_cbc_alg = { | |||
536 | }, | 626 | }, |
537 | }; | 627 | }; |
538 | 628 | ||
629 | #ifdef CONFIG_X86_64 | ||
539 | static int ablk_ctr_init(struct crypto_tfm *tfm) | 630 | static int ablk_ctr_init(struct crypto_tfm *tfm) |
540 | { | 631 | { |
541 | struct cryptd_ablkcipher *cryptd_tfm; | 632 | struct cryptd_ablkcipher *cryptd_tfm; |
@@ -612,6 +703,7 @@ static struct crypto_alg ablk_rfc3686_ctr_alg = { | |||
612 | }, | 703 | }, |
613 | }; | 704 | }; |
614 | #endif | 705 | #endif |
706 | #endif | ||
615 | 707 | ||
616 | #ifdef HAS_LRW | 708 | #ifdef HAS_LRW |
617 | static int ablk_lrw_init(struct crypto_tfm *tfm) | 709 | static int ablk_lrw_init(struct crypto_tfm *tfm) |
@@ -730,6 +822,424 @@ static struct crypto_alg ablk_xts_alg = { | |||
730 | }; | 822 | }; |
731 | #endif | 823 | #endif |
732 | 824 | ||
825 | #ifdef CONFIG_X86_64 | ||
826 | static int rfc4106_init(struct crypto_tfm *tfm) | ||
827 | { | ||
828 | struct cryptd_aead *cryptd_tfm; | ||
829 | struct aesni_rfc4106_gcm_ctx *ctx = (struct aesni_rfc4106_gcm_ctx *) | ||
830 | PTR_ALIGN((u8 *)crypto_tfm_ctx(tfm), AESNI_ALIGN); | ||
831 | cryptd_tfm = cryptd_alloc_aead("__driver-gcm-aes-aesni", 0, 0); | ||
832 | if (IS_ERR(cryptd_tfm)) | ||
833 | return PTR_ERR(cryptd_tfm); | ||
834 | ctx->cryptd_tfm = cryptd_tfm; | ||
835 | tfm->crt_aead.reqsize = sizeof(struct aead_request) | ||
836 | + crypto_aead_reqsize(&cryptd_tfm->base); | ||
837 | return 0; | ||
838 | } | ||
839 | |||
840 | static void rfc4106_exit(struct crypto_tfm *tfm) | ||
841 | { | ||
842 | struct aesni_rfc4106_gcm_ctx *ctx = | ||
843 | (struct aesni_rfc4106_gcm_ctx *) | ||
844 | PTR_ALIGN((u8 *)crypto_tfm_ctx(tfm), AESNI_ALIGN); | ||
845 | if (!IS_ERR(ctx->cryptd_tfm)) | ||
846 | cryptd_free_aead(ctx->cryptd_tfm); | ||
847 | return; | ||
848 | } | ||
849 | |||
850 | static void | ||
851 | rfc4106_set_hash_subkey_done(struct crypto_async_request *req, int err) | ||
852 | { | ||
853 | struct aesni_gcm_set_hash_subkey_result *result = req->data; | ||
854 | |||
855 | if (err == -EINPROGRESS) | ||
856 | return; | ||
857 | result->err = err; | ||
858 | complete(&result->completion); | ||
859 | } | ||
860 | |||
861 | static int | ||
862 | rfc4106_set_hash_subkey(u8 *hash_subkey, const u8 *key, unsigned int key_len) | ||
863 | { | ||
864 | struct crypto_ablkcipher *ctr_tfm; | ||
865 | struct ablkcipher_request *req; | ||
866 | int ret = -EINVAL; | ||
867 | struct aesni_hash_subkey_req_data *req_data; | ||
868 | |||
869 | ctr_tfm = crypto_alloc_ablkcipher("ctr(aes)", 0, 0); | ||
870 | if (IS_ERR(ctr_tfm)) | ||
871 | return PTR_ERR(ctr_tfm); | ||
872 | |||
873 | crypto_ablkcipher_clear_flags(ctr_tfm, ~0); | ||
874 | |||
875 | ret = crypto_ablkcipher_setkey(ctr_tfm, key, key_len); | ||
876 | if (ret) { | ||
877 | crypto_free_ablkcipher(ctr_tfm); | ||
878 | return ret; | ||
879 | } | ||
880 | |||
881 | req = ablkcipher_request_alloc(ctr_tfm, GFP_KERNEL); | ||
882 | if (!req) { | ||
883 | crypto_free_ablkcipher(ctr_tfm); | ||
884 | return -EINVAL; | ||
885 | } | ||
886 | |||
887 | req_data = kmalloc(sizeof(*req_data), GFP_KERNEL); | ||
888 | if (!req_data) { | ||
889 | crypto_free_ablkcipher(ctr_tfm); | ||
890 | return -ENOMEM; | ||
891 | } | ||
892 | memset(req_data->iv, 0, sizeof(req_data->iv)); | ||
893 | |||
894 | /* Clear the data in the hash sub key container to zero.*/ | ||
895 | /* We want to cipher all zeros to create the hash sub key. */ | ||
896 | memset(hash_subkey, 0, RFC4106_HASH_SUBKEY_SIZE); | ||
897 | |||
898 | init_completion(&req_data->result.completion); | ||
899 | sg_init_one(&req_data->sg, hash_subkey, RFC4106_HASH_SUBKEY_SIZE); | ||
900 | ablkcipher_request_set_tfm(req, ctr_tfm); | ||
901 | ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP | | ||
902 | CRYPTO_TFM_REQ_MAY_BACKLOG, | ||
903 | rfc4106_set_hash_subkey_done, | ||
904 | &req_data->result); | ||
905 | |||
906 | ablkcipher_request_set_crypt(req, &req_data->sg, | ||
907 | &req_data->sg, RFC4106_HASH_SUBKEY_SIZE, req_data->iv); | ||
908 | |||
909 | ret = crypto_ablkcipher_encrypt(req); | ||
910 | if (ret == -EINPROGRESS || ret == -EBUSY) { | ||
911 | ret = wait_for_completion_interruptible | ||
912 | (&req_data->result.completion); | ||
913 | if (!ret) | ||
914 | ret = req_data->result.err; | ||
915 | } | ||
916 | ablkcipher_request_free(req); | ||
917 | kfree(req_data); | ||
918 | crypto_free_ablkcipher(ctr_tfm); | ||
919 | return ret; | ||
920 | } | ||
921 | |||
922 | static int rfc4106_set_key(struct crypto_aead *parent, const u8 *key, | ||
923 | unsigned int key_len) | ||
924 | { | ||
925 | int ret = 0; | ||
926 | struct crypto_tfm *tfm = crypto_aead_tfm(parent); | ||
927 | struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(parent); | ||
928 | u8 *new_key_mem = NULL; | ||
929 | |||
930 | if (key_len < 4) { | ||
931 | crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); | ||
932 | return -EINVAL; | ||
933 | } | ||
934 | /*Account for 4 byte nonce at the end.*/ | ||
935 | key_len -= 4; | ||
936 | if (key_len != AES_KEYSIZE_128) { | ||
937 | crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); | ||
938 | return -EINVAL; | ||
939 | } | ||
940 | |||
941 | memcpy(ctx->nonce, key + key_len, sizeof(ctx->nonce)); | ||
942 | /*This must be on a 16 byte boundary!*/ | ||
943 | if ((unsigned long)(&(ctx->aes_key_expanded.key_enc[0])) % AESNI_ALIGN) | ||
944 | return -EINVAL; | ||
945 | |||
946 | if ((unsigned long)key % AESNI_ALIGN) { | ||
947 | /*key is not aligned: use an auxuliar aligned pointer*/ | ||
948 | new_key_mem = kmalloc(key_len+AESNI_ALIGN, GFP_KERNEL); | ||
949 | if (!new_key_mem) | ||
950 | return -ENOMEM; | ||
951 | |||
952 | new_key_mem = PTR_ALIGN(new_key_mem, AESNI_ALIGN); | ||
953 | memcpy(new_key_mem, key, key_len); | ||
954 | key = new_key_mem; | ||
955 | } | ||
956 | |||
957 | if (!irq_fpu_usable()) | ||
958 | ret = crypto_aes_expand_key(&(ctx->aes_key_expanded), | ||
959 | key, key_len); | ||
960 | else { | ||
961 | kernel_fpu_begin(); | ||
962 | ret = aesni_set_key(&(ctx->aes_key_expanded), key, key_len); | ||
963 | kernel_fpu_end(); | ||
964 | } | ||
965 | /*This must be on a 16 byte boundary!*/ | ||
966 | if ((unsigned long)(&(ctx->hash_subkey[0])) % AESNI_ALIGN) { | ||
967 | ret = -EINVAL; | ||
968 | goto exit; | ||
969 | } | ||
970 | ret = rfc4106_set_hash_subkey(ctx->hash_subkey, key, key_len); | ||
971 | exit: | ||
972 | kfree(new_key_mem); | ||
973 | return ret; | ||
974 | } | ||
975 | |||
976 | /* This is the Integrity Check Value (aka the authentication tag length and can | ||
977 | * be 8, 12 or 16 bytes long. */ | ||
978 | static int rfc4106_set_authsize(struct crypto_aead *parent, | ||
979 | unsigned int authsize) | ||
980 | { | ||
981 | struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(parent); | ||
982 | struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm); | ||
983 | |||
984 | switch (authsize) { | ||
985 | case 8: | ||
986 | case 12: | ||
987 | case 16: | ||
988 | break; | ||
989 | default: | ||
990 | return -EINVAL; | ||
991 | } | ||
992 | crypto_aead_crt(parent)->authsize = authsize; | ||
993 | crypto_aead_crt(cryptd_child)->authsize = authsize; | ||
994 | return 0; | ||
995 | } | ||
996 | |||
997 | static int rfc4106_encrypt(struct aead_request *req) | ||
998 | { | ||
999 | int ret; | ||
1000 | struct crypto_aead *tfm = crypto_aead_reqtfm(req); | ||
1001 | struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm); | ||
1002 | struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm); | ||
1003 | |||
1004 | if (!irq_fpu_usable()) { | ||
1005 | struct aead_request *cryptd_req = | ||
1006 | (struct aead_request *) aead_request_ctx(req); | ||
1007 | memcpy(cryptd_req, req, sizeof(*req)); | ||
1008 | aead_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); | ||
1009 | return crypto_aead_encrypt(cryptd_req); | ||
1010 | } else { | ||
1011 | kernel_fpu_begin(); | ||
1012 | ret = cryptd_child->base.crt_aead.encrypt(req); | ||
1013 | kernel_fpu_end(); | ||
1014 | return ret; | ||
1015 | } | ||
1016 | } | ||
1017 | |||
1018 | static int rfc4106_decrypt(struct aead_request *req) | ||
1019 | { | ||
1020 | int ret; | ||
1021 | struct crypto_aead *tfm = crypto_aead_reqtfm(req); | ||
1022 | struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm); | ||
1023 | struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm); | ||
1024 | |||
1025 | if (!irq_fpu_usable()) { | ||
1026 | struct aead_request *cryptd_req = | ||
1027 | (struct aead_request *) aead_request_ctx(req); | ||
1028 | memcpy(cryptd_req, req, sizeof(*req)); | ||
1029 | aead_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); | ||
1030 | return crypto_aead_decrypt(cryptd_req); | ||
1031 | } else { | ||
1032 | kernel_fpu_begin(); | ||
1033 | ret = cryptd_child->base.crt_aead.decrypt(req); | ||
1034 | kernel_fpu_end(); | ||
1035 | return ret; | ||
1036 | } | ||
1037 | } | ||
1038 | |||
1039 | static struct crypto_alg rfc4106_alg = { | ||
1040 | .cra_name = "rfc4106(gcm(aes))", | ||
1041 | .cra_driver_name = "rfc4106-gcm-aesni", | ||
1042 | .cra_priority = 400, | ||
1043 | .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC, | ||
1044 | .cra_blocksize = 1, | ||
1045 | .cra_ctxsize = sizeof(struct aesni_rfc4106_gcm_ctx) + AESNI_ALIGN, | ||
1046 | .cra_alignmask = 0, | ||
1047 | .cra_type = &crypto_nivaead_type, | ||
1048 | .cra_module = THIS_MODULE, | ||
1049 | .cra_list = LIST_HEAD_INIT(rfc4106_alg.cra_list), | ||
1050 | .cra_init = rfc4106_init, | ||
1051 | .cra_exit = rfc4106_exit, | ||
1052 | .cra_u = { | ||
1053 | .aead = { | ||
1054 | .setkey = rfc4106_set_key, | ||
1055 | .setauthsize = rfc4106_set_authsize, | ||
1056 | .encrypt = rfc4106_encrypt, | ||
1057 | .decrypt = rfc4106_decrypt, | ||
1058 | .geniv = "seqiv", | ||
1059 | .ivsize = 8, | ||
1060 | .maxauthsize = 16, | ||
1061 | }, | ||
1062 | }, | ||
1063 | }; | ||
1064 | |||
1065 | static int __driver_rfc4106_encrypt(struct aead_request *req) | ||
1066 | { | ||
1067 | u8 one_entry_in_sg = 0; | ||
1068 | u8 *src, *dst, *assoc; | ||
1069 | __be32 counter = cpu_to_be32(1); | ||
1070 | struct crypto_aead *tfm = crypto_aead_reqtfm(req); | ||
1071 | struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm); | ||
1072 | void *aes_ctx = &(ctx->aes_key_expanded); | ||
1073 | unsigned long auth_tag_len = crypto_aead_authsize(tfm); | ||
1074 | u8 iv_tab[16+AESNI_ALIGN]; | ||
1075 | u8* iv = (u8 *) PTR_ALIGN((u8 *)iv_tab, AESNI_ALIGN); | ||
1076 | struct scatter_walk src_sg_walk; | ||
1077 | struct scatter_walk assoc_sg_walk; | ||
1078 | struct scatter_walk dst_sg_walk; | ||
1079 | unsigned int i; | ||
1080 | |||
1081 | /* Assuming we are supporting rfc4106 64-bit extended */ | ||
1082 | /* sequence numbers We need to have the AAD length equal */ | ||
1083 | /* to 8 or 12 bytes */ | ||
1084 | if (unlikely(req->assoclen != 8 && req->assoclen != 12)) | ||
1085 | return -EINVAL; | ||
1086 | /* IV below built */ | ||
1087 | for (i = 0; i < 4; i++) | ||
1088 | *(iv+i) = ctx->nonce[i]; | ||
1089 | for (i = 0; i < 8; i++) | ||
1090 | *(iv+4+i) = req->iv[i]; | ||
1091 | *((__be32 *)(iv+12)) = counter; | ||
1092 | |||
1093 | if ((sg_is_last(req->src)) && (sg_is_last(req->assoc))) { | ||
1094 | one_entry_in_sg = 1; | ||
1095 | scatterwalk_start(&src_sg_walk, req->src); | ||
1096 | scatterwalk_start(&assoc_sg_walk, req->assoc); | ||
1097 | src = scatterwalk_map(&src_sg_walk, 0); | ||
1098 | assoc = scatterwalk_map(&assoc_sg_walk, 0); | ||
1099 | dst = src; | ||
1100 | if (unlikely(req->src != req->dst)) { | ||
1101 | scatterwalk_start(&dst_sg_walk, req->dst); | ||
1102 | dst = scatterwalk_map(&dst_sg_walk, 0); | ||
1103 | } | ||
1104 | |||
1105 | } else { | ||
1106 | /* Allocate memory for src, dst, assoc */ | ||
1107 | src = kmalloc(req->cryptlen + auth_tag_len + req->assoclen, | ||
1108 | GFP_ATOMIC); | ||
1109 | if (unlikely(!src)) | ||
1110 | return -ENOMEM; | ||
1111 | assoc = (src + req->cryptlen + auth_tag_len); | ||
1112 | scatterwalk_map_and_copy(src, req->src, 0, req->cryptlen, 0); | ||
1113 | scatterwalk_map_and_copy(assoc, req->assoc, 0, | ||
1114 | req->assoclen, 0); | ||
1115 | dst = src; | ||
1116 | } | ||
1117 | |||
1118 | aesni_gcm_enc(aes_ctx, dst, src, (unsigned long)req->cryptlen, iv, | ||
1119 | ctx->hash_subkey, assoc, (unsigned long)req->assoclen, dst | ||
1120 | + ((unsigned long)req->cryptlen), auth_tag_len); | ||
1121 | |||
1122 | /* The authTag (aka the Integrity Check Value) needs to be written | ||
1123 | * back to the packet. */ | ||
1124 | if (one_entry_in_sg) { | ||
1125 | if (unlikely(req->src != req->dst)) { | ||
1126 | scatterwalk_unmap(dst, 0); | ||
1127 | scatterwalk_done(&dst_sg_walk, 0, 0); | ||
1128 | } | ||
1129 | scatterwalk_unmap(src, 0); | ||
1130 | scatterwalk_unmap(assoc, 0); | ||
1131 | scatterwalk_done(&src_sg_walk, 0, 0); | ||
1132 | scatterwalk_done(&assoc_sg_walk, 0, 0); | ||
1133 | } else { | ||
1134 | scatterwalk_map_and_copy(dst, req->dst, 0, | ||
1135 | req->cryptlen + auth_tag_len, 1); | ||
1136 | kfree(src); | ||
1137 | } | ||
1138 | return 0; | ||
1139 | } | ||
1140 | |||
1141 | static int __driver_rfc4106_decrypt(struct aead_request *req) | ||
1142 | { | ||
1143 | u8 one_entry_in_sg = 0; | ||
1144 | u8 *src, *dst, *assoc; | ||
1145 | unsigned long tempCipherLen = 0; | ||
1146 | __be32 counter = cpu_to_be32(1); | ||
1147 | int retval = 0; | ||
1148 | struct crypto_aead *tfm = crypto_aead_reqtfm(req); | ||
1149 | struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm); | ||
1150 | void *aes_ctx = &(ctx->aes_key_expanded); | ||
1151 | unsigned long auth_tag_len = crypto_aead_authsize(tfm); | ||
1152 | u8 iv_and_authTag[32+AESNI_ALIGN]; | ||
1153 | u8 *iv = (u8 *) PTR_ALIGN((u8 *)iv_and_authTag, AESNI_ALIGN); | ||
1154 | u8 *authTag = iv + 16; | ||
1155 | struct scatter_walk src_sg_walk; | ||
1156 | struct scatter_walk assoc_sg_walk; | ||
1157 | struct scatter_walk dst_sg_walk; | ||
1158 | unsigned int i; | ||
1159 | |||
1160 | if (unlikely((req->cryptlen < auth_tag_len) || | ||
1161 | (req->assoclen != 8 && req->assoclen != 12))) | ||
1162 | return -EINVAL; | ||
1163 | /* Assuming we are supporting rfc4106 64-bit extended */ | ||
1164 | /* sequence numbers We need to have the AAD length */ | ||
1165 | /* equal to 8 or 12 bytes */ | ||
1166 | |||
1167 | tempCipherLen = (unsigned long)(req->cryptlen - auth_tag_len); | ||
1168 | /* IV below built */ | ||
1169 | for (i = 0; i < 4; i++) | ||
1170 | *(iv+i) = ctx->nonce[i]; | ||
1171 | for (i = 0; i < 8; i++) | ||
1172 | *(iv+4+i) = req->iv[i]; | ||
1173 | *((__be32 *)(iv+12)) = counter; | ||
1174 | |||
1175 | if ((sg_is_last(req->src)) && (sg_is_last(req->assoc))) { | ||
1176 | one_entry_in_sg = 1; | ||
1177 | scatterwalk_start(&src_sg_walk, req->src); | ||
1178 | scatterwalk_start(&assoc_sg_walk, req->assoc); | ||
1179 | src = scatterwalk_map(&src_sg_walk, 0); | ||
1180 | assoc = scatterwalk_map(&assoc_sg_walk, 0); | ||
1181 | dst = src; | ||
1182 | if (unlikely(req->src != req->dst)) { | ||
1183 | scatterwalk_start(&dst_sg_walk, req->dst); | ||
1184 | dst = scatterwalk_map(&dst_sg_walk, 0); | ||
1185 | } | ||
1186 | |||
1187 | } else { | ||
1188 | /* Allocate memory for src, dst, assoc */ | ||
1189 | src = kmalloc(req->cryptlen + req->assoclen, GFP_ATOMIC); | ||
1190 | if (!src) | ||
1191 | return -ENOMEM; | ||
1192 | assoc = (src + req->cryptlen + auth_tag_len); | ||
1193 | scatterwalk_map_and_copy(src, req->src, 0, req->cryptlen, 0); | ||
1194 | scatterwalk_map_and_copy(assoc, req->assoc, 0, | ||
1195 | req->assoclen, 0); | ||
1196 | dst = src; | ||
1197 | } | ||
1198 | |||
1199 | aesni_gcm_dec(aes_ctx, dst, src, tempCipherLen, iv, | ||
1200 | ctx->hash_subkey, assoc, (unsigned long)req->assoclen, | ||
1201 | authTag, auth_tag_len); | ||
1202 | |||
1203 | /* Compare generated tag with passed in tag. */ | ||
1204 | retval = memcmp(src + tempCipherLen, authTag, auth_tag_len) ? | ||
1205 | -EBADMSG : 0; | ||
1206 | |||
1207 | if (one_entry_in_sg) { | ||
1208 | if (unlikely(req->src != req->dst)) { | ||
1209 | scatterwalk_unmap(dst, 0); | ||
1210 | scatterwalk_done(&dst_sg_walk, 0, 0); | ||
1211 | } | ||
1212 | scatterwalk_unmap(src, 0); | ||
1213 | scatterwalk_unmap(assoc, 0); | ||
1214 | scatterwalk_done(&src_sg_walk, 0, 0); | ||
1215 | scatterwalk_done(&assoc_sg_walk, 0, 0); | ||
1216 | } else { | ||
1217 | scatterwalk_map_and_copy(dst, req->dst, 0, req->cryptlen, 1); | ||
1218 | kfree(src); | ||
1219 | } | ||
1220 | return retval; | ||
1221 | } | ||
1222 | |||
1223 | static struct crypto_alg __rfc4106_alg = { | ||
1224 | .cra_name = "__gcm-aes-aesni", | ||
1225 | .cra_driver_name = "__driver-gcm-aes-aesni", | ||
1226 | .cra_priority = 0, | ||
1227 | .cra_flags = CRYPTO_ALG_TYPE_AEAD, | ||
1228 | .cra_blocksize = 1, | ||
1229 | .cra_ctxsize = sizeof(struct aesni_rfc4106_gcm_ctx) + AESNI_ALIGN, | ||
1230 | .cra_alignmask = 0, | ||
1231 | .cra_type = &crypto_aead_type, | ||
1232 | .cra_module = THIS_MODULE, | ||
1233 | .cra_list = LIST_HEAD_INIT(__rfc4106_alg.cra_list), | ||
1234 | .cra_u = { | ||
1235 | .aead = { | ||
1236 | .encrypt = __driver_rfc4106_encrypt, | ||
1237 | .decrypt = __driver_rfc4106_decrypt, | ||
1238 | }, | ||
1239 | }, | ||
1240 | }; | ||
1241 | #endif | ||
1242 | |||
733 | static int __init aesni_init(void) | 1243 | static int __init aesni_init(void) |
734 | { | 1244 | { |
735 | int err; | 1245 | int err; |
@@ -738,6 +1248,7 @@ static int __init aesni_init(void) | |||
738 | printk(KERN_INFO "Intel AES-NI instructions are not detected.\n"); | 1248 | printk(KERN_INFO "Intel AES-NI instructions are not detected.\n"); |
739 | return -ENODEV; | 1249 | return -ENODEV; |
740 | } | 1250 | } |
1251 | |||
741 | if ((err = crypto_register_alg(&aesni_alg))) | 1252 | if ((err = crypto_register_alg(&aesni_alg))) |
742 | goto aes_err; | 1253 | goto aes_err; |
743 | if ((err = crypto_register_alg(&__aesni_alg))) | 1254 | if ((err = crypto_register_alg(&__aesni_alg))) |
@@ -746,18 +1257,24 @@ static int __init aesni_init(void) | |||
746 | goto blk_ecb_err; | 1257 | goto blk_ecb_err; |
747 | if ((err = crypto_register_alg(&blk_cbc_alg))) | 1258 | if ((err = crypto_register_alg(&blk_cbc_alg))) |
748 | goto blk_cbc_err; | 1259 | goto blk_cbc_err; |
749 | if ((err = crypto_register_alg(&blk_ctr_alg))) | ||
750 | goto blk_ctr_err; | ||
751 | if ((err = crypto_register_alg(&ablk_ecb_alg))) | 1260 | if ((err = crypto_register_alg(&ablk_ecb_alg))) |
752 | goto ablk_ecb_err; | 1261 | goto ablk_ecb_err; |
753 | if ((err = crypto_register_alg(&ablk_cbc_alg))) | 1262 | if ((err = crypto_register_alg(&ablk_cbc_alg))) |
754 | goto ablk_cbc_err; | 1263 | goto ablk_cbc_err; |
1264 | #ifdef CONFIG_X86_64 | ||
1265 | if ((err = crypto_register_alg(&blk_ctr_alg))) | ||
1266 | goto blk_ctr_err; | ||
755 | if ((err = crypto_register_alg(&ablk_ctr_alg))) | 1267 | if ((err = crypto_register_alg(&ablk_ctr_alg))) |
756 | goto ablk_ctr_err; | 1268 | goto ablk_ctr_err; |
1269 | if ((err = crypto_register_alg(&__rfc4106_alg))) | ||
1270 | goto __aead_gcm_err; | ||
1271 | if ((err = crypto_register_alg(&rfc4106_alg))) | ||
1272 | goto aead_gcm_err; | ||
757 | #ifdef HAS_CTR | 1273 | #ifdef HAS_CTR |
758 | if ((err = crypto_register_alg(&ablk_rfc3686_ctr_alg))) | 1274 | if ((err = crypto_register_alg(&ablk_rfc3686_ctr_alg))) |
759 | goto ablk_rfc3686_ctr_err; | 1275 | goto ablk_rfc3686_ctr_err; |
760 | #endif | 1276 | #endif |
1277 | #endif | ||
761 | #ifdef HAS_LRW | 1278 | #ifdef HAS_LRW |
762 | if ((err = crypto_register_alg(&ablk_lrw_alg))) | 1279 | if ((err = crypto_register_alg(&ablk_lrw_alg))) |
763 | goto ablk_lrw_err; | 1280 | goto ablk_lrw_err; |
@@ -770,7 +1287,6 @@ static int __init aesni_init(void) | |||
770 | if ((err = crypto_register_alg(&ablk_xts_alg))) | 1287 | if ((err = crypto_register_alg(&ablk_xts_alg))) |
771 | goto ablk_xts_err; | 1288 | goto ablk_xts_err; |
772 | #endif | 1289 | #endif |
773 | |||
774 | return err; | 1290 | return err; |
775 | 1291 | ||
776 | #ifdef HAS_XTS | 1292 | #ifdef HAS_XTS |
@@ -784,18 +1300,24 @@ ablk_pcbc_err: | |||
784 | crypto_unregister_alg(&ablk_lrw_alg); | 1300 | crypto_unregister_alg(&ablk_lrw_alg); |
785 | ablk_lrw_err: | 1301 | ablk_lrw_err: |
786 | #endif | 1302 | #endif |
1303 | #ifdef CONFIG_X86_64 | ||
787 | #ifdef HAS_CTR | 1304 | #ifdef HAS_CTR |
788 | crypto_unregister_alg(&ablk_rfc3686_ctr_alg); | 1305 | crypto_unregister_alg(&ablk_rfc3686_ctr_alg); |
789 | ablk_rfc3686_ctr_err: | 1306 | ablk_rfc3686_ctr_err: |
790 | #endif | 1307 | #endif |
1308 | crypto_unregister_alg(&rfc4106_alg); | ||
1309 | aead_gcm_err: | ||
1310 | crypto_unregister_alg(&__rfc4106_alg); | ||
1311 | __aead_gcm_err: | ||
791 | crypto_unregister_alg(&ablk_ctr_alg); | 1312 | crypto_unregister_alg(&ablk_ctr_alg); |
792 | ablk_ctr_err: | 1313 | ablk_ctr_err: |
1314 | crypto_unregister_alg(&blk_ctr_alg); | ||
1315 | blk_ctr_err: | ||
1316 | #endif | ||
793 | crypto_unregister_alg(&ablk_cbc_alg); | 1317 | crypto_unregister_alg(&ablk_cbc_alg); |
794 | ablk_cbc_err: | 1318 | ablk_cbc_err: |
795 | crypto_unregister_alg(&ablk_ecb_alg); | 1319 | crypto_unregister_alg(&ablk_ecb_alg); |
796 | ablk_ecb_err: | 1320 | ablk_ecb_err: |
797 | crypto_unregister_alg(&blk_ctr_alg); | ||
798 | blk_ctr_err: | ||
799 | crypto_unregister_alg(&blk_cbc_alg); | 1321 | crypto_unregister_alg(&blk_cbc_alg); |
800 | blk_cbc_err: | 1322 | blk_cbc_err: |
801 | crypto_unregister_alg(&blk_ecb_alg); | 1323 | crypto_unregister_alg(&blk_ecb_alg); |
@@ -818,13 +1340,17 @@ static void __exit aesni_exit(void) | |||
818 | #ifdef HAS_LRW | 1340 | #ifdef HAS_LRW |
819 | crypto_unregister_alg(&ablk_lrw_alg); | 1341 | crypto_unregister_alg(&ablk_lrw_alg); |
820 | #endif | 1342 | #endif |
1343 | #ifdef CONFIG_X86_64 | ||
821 | #ifdef HAS_CTR | 1344 | #ifdef HAS_CTR |
822 | crypto_unregister_alg(&ablk_rfc3686_ctr_alg); | 1345 | crypto_unregister_alg(&ablk_rfc3686_ctr_alg); |
823 | #endif | 1346 | #endif |
1347 | crypto_unregister_alg(&rfc4106_alg); | ||
1348 | crypto_unregister_alg(&__rfc4106_alg); | ||
824 | crypto_unregister_alg(&ablk_ctr_alg); | 1349 | crypto_unregister_alg(&ablk_ctr_alg); |
1350 | crypto_unregister_alg(&blk_ctr_alg); | ||
1351 | #endif | ||
825 | crypto_unregister_alg(&ablk_cbc_alg); | 1352 | crypto_unregister_alg(&ablk_cbc_alg); |
826 | crypto_unregister_alg(&ablk_ecb_alg); | 1353 | crypto_unregister_alg(&ablk_ecb_alg); |
827 | crypto_unregister_alg(&blk_ctr_alg); | ||
828 | crypto_unregister_alg(&blk_cbc_alg); | 1354 | crypto_unregister_alg(&blk_cbc_alg); |
829 | crypto_unregister_alg(&blk_ecb_alg); | 1355 | crypto_unregister_alg(&blk_ecb_alg); |
830 | crypto_unregister_alg(&__aesni_alg); | 1356 | crypto_unregister_alg(&__aesni_alg); |
diff --git a/arch/x86/include/asm/boot.h b/arch/x86/include/asm/boot.h index 3b62ab56c7a0..5e1a2eef3e7c 100644 --- a/arch/x86/include/asm/boot.h +++ b/arch/x86/include/asm/boot.h | |||
@@ -32,11 +32,7 @@ | |||
32 | #define BOOT_HEAP_SIZE 0x400000 | 32 | #define BOOT_HEAP_SIZE 0x400000 |
33 | #else /* !CONFIG_KERNEL_BZIP2 */ | 33 | #else /* !CONFIG_KERNEL_BZIP2 */ |
34 | 34 | ||
35 | #ifdef CONFIG_X86_64 | 35 | #define BOOT_HEAP_SIZE 0x8000 |
36 | #define BOOT_HEAP_SIZE 0x7000 | ||
37 | #else | ||
38 | #define BOOT_HEAP_SIZE 0x4000 | ||
39 | #endif | ||
40 | 36 | ||
41 | #endif /* !CONFIG_KERNEL_BZIP2 */ | 37 | #endif /* !CONFIG_KERNEL_BZIP2 */ |
42 | 38 | ||
diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h index ba870bb6dd8e..c704b38c57a2 100644 --- a/arch/x86/include/asm/irq.h +++ b/arch/x86/include/asm/irq.h | |||
@@ -10,6 +10,9 @@ | |||
10 | #include <asm/apicdef.h> | 10 | #include <asm/apicdef.h> |
11 | #include <asm/irq_vectors.h> | 11 | #include <asm/irq_vectors.h> |
12 | 12 | ||
13 | /* Even though we don't support this, supply it to appease OF */ | ||
14 | static inline void irq_dispose_mapping(unsigned int virq) { } | ||
15 | |||
13 | static inline int irq_canonicalize(int irq) | 16 | static inline int irq_canonicalize(int irq) |
14 | { | 17 | { |
15 | return ((irq == 2) ? 9 : irq); | 18 | return ((irq == 2) ? 9 : irq); |
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h index b36c6b3fe144..8e37deb1eb38 100644 --- a/arch/x86/include/asm/kvm_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h | |||
@@ -15,6 +15,14 @@ | |||
15 | 15 | ||
16 | struct x86_emulate_ctxt; | 16 | struct x86_emulate_ctxt; |
17 | 17 | ||
18 | struct x86_exception { | ||
19 | u8 vector; | ||
20 | bool error_code_valid; | ||
21 | u16 error_code; | ||
22 | bool nested_page_fault; | ||
23 | u64 address; /* cr2 or nested page fault gpa */ | ||
24 | }; | ||
25 | |||
18 | /* | 26 | /* |
19 | * x86_emulate_ops: | 27 | * x86_emulate_ops: |
20 | * | 28 | * |
@@ -64,7 +72,8 @@ struct x86_emulate_ops { | |||
64 | * @bytes: [IN ] Number of bytes to read from memory. | 72 | * @bytes: [IN ] Number of bytes to read from memory. |
65 | */ | 73 | */ |
66 | int (*read_std)(unsigned long addr, void *val, | 74 | int (*read_std)(unsigned long addr, void *val, |
67 | unsigned int bytes, struct kvm_vcpu *vcpu, u32 *error); | 75 | unsigned int bytes, struct kvm_vcpu *vcpu, |
76 | struct x86_exception *fault); | ||
68 | 77 | ||
69 | /* | 78 | /* |
70 | * write_std: Write bytes of standard (non-emulated/special) memory. | 79 | * write_std: Write bytes of standard (non-emulated/special) memory. |
@@ -74,7 +83,8 @@ struct x86_emulate_ops { | |||
74 | * @bytes: [IN ] Number of bytes to write to memory. | 83 | * @bytes: [IN ] Number of bytes to write to memory. |
75 | */ | 84 | */ |
76 | int (*write_std)(unsigned long addr, void *val, | 85 | int (*write_std)(unsigned long addr, void *val, |
77 | unsigned int bytes, struct kvm_vcpu *vcpu, u32 *error); | 86 | unsigned int bytes, struct kvm_vcpu *vcpu, |
87 | struct x86_exception *fault); | ||
78 | /* | 88 | /* |
79 | * fetch: Read bytes of standard (non-emulated/special) memory. | 89 | * fetch: Read bytes of standard (non-emulated/special) memory. |
80 | * Used for instruction fetch. | 90 | * Used for instruction fetch. |
@@ -83,7 +93,8 @@ struct x86_emulate_ops { | |||
83 | * @bytes: [IN ] Number of bytes to read from memory. | 93 | * @bytes: [IN ] Number of bytes to read from memory. |
84 | */ | 94 | */ |
85 | int (*fetch)(unsigned long addr, void *val, | 95 | int (*fetch)(unsigned long addr, void *val, |
86 | unsigned int bytes, struct kvm_vcpu *vcpu, u32 *error); | 96 | unsigned int bytes, struct kvm_vcpu *vcpu, |
97 | struct x86_exception *fault); | ||
87 | 98 | ||
88 | /* | 99 | /* |
89 | * read_emulated: Read bytes from emulated/special memory area. | 100 | * read_emulated: Read bytes from emulated/special memory area. |
@@ -94,7 +105,7 @@ struct x86_emulate_ops { | |||
94 | int (*read_emulated)(unsigned long addr, | 105 | int (*read_emulated)(unsigned long addr, |
95 | void *val, | 106 | void *val, |
96 | unsigned int bytes, | 107 | unsigned int bytes, |
97 | unsigned int *error, | 108 | struct x86_exception *fault, |
98 | struct kvm_vcpu *vcpu); | 109 | struct kvm_vcpu *vcpu); |
99 | 110 | ||
100 | /* | 111 | /* |
@@ -107,7 +118,7 @@ struct x86_emulate_ops { | |||
107 | int (*write_emulated)(unsigned long addr, | 118 | int (*write_emulated)(unsigned long addr, |
108 | const void *val, | 119 | const void *val, |
109 | unsigned int bytes, | 120 | unsigned int bytes, |
110 | unsigned int *error, | 121 | struct x86_exception *fault, |
111 | struct kvm_vcpu *vcpu); | 122 | struct kvm_vcpu *vcpu); |
112 | 123 | ||
113 | /* | 124 | /* |
@@ -122,7 +133,7 @@ struct x86_emulate_ops { | |||
122 | const void *old, | 133 | const void *old, |
123 | const void *new, | 134 | const void *new, |
124 | unsigned int bytes, | 135 | unsigned int bytes, |
125 | unsigned int *error, | 136 | struct x86_exception *fault, |
126 | struct kvm_vcpu *vcpu); | 137 | struct kvm_vcpu *vcpu); |
127 | 138 | ||
128 | int (*pio_in_emulated)(int size, unsigned short port, void *val, | 139 | int (*pio_in_emulated)(int size, unsigned short port, void *val, |
@@ -159,7 +170,10 @@ struct operand { | |||
159 | }; | 170 | }; |
160 | union { | 171 | union { |
161 | unsigned long *reg; | 172 | unsigned long *reg; |
162 | unsigned long mem; | 173 | struct segmented_address { |
174 | ulong ea; | ||
175 | unsigned seg; | ||
176 | } mem; | ||
163 | } addr; | 177 | } addr; |
164 | union { | 178 | union { |
165 | unsigned long val; | 179 | unsigned long val; |
@@ -226,9 +240,8 @@ struct x86_emulate_ctxt { | |||
226 | 240 | ||
227 | bool perm_ok; /* do not check permissions if true */ | 241 | bool perm_ok; /* do not check permissions if true */ |
228 | 242 | ||
229 | int exception; /* exception that happens during emulation or -1 */ | 243 | bool have_exception; |
230 | u32 error_code; /* error code for exception */ | 244 | struct x86_exception exception; |
231 | bool error_code_valid; | ||
232 | 245 | ||
233 | /* decode cache */ | 246 | /* decode cache */ |
234 | struct decode_cache decode; | 247 | struct decode_cache decode; |
@@ -252,7 +265,7 @@ struct x86_emulate_ctxt { | |||
252 | #define X86EMUL_MODE_HOST X86EMUL_MODE_PROT64 | 265 | #define X86EMUL_MODE_HOST X86EMUL_MODE_PROT64 |
253 | #endif | 266 | #endif |
254 | 267 | ||
255 | int x86_decode_insn(struct x86_emulate_ctxt *ctxt); | 268 | int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len); |
256 | #define EMULATION_FAILED -1 | 269 | #define EMULATION_FAILED -1 |
257 | #define EMULATION_OK 0 | 270 | #define EMULATION_OK 0 |
258 | #define EMULATION_RESTART 1 | 271 | #define EMULATION_RESTART 1 |
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index f702f82aa1eb..ffd7f8d29187 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
@@ -83,11 +83,14 @@ | |||
83 | #define KVM_NR_FIXED_MTRR_REGION 88 | 83 | #define KVM_NR_FIXED_MTRR_REGION 88 |
84 | #define KVM_NR_VAR_MTRR 8 | 84 | #define KVM_NR_VAR_MTRR 8 |
85 | 85 | ||
86 | #define ASYNC_PF_PER_VCPU 64 | ||
87 | |||
86 | extern spinlock_t kvm_lock; | 88 | extern spinlock_t kvm_lock; |
87 | extern struct list_head vm_list; | 89 | extern struct list_head vm_list; |
88 | 90 | ||
89 | struct kvm_vcpu; | 91 | struct kvm_vcpu; |
90 | struct kvm; | 92 | struct kvm; |
93 | struct kvm_async_pf; | ||
91 | 94 | ||
92 | enum kvm_reg { | 95 | enum kvm_reg { |
93 | VCPU_REGS_RAX = 0, | 96 | VCPU_REGS_RAX = 0, |
@@ -114,6 +117,7 @@ enum kvm_reg { | |||
114 | 117 | ||
115 | enum kvm_reg_ex { | 118 | enum kvm_reg_ex { |
116 | VCPU_EXREG_PDPTR = NR_VCPU_REGS, | 119 | VCPU_EXREG_PDPTR = NR_VCPU_REGS, |
120 | VCPU_EXREG_CR3, | ||
117 | }; | 121 | }; |
118 | 122 | ||
119 | enum { | 123 | enum { |
@@ -238,16 +242,18 @@ struct kvm_mmu { | |||
238 | void (*new_cr3)(struct kvm_vcpu *vcpu); | 242 | void (*new_cr3)(struct kvm_vcpu *vcpu); |
239 | void (*set_cr3)(struct kvm_vcpu *vcpu, unsigned long root); | 243 | void (*set_cr3)(struct kvm_vcpu *vcpu, unsigned long root); |
240 | unsigned long (*get_cr3)(struct kvm_vcpu *vcpu); | 244 | unsigned long (*get_cr3)(struct kvm_vcpu *vcpu); |
241 | int (*page_fault)(struct kvm_vcpu *vcpu, gva_t gva, u32 err); | 245 | int (*page_fault)(struct kvm_vcpu *vcpu, gva_t gva, u32 err, |
242 | void (*inject_page_fault)(struct kvm_vcpu *vcpu); | 246 | bool prefault); |
247 | void (*inject_page_fault)(struct kvm_vcpu *vcpu, | ||
248 | struct x86_exception *fault); | ||
243 | void (*free)(struct kvm_vcpu *vcpu); | 249 | void (*free)(struct kvm_vcpu *vcpu); |
244 | gpa_t (*gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t gva, u32 access, | 250 | gpa_t (*gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t gva, u32 access, |
245 | u32 *error); | 251 | struct x86_exception *exception); |
246 | gpa_t (*translate_gpa)(struct kvm_vcpu *vcpu, gpa_t gpa, u32 access); | 252 | gpa_t (*translate_gpa)(struct kvm_vcpu *vcpu, gpa_t gpa, u32 access); |
247 | void (*prefetch_page)(struct kvm_vcpu *vcpu, | 253 | void (*prefetch_page)(struct kvm_vcpu *vcpu, |
248 | struct kvm_mmu_page *page); | 254 | struct kvm_mmu_page *page); |
249 | int (*sync_page)(struct kvm_vcpu *vcpu, | 255 | int (*sync_page)(struct kvm_vcpu *vcpu, |
250 | struct kvm_mmu_page *sp, bool clear_unsync); | 256 | struct kvm_mmu_page *sp); |
251 | void (*invlpg)(struct kvm_vcpu *vcpu, gva_t gva); | 257 | void (*invlpg)(struct kvm_vcpu *vcpu, gva_t gva); |
252 | hpa_t root_hpa; | 258 | hpa_t root_hpa; |
253 | int root_level; | 259 | int root_level; |
@@ -315,16 +321,6 @@ struct kvm_vcpu_arch { | |||
315 | */ | 321 | */ |
316 | struct kvm_mmu *walk_mmu; | 322 | struct kvm_mmu *walk_mmu; |
317 | 323 | ||
318 | /* | ||
319 | * This struct is filled with the necessary information to propagate a | ||
320 | * page fault into the guest | ||
321 | */ | ||
322 | struct { | ||
323 | u64 address; | ||
324 | unsigned error_code; | ||
325 | bool nested; | ||
326 | } fault; | ||
327 | |||
328 | /* only needed in kvm_pv_mmu_op() path, but it's hot so | 324 | /* only needed in kvm_pv_mmu_op() path, but it's hot so |
329 | * put it here to avoid allocation */ | 325 | * put it here to avoid allocation */ |
330 | struct kvm_pv_mmu_op_buffer mmu_op_buffer; | 326 | struct kvm_pv_mmu_op_buffer mmu_op_buffer; |
@@ -412,6 +408,15 @@ struct kvm_vcpu_arch { | |||
412 | u64 hv_vapic; | 408 | u64 hv_vapic; |
413 | 409 | ||
414 | cpumask_var_t wbinvd_dirty_mask; | 410 | cpumask_var_t wbinvd_dirty_mask; |
411 | |||
412 | struct { | ||
413 | bool halted; | ||
414 | gfn_t gfns[roundup_pow_of_two(ASYNC_PF_PER_VCPU)]; | ||
415 | struct gfn_to_hva_cache data; | ||
416 | u64 msr_val; | ||
417 | u32 id; | ||
418 | bool send_user_only; | ||
419 | } apf; | ||
415 | }; | 420 | }; |
416 | 421 | ||
417 | struct kvm_arch { | 422 | struct kvm_arch { |
@@ -456,6 +461,10 @@ struct kvm_arch { | |||
456 | /* fields used by HYPER-V emulation */ | 461 | /* fields used by HYPER-V emulation */ |
457 | u64 hv_guest_os_id; | 462 | u64 hv_guest_os_id; |
458 | u64 hv_hypercall; | 463 | u64 hv_hypercall; |
464 | |||
465 | #ifdef CONFIG_KVM_MMU_AUDIT | ||
466 | int audit_point; | ||
467 | #endif | ||
459 | }; | 468 | }; |
460 | 469 | ||
461 | struct kvm_vm_stat { | 470 | struct kvm_vm_stat { |
@@ -529,6 +538,7 @@ struct kvm_x86_ops { | |||
529 | struct kvm_segment *var, int seg); | 538 | struct kvm_segment *var, int seg); |
530 | void (*get_cs_db_l_bits)(struct kvm_vcpu *vcpu, int *db, int *l); | 539 | void (*get_cs_db_l_bits)(struct kvm_vcpu *vcpu, int *db, int *l); |
531 | void (*decache_cr0_guest_bits)(struct kvm_vcpu *vcpu); | 540 | void (*decache_cr0_guest_bits)(struct kvm_vcpu *vcpu); |
541 | void (*decache_cr3)(struct kvm_vcpu *vcpu); | ||
532 | void (*decache_cr4_guest_bits)(struct kvm_vcpu *vcpu); | 542 | void (*decache_cr4_guest_bits)(struct kvm_vcpu *vcpu); |
533 | void (*set_cr0)(struct kvm_vcpu *vcpu, unsigned long cr0); | 543 | void (*set_cr0)(struct kvm_vcpu *vcpu, unsigned long cr0); |
534 | void (*set_cr3)(struct kvm_vcpu *vcpu, unsigned long cr3); | 544 | void (*set_cr3)(struct kvm_vcpu *vcpu, unsigned long cr3); |
@@ -582,9 +592,17 @@ struct kvm_x86_ops { | |||
582 | 592 | ||
583 | void (*write_tsc_offset)(struct kvm_vcpu *vcpu, u64 offset); | 593 | void (*write_tsc_offset)(struct kvm_vcpu *vcpu, u64 offset); |
584 | 594 | ||
595 | void (*get_exit_info)(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2); | ||
585 | const struct trace_print_flags *exit_reasons_str; | 596 | const struct trace_print_flags *exit_reasons_str; |
586 | }; | 597 | }; |
587 | 598 | ||
599 | struct kvm_arch_async_pf { | ||
600 | u32 token; | ||
601 | gfn_t gfn; | ||
602 | unsigned long cr3; | ||
603 | bool direct_map; | ||
604 | }; | ||
605 | |||
588 | extern struct kvm_x86_ops *kvm_x86_ops; | 606 | extern struct kvm_x86_ops *kvm_x86_ops; |
589 | 607 | ||
590 | int kvm_mmu_module_init(void); | 608 | int kvm_mmu_module_init(void); |
@@ -594,7 +612,6 @@ void kvm_mmu_destroy(struct kvm_vcpu *vcpu); | |||
594 | int kvm_mmu_create(struct kvm_vcpu *vcpu); | 612 | int kvm_mmu_create(struct kvm_vcpu *vcpu); |
595 | int kvm_mmu_setup(struct kvm_vcpu *vcpu); | 613 | int kvm_mmu_setup(struct kvm_vcpu *vcpu); |
596 | void kvm_mmu_set_nonpresent_ptes(u64 trap_pte, u64 notrap_pte); | 614 | void kvm_mmu_set_nonpresent_ptes(u64 trap_pte, u64 notrap_pte); |
597 | void kvm_mmu_set_base_ptes(u64 base_pte); | ||
598 | void kvm_mmu_set_mask_ptes(u64 user_mask, u64 accessed_mask, | 615 | void kvm_mmu_set_mask_ptes(u64 user_mask, u64 accessed_mask, |
599 | u64 dirty_mask, u64 nx_mask, u64 x_mask); | 616 | u64 dirty_mask, u64 nx_mask, u64 x_mask); |
600 | 617 | ||
@@ -623,8 +640,15 @@ enum emulation_result { | |||
623 | #define EMULTYPE_NO_DECODE (1 << 0) | 640 | #define EMULTYPE_NO_DECODE (1 << 0) |
624 | #define EMULTYPE_TRAP_UD (1 << 1) | 641 | #define EMULTYPE_TRAP_UD (1 << 1) |
625 | #define EMULTYPE_SKIP (1 << 2) | 642 | #define EMULTYPE_SKIP (1 << 2) |
626 | int emulate_instruction(struct kvm_vcpu *vcpu, | 643 | int x86_emulate_instruction(struct kvm_vcpu *vcpu, unsigned long cr2, |
627 | unsigned long cr2, u16 error_code, int emulation_type); | 644 | int emulation_type, void *insn, int insn_len); |
645 | |||
646 | static inline int emulate_instruction(struct kvm_vcpu *vcpu, | ||
647 | int emulation_type) | ||
648 | { | ||
649 | return x86_emulate_instruction(vcpu, 0, emulation_type, NULL, 0); | ||
650 | } | ||
651 | |||
628 | void realmode_lgdt(struct kvm_vcpu *vcpu, u16 size, unsigned long address); | 652 | void realmode_lgdt(struct kvm_vcpu *vcpu, u16 size, unsigned long address); |
629 | void realmode_lidt(struct kvm_vcpu *vcpu, u16 size, unsigned long address); | 653 | void realmode_lidt(struct kvm_vcpu *vcpu, u16 size, unsigned long address); |
630 | 654 | ||
@@ -650,7 +674,7 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason, | |||
650 | int kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0); | 674 | int kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0); |
651 | int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3); | 675 | int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3); |
652 | int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4); | 676 | int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4); |
653 | void kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8); | 677 | int kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8); |
654 | int kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val); | 678 | int kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val); |
655 | int kvm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *val); | 679 | int kvm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *val); |
656 | unsigned long kvm_get_cr8(struct kvm_vcpu *vcpu); | 680 | unsigned long kvm_get_cr8(struct kvm_vcpu *vcpu); |
@@ -668,11 +692,11 @@ void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr); | |||
668 | void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code); | 692 | void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code); |
669 | void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned nr); | 693 | void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned nr); |
670 | void kvm_requeue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code); | 694 | void kvm_requeue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code); |
671 | void kvm_inject_page_fault(struct kvm_vcpu *vcpu); | 695 | void kvm_inject_page_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault); |
672 | int kvm_read_guest_page_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, | 696 | int kvm_read_guest_page_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, |
673 | gfn_t gfn, void *data, int offset, int len, | 697 | gfn_t gfn, void *data, int offset, int len, |
674 | u32 access); | 698 | u32 access); |
675 | void kvm_propagate_fault(struct kvm_vcpu *vcpu); | 699 | void kvm_propagate_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault); |
676 | bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl); | 700 | bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl); |
677 | 701 | ||
678 | int kvm_pic_set_irq(void *opaque, int irq, int level); | 702 | int kvm_pic_set_irq(void *opaque, int irq, int level); |
@@ -690,16 +714,21 @@ void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu); | |||
690 | int kvm_mmu_load(struct kvm_vcpu *vcpu); | 714 | int kvm_mmu_load(struct kvm_vcpu *vcpu); |
691 | void kvm_mmu_unload(struct kvm_vcpu *vcpu); | 715 | void kvm_mmu_unload(struct kvm_vcpu *vcpu); |
692 | void kvm_mmu_sync_roots(struct kvm_vcpu *vcpu); | 716 | void kvm_mmu_sync_roots(struct kvm_vcpu *vcpu); |
693 | gpa_t kvm_mmu_gva_to_gpa_read(struct kvm_vcpu *vcpu, gva_t gva, u32 *error); | 717 | gpa_t kvm_mmu_gva_to_gpa_read(struct kvm_vcpu *vcpu, gva_t gva, |
694 | gpa_t kvm_mmu_gva_to_gpa_fetch(struct kvm_vcpu *vcpu, gva_t gva, u32 *error); | 718 | struct x86_exception *exception); |
695 | gpa_t kvm_mmu_gva_to_gpa_write(struct kvm_vcpu *vcpu, gva_t gva, u32 *error); | 719 | gpa_t kvm_mmu_gva_to_gpa_fetch(struct kvm_vcpu *vcpu, gva_t gva, |
696 | gpa_t kvm_mmu_gva_to_gpa_system(struct kvm_vcpu *vcpu, gva_t gva, u32 *error); | 720 | struct x86_exception *exception); |
721 | gpa_t kvm_mmu_gva_to_gpa_write(struct kvm_vcpu *vcpu, gva_t gva, | ||
722 | struct x86_exception *exception); | ||
723 | gpa_t kvm_mmu_gva_to_gpa_system(struct kvm_vcpu *vcpu, gva_t gva, | ||
724 | struct x86_exception *exception); | ||
697 | 725 | ||
698 | int kvm_emulate_hypercall(struct kvm_vcpu *vcpu); | 726 | int kvm_emulate_hypercall(struct kvm_vcpu *vcpu); |
699 | 727 | ||
700 | int kvm_fix_hypercall(struct kvm_vcpu *vcpu); | 728 | int kvm_fix_hypercall(struct kvm_vcpu *vcpu); |
701 | 729 | ||
702 | int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva, u32 error_code); | 730 | int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva, u32 error_code, |
731 | void *insn, int insn_len); | ||
703 | void kvm_mmu_invlpg(struct kvm_vcpu *vcpu, gva_t gva); | 732 | void kvm_mmu_invlpg(struct kvm_vcpu *vcpu, gva_t gva); |
704 | 733 | ||
705 | void kvm_enable_tdp(void); | 734 | void kvm_enable_tdp(void); |
@@ -766,20 +795,25 @@ enum { | |||
766 | #define HF_VINTR_MASK (1 << 2) | 795 | #define HF_VINTR_MASK (1 << 2) |
767 | #define HF_NMI_MASK (1 << 3) | 796 | #define HF_NMI_MASK (1 << 3) |
768 | #define HF_IRET_MASK (1 << 4) | 797 | #define HF_IRET_MASK (1 << 4) |
798 | #define HF_GUEST_MASK (1 << 5) /* VCPU is in guest-mode */ | ||
769 | 799 | ||
770 | /* | 800 | /* |
771 | * Hardware virtualization extension instructions may fault if a | 801 | * Hardware virtualization extension instructions may fault if a |
772 | * reboot turns off virtualization while processes are running. | 802 | * reboot turns off virtualization while processes are running. |
773 | * Trap the fault and ignore the instruction if that happens. | 803 | * Trap the fault and ignore the instruction if that happens. |
774 | */ | 804 | */ |
775 | asmlinkage void kvm_handle_fault_on_reboot(void); | 805 | asmlinkage void kvm_spurious_fault(void); |
806 | extern bool kvm_rebooting; | ||
776 | 807 | ||
777 | #define __kvm_handle_fault_on_reboot(insn) \ | 808 | #define __kvm_handle_fault_on_reboot(insn) \ |
778 | "666: " insn "\n\t" \ | 809 | "666: " insn "\n\t" \ |
810 | "668: \n\t" \ | ||
779 | ".pushsection .fixup, \"ax\" \n" \ | 811 | ".pushsection .fixup, \"ax\" \n" \ |
780 | "667: \n\t" \ | 812 | "667: \n\t" \ |
813 | "cmpb $0, kvm_rebooting \n\t" \ | ||
814 | "jne 668b \n\t" \ | ||
781 | __ASM_SIZE(push) " $666b \n\t" \ | 815 | __ASM_SIZE(push) " $666b \n\t" \ |
782 | "jmp kvm_handle_fault_on_reboot \n\t" \ | 816 | "call kvm_spurious_fault \n\t" \ |
783 | ".popsection \n\t" \ | 817 | ".popsection \n\t" \ |
784 | ".pushsection __ex_table, \"a\" \n\t" \ | 818 | ".pushsection __ex_table, \"a\" \n\t" \ |
785 | _ASM_PTR " 666b, 667b \n\t" \ | 819 | _ASM_PTR " 666b, 667b \n\t" \ |
@@ -788,6 +822,7 @@ asmlinkage void kvm_handle_fault_on_reboot(void); | |||
788 | #define KVM_ARCH_WANT_MMU_NOTIFIER | 822 | #define KVM_ARCH_WANT_MMU_NOTIFIER |
789 | int kvm_unmap_hva(struct kvm *kvm, unsigned long hva); | 823 | int kvm_unmap_hva(struct kvm *kvm, unsigned long hva); |
790 | int kvm_age_hva(struct kvm *kvm, unsigned long hva); | 824 | int kvm_age_hva(struct kvm *kvm, unsigned long hva); |
825 | int kvm_test_age_hva(struct kvm *kvm, unsigned long hva); | ||
791 | void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); | 826 | void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); |
792 | int cpuid_maxphyaddr(struct kvm_vcpu *vcpu); | 827 | int cpuid_maxphyaddr(struct kvm_vcpu *vcpu); |
793 | int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu); | 828 | int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu); |
@@ -799,4 +834,15 @@ void kvm_set_shared_msr(unsigned index, u64 val, u64 mask); | |||
799 | 834 | ||
800 | bool kvm_is_linear_rip(struct kvm_vcpu *vcpu, unsigned long linear_rip); | 835 | bool kvm_is_linear_rip(struct kvm_vcpu *vcpu, unsigned long linear_rip); |
801 | 836 | ||
837 | void kvm_arch_async_page_not_present(struct kvm_vcpu *vcpu, | ||
838 | struct kvm_async_pf *work); | ||
839 | void kvm_arch_async_page_present(struct kvm_vcpu *vcpu, | ||
840 | struct kvm_async_pf *work); | ||
841 | void kvm_arch_async_page_ready(struct kvm_vcpu *vcpu, | ||
842 | struct kvm_async_pf *work); | ||
843 | bool kvm_arch_can_inject_async_page_present(struct kvm_vcpu *vcpu); | ||
844 | extern bool kvm_find_async_pf_gfn(struct kvm_vcpu *vcpu, gfn_t gfn); | ||
845 | |||
846 | void kvm_complete_insn_gp(struct kvm_vcpu *vcpu, int err); | ||
847 | |||
802 | #endif /* _ASM_X86_KVM_HOST_H */ | 848 | #endif /* _ASM_X86_KVM_HOST_H */ |
diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h index 7b562b6184bc..a427bf77a93d 100644 --- a/arch/x86/include/asm/kvm_para.h +++ b/arch/x86/include/asm/kvm_para.h | |||
@@ -20,6 +20,7 @@ | |||
20 | * are available. The use of 0x11 and 0x12 is deprecated | 20 | * are available. The use of 0x11 and 0x12 is deprecated |
21 | */ | 21 | */ |
22 | #define KVM_FEATURE_CLOCKSOURCE2 3 | 22 | #define KVM_FEATURE_CLOCKSOURCE2 3 |
23 | #define KVM_FEATURE_ASYNC_PF 4 | ||
23 | 24 | ||
24 | /* The last 8 bits are used to indicate how to interpret the flags field | 25 | /* The last 8 bits are used to indicate how to interpret the flags field |
25 | * in pvclock structure. If no bits are set, all flags are ignored. | 26 | * in pvclock structure. If no bits are set, all flags are ignored. |
@@ -32,9 +33,13 @@ | |||
32 | /* Custom MSRs falls in the range 0x4b564d00-0x4b564dff */ | 33 | /* Custom MSRs falls in the range 0x4b564d00-0x4b564dff */ |
33 | #define MSR_KVM_WALL_CLOCK_NEW 0x4b564d00 | 34 | #define MSR_KVM_WALL_CLOCK_NEW 0x4b564d00 |
34 | #define MSR_KVM_SYSTEM_TIME_NEW 0x4b564d01 | 35 | #define MSR_KVM_SYSTEM_TIME_NEW 0x4b564d01 |
36 | #define MSR_KVM_ASYNC_PF_EN 0x4b564d02 | ||
35 | 37 | ||
36 | #define KVM_MAX_MMU_OP_BATCH 32 | 38 | #define KVM_MAX_MMU_OP_BATCH 32 |
37 | 39 | ||
40 | #define KVM_ASYNC_PF_ENABLED (1 << 0) | ||
41 | #define KVM_ASYNC_PF_SEND_ALWAYS (1 << 1) | ||
42 | |||
38 | /* Operations for KVM_HC_MMU_OP */ | 43 | /* Operations for KVM_HC_MMU_OP */ |
39 | #define KVM_MMU_OP_WRITE_PTE 1 | 44 | #define KVM_MMU_OP_WRITE_PTE 1 |
40 | #define KVM_MMU_OP_FLUSH_TLB 2 | 45 | #define KVM_MMU_OP_FLUSH_TLB 2 |
@@ -61,10 +66,20 @@ struct kvm_mmu_op_release_pt { | |||
61 | __u64 pt_phys; | 66 | __u64 pt_phys; |
62 | }; | 67 | }; |
63 | 68 | ||
69 | #define KVM_PV_REASON_PAGE_NOT_PRESENT 1 | ||
70 | #define KVM_PV_REASON_PAGE_READY 2 | ||
71 | |||
72 | struct kvm_vcpu_pv_apf_data { | ||
73 | __u32 reason; | ||
74 | __u8 pad[60]; | ||
75 | __u32 enabled; | ||
76 | }; | ||
77 | |||
64 | #ifdef __KERNEL__ | 78 | #ifdef __KERNEL__ |
65 | #include <asm/processor.h> | 79 | #include <asm/processor.h> |
66 | 80 | ||
67 | extern void kvmclock_init(void); | 81 | extern void kvmclock_init(void); |
82 | extern int kvm_register_clock(char *txt); | ||
68 | 83 | ||
69 | 84 | ||
70 | /* This instruction is vmcall. On non-VT architectures, it will generate a | 85 | /* This instruction is vmcall. On non-VT architectures, it will generate a |
@@ -160,8 +175,17 @@ static inline unsigned int kvm_arch_para_features(void) | |||
160 | 175 | ||
161 | #ifdef CONFIG_KVM_GUEST | 176 | #ifdef CONFIG_KVM_GUEST |
162 | void __init kvm_guest_init(void); | 177 | void __init kvm_guest_init(void); |
178 | void kvm_async_pf_task_wait(u32 token); | ||
179 | void kvm_async_pf_task_wake(u32 token); | ||
180 | u32 kvm_read_and_reset_pf_reason(void); | ||
163 | #else | 181 | #else |
164 | #define kvm_guest_init() do { } while (0) | 182 | #define kvm_guest_init() do { } while (0) |
183 | #define kvm_async_pf_task_wait(T) do {} while(0) | ||
184 | #define kvm_async_pf_task_wake(T) do {} while(0) | ||
185 | static inline u32 kvm_read_and_reset_pf_reason(void) | ||
186 | { | ||
187 | return 0; | ||
188 | } | ||
165 | #endif | 189 | #endif |
166 | 190 | ||
167 | #endif /* __KERNEL__ */ | 191 | #endif /* __KERNEL__ */ |
diff --git a/arch/x86/include/asm/olpc.h b/arch/x86/include/asm/olpc.h index 42a978c0c1b3..f482010350fb 100644 --- a/arch/x86/include/asm/olpc.h +++ b/arch/x86/include/asm/olpc.h | |||
@@ -107,10 +107,14 @@ extern int olpc_ec_mask_unset(uint8_t bits); | |||
107 | /* GPIO assignments */ | 107 | /* GPIO assignments */ |
108 | 108 | ||
109 | #define OLPC_GPIO_MIC_AC 1 | 109 | #define OLPC_GPIO_MIC_AC 1 |
110 | #define OLPC_GPIO_DCON_IRQ geode_gpio(7) | 110 | #define OLPC_GPIO_DCON_STAT0 5 |
111 | #define OLPC_GPIO_DCON_STAT1 6 | ||
112 | #define OLPC_GPIO_DCON_IRQ 7 | ||
111 | #define OLPC_GPIO_THRM_ALRM geode_gpio(10) | 113 | #define OLPC_GPIO_THRM_ALRM geode_gpio(10) |
112 | #define OLPC_GPIO_SMB_CLK geode_gpio(14) | 114 | #define OLPC_GPIO_DCON_LOAD 11 |
113 | #define OLPC_GPIO_SMB_DATA geode_gpio(15) | 115 | #define OLPC_GPIO_DCON_BLANK 12 |
116 | #define OLPC_GPIO_SMB_CLK 14 | ||
117 | #define OLPC_GPIO_SMB_DATA 15 | ||
114 | #define OLPC_GPIO_WORKAUX geode_gpio(24) | 118 | #define OLPC_GPIO_WORKAUX geode_gpio(24) |
115 | #define OLPC_GPIO_LID geode_gpio(26) | 119 | #define OLPC_GPIO_LID geode_gpio(26) |
116 | #define OLPC_GPIO_ECSCI geode_gpio(27) | 120 | #define OLPC_GPIO_ECSCI geode_gpio(27) |
diff --git a/arch/x86/include/asm/olpc_ofw.h b/arch/x86/include/asm/olpc_ofw.h index 2a8478140bb3..641988efe063 100644 --- a/arch/x86/include/asm/olpc_ofw.h +++ b/arch/x86/include/asm/olpc_ofw.h | |||
@@ -8,6 +8,8 @@ | |||
8 | 8 | ||
9 | #ifdef CONFIG_OLPC_OPENFIRMWARE | 9 | #ifdef CONFIG_OLPC_OPENFIRMWARE |
10 | 10 | ||
11 | extern bool olpc_ofw_is_installed(void); | ||
12 | |||
11 | /* run an OFW command by calling into the firmware */ | 13 | /* run an OFW command by calling into the firmware */ |
12 | #define olpc_ofw(name, args, res) \ | 14 | #define olpc_ofw(name, args, res) \ |
13 | __olpc_ofw((name), ARRAY_SIZE(args), args, ARRAY_SIZE(res), res) | 15 | __olpc_ofw((name), ARRAY_SIZE(args), args, ARRAY_SIZE(res), res) |
@@ -26,10 +28,17 @@ extern bool olpc_ofw_present(void); | |||
26 | 28 | ||
27 | #else /* !CONFIG_OLPC_OPENFIRMWARE */ | 29 | #else /* !CONFIG_OLPC_OPENFIRMWARE */ |
28 | 30 | ||
31 | static inline bool olpc_ofw_is_installed(void) { return false; } | ||
29 | static inline void olpc_ofw_detect(void) { } | 32 | static inline void olpc_ofw_detect(void) { } |
30 | static inline void setup_olpc_ofw_pgd(void) { } | 33 | static inline void setup_olpc_ofw_pgd(void) { } |
31 | static inline bool olpc_ofw_present(void) { return false; } | 34 | static inline bool olpc_ofw_present(void) { return false; } |
32 | 35 | ||
33 | #endif /* !CONFIG_OLPC_OPENFIRMWARE */ | 36 | #endif /* !CONFIG_OLPC_OPENFIRMWARE */ |
34 | 37 | ||
38 | #ifdef CONFIG_OLPC_OPENFIRMWARE_DT | ||
39 | extern void olpc_dt_build_devicetree(void); | ||
40 | #else | ||
41 | static inline void olpc_dt_build_devicetree(void) { } | ||
42 | #endif /* CONFIG_OLPC_OPENFIRMWARE_DT */ | ||
43 | |||
35 | #endif /* _ASM_X86_OLPC_OFW_H */ | 44 | #endif /* _ASM_X86_OLPC_OFW_H */ |
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index 7709c12431b8..2071a8b2b32f 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h | |||
@@ -435,6 +435,11 @@ static inline void pte_update(struct mm_struct *mm, unsigned long addr, | |||
435 | { | 435 | { |
436 | PVOP_VCALL3(pv_mmu_ops.pte_update, mm, addr, ptep); | 436 | PVOP_VCALL3(pv_mmu_ops.pte_update, mm, addr, ptep); |
437 | } | 437 | } |
438 | static inline void pmd_update(struct mm_struct *mm, unsigned long addr, | ||
439 | pmd_t *pmdp) | ||
440 | { | ||
441 | PVOP_VCALL3(pv_mmu_ops.pmd_update, mm, addr, pmdp); | ||
442 | } | ||
438 | 443 | ||
439 | static inline void pte_update_defer(struct mm_struct *mm, unsigned long addr, | 444 | static inline void pte_update_defer(struct mm_struct *mm, unsigned long addr, |
440 | pte_t *ptep) | 445 | pte_t *ptep) |
@@ -442,6 +447,12 @@ static inline void pte_update_defer(struct mm_struct *mm, unsigned long addr, | |||
442 | PVOP_VCALL3(pv_mmu_ops.pte_update_defer, mm, addr, ptep); | 447 | PVOP_VCALL3(pv_mmu_ops.pte_update_defer, mm, addr, ptep); |
443 | } | 448 | } |
444 | 449 | ||
450 | static inline void pmd_update_defer(struct mm_struct *mm, unsigned long addr, | ||
451 | pmd_t *pmdp) | ||
452 | { | ||
453 | PVOP_VCALL3(pv_mmu_ops.pmd_update_defer, mm, addr, pmdp); | ||
454 | } | ||
455 | |||
445 | static inline pte_t __pte(pteval_t val) | 456 | static inline pte_t __pte(pteval_t val) |
446 | { | 457 | { |
447 | pteval_t ret; | 458 | pteval_t ret; |
@@ -543,6 +554,20 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, | |||
543 | PVOP_VCALL4(pv_mmu_ops.set_pte_at, mm, addr, ptep, pte.pte); | 554 | PVOP_VCALL4(pv_mmu_ops.set_pte_at, mm, addr, ptep, pte.pte); |
544 | } | 555 | } |
545 | 556 | ||
557 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | ||
558 | static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr, | ||
559 | pmd_t *pmdp, pmd_t pmd) | ||
560 | { | ||
561 | #if PAGETABLE_LEVELS >= 3 | ||
562 | if (sizeof(pmdval_t) > sizeof(long)) | ||
563 | /* 5 arg words */ | ||
564 | pv_mmu_ops.set_pmd_at(mm, addr, pmdp, pmd); | ||
565 | else | ||
566 | PVOP_VCALL4(pv_mmu_ops.set_pmd_at, mm, addr, pmdp, pmd.pmd); | ||
567 | #endif | ||
568 | } | ||
569 | #endif | ||
570 | |||
546 | static inline void set_pmd(pmd_t *pmdp, pmd_t pmd) | 571 | static inline void set_pmd(pmd_t *pmdp, pmd_t pmd) |
547 | { | 572 | { |
548 | pmdval_t val = native_pmd_val(pmd); | 573 | pmdval_t val = native_pmd_val(pmd); |
diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h index b82bac975250..82885099c869 100644 --- a/arch/x86/include/asm/paravirt_types.h +++ b/arch/x86/include/asm/paravirt_types.h | |||
@@ -265,10 +265,16 @@ struct pv_mmu_ops { | |||
265 | void (*set_pte_at)(struct mm_struct *mm, unsigned long addr, | 265 | void (*set_pte_at)(struct mm_struct *mm, unsigned long addr, |
266 | pte_t *ptep, pte_t pteval); | 266 | pte_t *ptep, pte_t pteval); |
267 | void (*set_pmd)(pmd_t *pmdp, pmd_t pmdval); | 267 | void (*set_pmd)(pmd_t *pmdp, pmd_t pmdval); |
268 | void (*set_pmd_at)(struct mm_struct *mm, unsigned long addr, | ||
269 | pmd_t *pmdp, pmd_t pmdval); | ||
268 | void (*pte_update)(struct mm_struct *mm, unsigned long addr, | 270 | void (*pte_update)(struct mm_struct *mm, unsigned long addr, |
269 | pte_t *ptep); | 271 | pte_t *ptep); |
270 | void (*pte_update_defer)(struct mm_struct *mm, | 272 | void (*pte_update_defer)(struct mm_struct *mm, |
271 | unsigned long addr, pte_t *ptep); | 273 | unsigned long addr, pte_t *ptep); |
274 | void (*pmd_update)(struct mm_struct *mm, unsigned long addr, | ||
275 | pmd_t *pmdp); | ||
276 | void (*pmd_update_defer)(struct mm_struct *mm, | ||
277 | unsigned long addr, pmd_t *pmdp); | ||
272 | 278 | ||
273 | pte_t (*ptep_modify_prot_start)(struct mm_struct *mm, unsigned long addr, | 279 | pte_t (*ptep_modify_prot_start)(struct mm_struct *mm, unsigned long addr, |
274 | pte_t *ptep); | 280 | pte_t *ptep); |
diff --git a/arch/x86/include/asm/pgalloc.h b/arch/x86/include/asm/pgalloc.h index 271de94c3810..b4389a468fb6 100644 --- a/arch/x86/include/asm/pgalloc.h +++ b/arch/x86/include/asm/pgalloc.h | |||
@@ -92,7 +92,7 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) | |||
92 | extern void ___pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd); | 92 | extern void ___pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd); |
93 | 93 | ||
94 | static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd, | 94 | static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd, |
95 | unsigned long adddress) | 95 | unsigned long address) |
96 | { | 96 | { |
97 | ___pmd_free_tlb(tlb, pmd); | 97 | ___pmd_free_tlb(tlb, pmd); |
98 | } | 98 | } |
diff --git a/arch/x86/include/asm/pgtable-2level.h b/arch/x86/include/asm/pgtable-2level.h index 2334982b339e..98391db840c6 100644 --- a/arch/x86/include/asm/pgtable-2level.h +++ b/arch/x86/include/asm/pgtable-2level.h | |||
@@ -46,6 +46,15 @@ static inline pte_t native_ptep_get_and_clear(pte_t *xp) | |||
46 | #define native_ptep_get_and_clear(xp) native_local_ptep_get_and_clear(xp) | 46 | #define native_ptep_get_and_clear(xp) native_local_ptep_get_and_clear(xp) |
47 | #endif | 47 | #endif |
48 | 48 | ||
49 | #ifdef CONFIG_SMP | ||
50 | static inline pmd_t native_pmdp_get_and_clear(pmd_t *xp) | ||
51 | { | ||
52 | return __pmd(xchg((pmdval_t *)xp, 0)); | ||
53 | } | ||
54 | #else | ||
55 | #define native_pmdp_get_and_clear(xp) native_local_pmdp_get_and_clear(xp) | ||
56 | #endif | ||
57 | |||
49 | /* | 58 | /* |
50 | * Bits _PAGE_BIT_PRESENT, _PAGE_BIT_FILE and _PAGE_BIT_PROTNONE are taken, | 59 | * Bits _PAGE_BIT_PRESENT, _PAGE_BIT_FILE and _PAGE_BIT_PROTNONE are taken, |
51 | * split up the 29 bits of offset into this range: | 60 | * split up the 29 bits of offset into this range: |
diff --git a/arch/x86/include/asm/pgtable-3level.h b/arch/x86/include/asm/pgtable-3level.h index 177b0165ea01..94b979d1b58d 100644 --- a/arch/x86/include/asm/pgtable-3level.h +++ b/arch/x86/include/asm/pgtable-3level.h | |||
@@ -104,6 +104,29 @@ static inline pte_t native_ptep_get_and_clear(pte_t *ptep) | |||
104 | #define native_ptep_get_and_clear(xp) native_local_ptep_get_and_clear(xp) | 104 | #define native_ptep_get_and_clear(xp) native_local_ptep_get_and_clear(xp) |
105 | #endif | 105 | #endif |
106 | 106 | ||
107 | #ifdef CONFIG_SMP | ||
108 | union split_pmd { | ||
109 | struct { | ||
110 | u32 pmd_low; | ||
111 | u32 pmd_high; | ||
112 | }; | ||
113 | pmd_t pmd; | ||
114 | }; | ||
115 | static inline pmd_t native_pmdp_get_and_clear(pmd_t *pmdp) | ||
116 | { | ||
117 | union split_pmd res, *orig = (union split_pmd *)pmdp; | ||
118 | |||
119 | /* xchg acts as a barrier before setting of the high bits */ | ||
120 | res.pmd_low = xchg(&orig->pmd_low, 0); | ||
121 | res.pmd_high = orig->pmd_high; | ||
122 | orig->pmd_high = 0; | ||
123 | |||
124 | return res.pmd; | ||
125 | } | ||
126 | #else | ||
127 | #define native_pmdp_get_and_clear(xp) native_local_pmdp_get_and_clear(xp) | ||
128 | #endif | ||
129 | |||
107 | /* | 130 | /* |
108 | * Bits 0, 6 and 7 are taken in the low part of the pte, | 131 | * Bits 0, 6 and 7 are taken in the low part of the pte, |
109 | * put the 32 bits of offset into the high part. | 132 | * put the 32 bits of offset into the high part. |
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index ada823a13c7c..18601c86fab1 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h | |||
@@ -35,6 +35,7 @@ extern struct mm_struct *pgd_page_get_mm(struct page *page); | |||
35 | #else /* !CONFIG_PARAVIRT */ | 35 | #else /* !CONFIG_PARAVIRT */ |
36 | #define set_pte(ptep, pte) native_set_pte(ptep, pte) | 36 | #define set_pte(ptep, pte) native_set_pte(ptep, pte) |
37 | #define set_pte_at(mm, addr, ptep, pte) native_set_pte_at(mm, addr, ptep, pte) | 37 | #define set_pte_at(mm, addr, ptep, pte) native_set_pte_at(mm, addr, ptep, pte) |
38 | #define set_pmd_at(mm, addr, pmdp, pmd) native_set_pmd_at(mm, addr, pmdp, pmd) | ||
38 | 39 | ||
39 | #define set_pte_atomic(ptep, pte) \ | 40 | #define set_pte_atomic(ptep, pte) \ |
40 | native_set_pte_atomic(ptep, pte) | 41 | native_set_pte_atomic(ptep, pte) |
@@ -59,6 +60,8 @@ extern struct mm_struct *pgd_page_get_mm(struct page *page); | |||
59 | 60 | ||
60 | #define pte_update(mm, addr, ptep) do { } while (0) | 61 | #define pte_update(mm, addr, ptep) do { } while (0) |
61 | #define pte_update_defer(mm, addr, ptep) do { } while (0) | 62 | #define pte_update_defer(mm, addr, ptep) do { } while (0) |
63 | #define pmd_update(mm, addr, ptep) do { } while (0) | ||
64 | #define pmd_update_defer(mm, addr, ptep) do { } while (0) | ||
62 | 65 | ||
63 | #define pgd_val(x) native_pgd_val(x) | 66 | #define pgd_val(x) native_pgd_val(x) |
64 | #define __pgd(x) native_make_pgd(x) | 67 | #define __pgd(x) native_make_pgd(x) |
@@ -94,6 +97,11 @@ static inline int pte_young(pte_t pte) | |||
94 | return pte_flags(pte) & _PAGE_ACCESSED; | 97 | return pte_flags(pte) & _PAGE_ACCESSED; |
95 | } | 98 | } |
96 | 99 | ||
100 | static inline int pmd_young(pmd_t pmd) | ||
101 | { | ||
102 | return pmd_flags(pmd) & _PAGE_ACCESSED; | ||
103 | } | ||
104 | |||
97 | static inline int pte_write(pte_t pte) | 105 | static inline int pte_write(pte_t pte) |
98 | { | 106 | { |
99 | return pte_flags(pte) & _PAGE_RW; | 107 | return pte_flags(pte) & _PAGE_RW; |
@@ -142,6 +150,23 @@ static inline int pmd_large(pmd_t pte) | |||
142 | (_PAGE_PSE | _PAGE_PRESENT); | 150 | (_PAGE_PSE | _PAGE_PRESENT); |
143 | } | 151 | } |
144 | 152 | ||
153 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | ||
154 | static inline int pmd_trans_splitting(pmd_t pmd) | ||
155 | { | ||
156 | return pmd_val(pmd) & _PAGE_SPLITTING; | ||
157 | } | ||
158 | |||
159 | static inline int pmd_trans_huge(pmd_t pmd) | ||
160 | { | ||
161 | return pmd_val(pmd) & _PAGE_PSE; | ||
162 | } | ||
163 | |||
164 | static inline int has_transparent_hugepage(void) | ||
165 | { | ||
166 | return cpu_has_pse; | ||
167 | } | ||
168 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ | ||
169 | |||
145 | static inline pte_t pte_set_flags(pte_t pte, pteval_t set) | 170 | static inline pte_t pte_set_flags(pte_t pte, pteval_t set) |
146 | { | 171 | { |
147 | pteval_t v = native_pte_val(pte); | 172 | pteval_t v = native_pte_val(pte); |
@@ -216,6 +241,55 @@ static inline pte_t pte_mkspecial(pte_t pte) | |||
216 | return pte_set_flags(pte, _PAGE_SPECIAL); | 241 | return pte_set_flags(pte, _PAGE_SPECIAL); |
217 | } | 242 | } |
218 | 243 | ||
244 | static inline pmd_t pmd_set_flags(pmd_t pmd, pmdval_t set) | ||
245 | { | ||
246 | pmdval_t v = native_pmd_val(pmd); | ||
247 | |||
248 | return __pmd(v | set); | ||
249 | } | ||
250 | |||
251 | static inline pmd_t pmd_clear_flags(pmd_t pmd, pmdval_t clear) | ||
252 | { | ||
253 | pmdval_t v = native_pmd_val(pmd); | ||
254 | |||
255 | return __pmd(v & ~clear); | ||
256 | } | ||
257 | |||
258 | static inline pmd_t pmd_mkold(pmd_t pmd) | ||
259 | { | ||
260 | return pmd_clear_flags(pmd, _PAGE_ACCESSED); | ||
261 | } | ||
262 | |||
263 | static inline pmd_t pmd_wrprotect(pmd_t pmd) | ||
264 | { | ||
265 | return pmd_clear_flags(pmd, _PAGE_RW); | ||
266 | } | ||
267 | |||
268 | static inline pmd_t pmd_mkdirty(pmd_t pmd) | ||
269 | { | ||
270 | return pmd_set_flags(pmd, _PAGE_DIRTY); | ||
271 | } | ||
272 | |||
273 | static inline pmd_t pmd_mkhuge(pmd_t pmd) | ||
274 | { | ||
275 | return pmd_set_flags(pmd, _PAGE_PSE); | ||
276 | } | ||
277 | |||
278 | static inline pmd_t pmd_mkyoung(pmd_t pmd) | ||
279 | { | ||
280 | return pmd_set_flags(pmd, _PAGE_ACCESSED); | ||
281 | } | ||
282 | |||
283 | static inline pmd_t pmd_mkwrite(pmd_t pmd) | ||
284 | { | ||
285 | return pmd_set_flags(pmd, _PAGE_RW); | ||
286 | } | ||
287 | |||
288 | static inline pmd_t pmd_mknotpresent(pmd_t pmd) | ||
289 | { | ||
290 | return pmd_clear_flags(pmd, _PAGE_PRESENT); | ||
291 | } | ||
292 | |||
219 | /* | 293 | /* |
220 | * Mask out unsupported bits in a present pgprot. Non-present pgprots | 294 | * Mask out unsupported bits in a present pgprot. Non-present pgprots |
221 | * can use those bits for other purposes, so leave them be. | 295 | * can use those bits for other purposes, so leave them be. |
@@ -256,6 +330,16 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | |||
256 | return __pte(val); | 330 | return __pte(val); |
257 | } | 331 | } |
258 | 332 | ||
333 | static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) | ||
334 | { | ||
335 | pmdval_t val = pmd_val(pmd); | ||
336 | |||
337 | val &= _HPAGE_CHG_MASK; | ||
338 | val |= massage_pgprot(newprot) & ~_HPAGE_CHG_MASK; | ||
339 | |||
340 | return __pmd(val); | ||
341 | } | ||
342 | |||
259 | /* mprotect needs to preserve PAT bits when updating vm_page_prot */ | 343 | /* mprotect needs to preserve PAT bits when updating vm_page_prot */ |
260 | #define pgprot_modify pgprot_modify | 344 | #define pgprot_modify pgprot_modify |
261 | static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot) | 345 | static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot) |
@@ -350,7 +434,7 @@ static inline unsigned long pmd_page_vaddr(pmd_t pmd) | |||
350 | * Currently stuck as a macro due to indirect forward reference to | 434 | * Currently stuck as a macro due to indirect forward reference to |
351 | * linux/mmzone.h's __section_mem_map_addr() definition: | 435 | * linux/mmzone.h's __section_mem_map_addr() definition: |
352 | */ | 436 | */ |
353 | #define pmd_page(pmd) pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT) | 437 | #define pmd_page(pmd) pfn_to_page((pmd_val(pmd) & PTE_PFN_MASK) >> PAGE_SHIFT) |
354 | 438 | ||
355 | /* | 439 | /* |
356 | * the pmd page can be thought of an array like this: pmd_t[PTRS_PER_PMD] | 440 | * the pmd page can be thought of an array like this: pmd_t[PTRS_PER_PMD] |
@@ -524,12 +608,26 @@ static inline pte_t native_local_ptep_get_and_clear(pte_t *ptep) | |||
524 | return res; | 608 | return res; |
525 | } | 609 | } |
526 | 610 | ||
611 | static inline pmd_t native_local_pmdp_get_and_clear(pmd_t *pmdp) | ||
612 | { | ||
613 | pmd_t res = *pmdp; | ||
614 | |||
615 | native_pmd_clear(pmdp); | ||
616 | return res; | ||
617 | } | ||
618 | |||
527 | static inline void native_set_pte_at(struct mm_struct *mm, unsigned long addr, | 619 | static inline void native_set_pte_at(struct mm_struct *mm, unsigned long addr, |
528 | pte_t *ptep , pte_t pte) | 620 | pte_t *ptep , pte_t pte) |
529 | { | 621 | { |
530 | native_set_pte(ptep, pte); | 622 | native_set_pte(ptep, pte); |
531 | } | 623 | } |
532 | 624 | ||
625 | static inline void native_set_pmd_at(struct mm_struct *mm, unsigned long addr, | ||
626 | pmd_t *pmdp , pmd_t pmd) | ||
627 | { | ||
628 | native_set_pmd(pmdp, pmd); | ||
629 | } | ||
630 | |||
533 | #ifndef CONFIG_PARAVIRT | 631 | #ifndef CONFIG_PARAVIRT |
534 | /* | 632 | /* |
535 | * Rules for using pte_update - it must be called after any PTE update which | 633 | * Rules for using pte_update - it must be called after any PTE update which |
@@ -607,6 +705,49 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, | |||
607 | 705 | ||
608 | #define flush_tlb_fix_spurious_fault(vma, address) | 706 | #define flush_tlb_fix_spurious_fault(vma, address) |
609 | 707 | ||
708 | #define mk_pmd(page, pgprot) pfn_pmd(page_to_pfn(page), (pgprot)) | ||
709 | |||
710 | #define __HAVE_ARCH_PMDP_SET_ACCESS_FLAGS | ||
711 | extern int pmdp_set_access_flags(struct vm_area_struct *vma, | ||
712 | unsigned long address, pmd_t *pmdp, | ||
713 | pmd_t entry, int dirty); | ||
714 | |||
715 | #define __HAVE_ARCH_PMDP_TEST_AND_CLEAR_YOUNG | ||
716 | extern int pmdp_test_and_clear_young(struct vm_area_struct *vma, | ||
717 | unsigned long addr, pmd_t *pmdp); | ||
718 | |||
719 | #define __HAVE_ARCH_PMDP_CLEAR_YOUNG_FLUSH | ||
720 | extern int pmdp_clear_flush_young(struct vm_area_struct *vma, | ||
721 | unsigned long address, pmd_t *pmdp); | ||
722 | |||
723 | |||
724 | #define __HAVE_ARCH_PMDP_SPLITTING_FLUSH | ||
725 | extern void pmdp_splitting_flush(struct vm_area_struct *vma, | ||
726 | unsigned long addr, pmd_t *pmdp); | ||
727 | |||
728 | #define __HAVE_ARCH_PMD_WRITE | ||
729 | static inline int pmd_write(pmd_t pmd) | ||
730 | { | ||
731 | return pmd_flags(pmd) & _PAGE_RW; | ||
732 | } | ||
733 | |||
734 | #define __HAVE_ARCH_PMDP_GET_AND_CLEAR | ||
735 | static inline pmd_t pmdp_get_and_clear(struct mm_struct *mm, unsigned long addr, | ||
736 | pmd_t *pmdp) | ||
737 | { | ||
738 | pmd_t pmd = native_pmdp_get_and_clear(pmdp); | ||
739 | pmd_update(mm, addr, pmdp); | ||
740 | return pmd; | ||
741 | } | ||
742 | |||
743 | #define __HAVE_ARCH_PMDP_SET_WRPROTECT | ||
744 | static inline void pmdp_set_wrprotect(struct mm_struct *mm, | ||
745 | unsigned long addr, pmd_t *pmdp) | ||
746 | { | ||
747 | clear_bit(_PAGE_BIT_RW, (unsigned long *)pmdp); | ||
748 | pmd_update(mm, addr, pmdp); | ||
749 | } | ||
750 | |||
610 | /* | 751 | /* |
611 | * clone_pgd_range(pgd_t *dst, pgd_t *src, int count); | 752 | * clone_pgd_range(pgd_t *dst, pgd_t *src, int count); |
612 | * | 753 | * |
diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h index f86da20347f2..975f709e09ae 100644 --- a/arch/x86/include/asm/pgtable_64.h +++ b/arch/x86/include/asm/pgtable_64.h | |||
@@ -59,6 +59,16 @@ static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte) | |||
59 | native_set_pte(ptep, pte); | 59 | native_set_pte(ptep, pte); |
60 | } | 60 | } |
61 | 61 | ||
62 | static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd) | ||
63 | { | ||
64 | *pmdp = pmd; | ||
65 | } | ||
66 | |||
67 | static inline void native_pmd_clear(pmd_t *pmd) | ||
68 | { | ||
69 | native_set_pmd(pmd, native_make_pmd(0)); | ||
70 | } | ||
71 | |||
62 | static inline pte_t native_ptep_get_and_clear(pte_t *xp) | 72 | static inline pte_t native_ptep_get_and_clear(pte_t *xp) |
63 | { | 73 | { |
64 | #ifdef CONFIG_SMP | 74 | #ifdef CONFIG_SMP |
@@ -72,14 +82,17 @@ static inline pte_t native_ptep_get_and_clear(pte_t *xp) | |||
72 | #endif | 82 | #endif |
73 | } | 83 | } |
74 | 84 | ||
75 | static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd) | 85 | static inline pmd_t native_pmdp_get_and_clear(pmd_t *xp) |
76 | { | 86 | { |
77 | *pmdp = pmd; | 87 | #ifdef CONFIG_SMP |
78 | } | 88 | return native_make_pmd(xchg(&xp->pmd, 0)); |
79 | 89 | #else | |
80 | static inline void native_pmd_clear(pmd_t *pmd) | 90 | /* native_local_pmdp_get_and_clear, |
81 | { | 91 | but duplicated because of cyclic dependency */ |
82 | native_set_pmd(pmd, native_make_pmd(0)); | 92 | pmd_t ret = *xp; |
93 | native_pmd_clear(xp); | ||
94 | return ret; | ||
95 | #endif | ||
83 | } | 96 | } |
84 | 97 | ||
85 | static inline void native_set_pud(pud_t *pudp, pud_t pud) | 98 | static inline void native_set_pud(pud_t *pudp, pud_t pud) |
@@ -168,6 +181,7 @@ extern void cleanup_highmap(void); | |||
168 | #define kc_offset_to_vaddr(o) ((o) | ~__VIRTUAL_MASK) | 181 | #define kc_offset_to_vaddr(o) ((o) | ~__VIRTUAL_MASK) |
169 | 182 | ||
170 | #define __HAVE_ARCH_PTE_SAME | 183 | #define __HAVE_ARCH_PTE_SAME |
184 | |||
171 | #endif /* !__ASSEMBLY__ */ | 185 | #endif /* !__ASSEMBLY__ */ |
172 | 186 | ||
173 | #endif /* _ASM_X86_PGTABLE_64_H */ | 187 | #endif /* _ASM_X86_PGTABLE_64_H */ |
diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h index d1f4a760be23..7db7723d1f32 100644 --- a/arch/x86/include/asm/pgtable_types.h +++ b/arch/x86/include/asm/pgtable_types.h | |||
@@ -22,6 +22,7 @@ | |||
22 | #define _PAGE_BIT_PAT_LARGE 12 /* On 2MB or 1GB pages */ | 22 | #define _PAGE_BIT_PAT_LARGE 12 /* On 2MB or 1GB pages */ |
23 | #define _PAGE_BIT_SPECIAL _PAGE_BIT_UNUSED1 | 23 | #define _PAGE_BIT_SPECIAL _PAGE_BIT_UNUSED1 |
24 | #define _PAGE_BIT_CPA_TEST _PAGE_BIT_UNUSED1 | 24 | #define _PAGE_BIT_CPA_TEST _PAGE_BIT_UNUSED1 |
25 | #define _PAGE_BIT_SPLITTING _PAGE_BIT_UNUSED1 /* only valid on a PSE pmd */ | ||
25 | #define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */ | 26 | #define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */ |
26 | 27 | ||
27 | /* If _PAGE_BIT_PRESENT is clear, we use these: */ | 28 | /* If _PAGE_BIT_PRESENT is clear, we use these: */ |
@@ -45,6 +46,7 @@ | |||
45 | #define _PAGE_PAT_LARGE (_AT(pteval_t, 1) << _PAGE_BIT_PAT_LARGE) | 46 | #define _PAGE_PAT_LARGE (_AT(pteval_t, 1) << _PAGE_BIT_PAT_LARGE) |
46 | #define _PAGE_SPECIAL (_AT(pteval_t, 1) << _PAGE_BIT_SPECIAL) | 47 | #define _PAGE_SPECIAL (_AT(pteval_t, 1) << _PAGE_BIT_SPECIAL) |
47 | #define _PAGE_CPA_TEST (_AT(pteval_t, 1) << _PAGE_BIT_CPA_TEST) | 48 | #define _PAGE_CPA_TEST (_AT(pteval_t, 1) << _PAGE_BIT_CPA_TEST) |
49 | #define _PAGE_SPLITTING (_AT(pteval_t, 1) << _PAGE_BIT_SPLITTING) | ||
48 | #define __HAVE_ARCH_PTE_SPECIAL | 50 | #define __HAVE_ARCH_PTE_SPECIAL |
49 | 51 | ||
50 | #ifdef CONFIG_KMEMCHECK | 52 | #ifdef CONFIG_KMEMCHECK |
@@ -70,6 +72,7 @@ | |||
70 | /* Set of bits not changed in pte_modify */ | 72 | /* Set of bits not changed in pte_modify */ |
71 | #define _PAGE_CHG_MASK (PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT | \ | 73 | #define _PAGE_CHG_MASK (PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT | \ |
72 | _PAGE_SPECIAL | _PAGE_ACCESSED | _PAGE_DIRTY) | 74 | _PAGE_SPECIAL | _PAGE_ACCESSED | _PAGE_DIRTY) |
75 | #define _HPAGE_CHG_MASK (_PAGE_CHG_MASK | _PAGE_PSE) | ||
73 | 76 | ||
74 | #define _PAGE_CACHE_MASK (_PAGE_PCD | _PAGE_PWT) | 77 | #define _PAGE_CACHE_MASK (_PAGE_PCD | _PAGE_PWT) |
75 | #define _PAGE_CACHE_WB (0) | 78 | #define _PAGE_CACHE_WB (0) |
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index c6efecf85a6a..45636cefa186 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h | |||
@@ -761,10 +761,11 @@ extern void select_idle_routine(const struct cpuinfo_x86 *c); | |||
761 | extern void init_c1e_mask(void); | 761 | extern void init_c1e_mask(void); |
762 | 762 | ||
763 | extern unsigned long boot_option_idle_override; | 763 | extern unsigned long boot_option_idle_override; |
764 | extern unsigned long idle_halt; | ||
765 | extern unsigned long idle_nomwait; | ||
766 | extern bool c1e_detected; | 764 | extern bool c1e_detected; |
767 | 765 | ||
766 | enum idle_boot_override {IDLE_NO_OVERRIDE=0, IDLE_HALT, IDLE_NOMWAIT, | ||
767 | IDLE_POLL, IDLE_FORCE_MWAIT}; | ||
768 | |||
768 | extern void enable_sep_cpu(void); | 769 | extern void enable_sep_cpu(void); |
769 | extern int sysenter_setup(void); | 770 | extern int sysenter_setup(void); |
770 | 771 | ||
@@ -901,7 +902,7 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk); | |||
901 | /* | 902 | /* |
902 | * The below -8 is to reserve 8 bytes on top of the ring0 stack. | 903 | * The below -8 is to reserve 8 bytes on top of the ring0 stack. |
903 | * This is necessary to guarantee that the entire "struct pt_regs" | 904 | * This is necessary to guarantee that the entire "struct pt_regs" |
904 | * is accessable even if the CPU haven't stored the SS/ESP registers | 905 | * is accessible even if the CPU haven't stored the SS/ESP registers |
905 | * on the stack (interrupt gate does not save these registers | 906 | * on the stack (interrupt gate does not save these registers |
906 | * when switching to the same priv ring). | 907 | * when switching to the same priv ring). |
907 | * Therefore beware: accessing the ss/esp fields of the | 908 | * Therefore beware: accessing the ss/esp fields of the |
diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h new file mode 100644 index 000000000000..b4ec95f07518 --- /dev/null +++ b/arch/x86/include/asm/prom.h | |||
@@ -0,0 +1 @@ | |||
/* dummy prom.h; here to make linux/of.h's #includes happy */ | |||
diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h index 0e831059ac5a..f2b83bc7d784 100644 --- a/arch/x86/include/asm/svm.h +++ b/arch/x86/include/asm/svm.h | |||
@@ -47,14 +47,13 @@ enum { | |||
47 | INTERCEPT_MONITOR, | 47 | INTERCEPT_MONITOR, |
48 | INTERCEPT_MWAIT, | 48 | INTERCEPT_MWAIT, |
49 | INTERCEPT_MWAIT_COND, | 49 | INTERCEPT_MWAIT_COND, |
50 | INTERCEPT_XSETBV, | ||
50 | }; | 51 | }; |
51 | 52 | ||
52 | 53 | ||
53 | struct __attribute__ ((__packed__)) vmcb_control_area { | 54 | struct __attribute__ ((__packed__)) vmcb_control_area { |
54 | u16 intercept_cr_read; | 55 | u32 intercept_cr; |
55 | u16 intercept_cr_write; | 56 | u32 intercept_dr; |
56 | u16 intercept_dr_read; | ||
57 | u16 intercept_dr_write; | ||
58 | u32 intercept_exceptions; | 57 | u32 intercept_exceptions; |
59 | u64 intercept; | 58 | u64 intercept; |
60 | u8 reserved_1[42]; | 59 | u8 reserved_1[42]; |
@@ -81,14 +80,19 @@ struct __attribute__ ((__packed__)) vmcb_control_area { | |||
81 | u32 event_inj_err; | 80 | u32 event_inj_err; |
82 | u64 nested_cr3; | 81 | u64 nested_cr3; |
83 | u64 lbr_ctl; | 82 | u64 lbr_ctl; |
84 | u64 reserved_5; | 83 | u32 clean; |
84 | u32 reserved_5; | ||
85 | u64 next_rip; | 85 | u64 next_rip; |
86 | u8 reserved_6[816]; | 86 | u8 insn_len; |
87 | u8 insn_bytes[15]; | ||
88 | u8 reserved_6[800]; | ||
87 | }; | 89 | }; |
88 | 90 | ||
89 | 91 | ||
90 | #define TLB_CONTROL_DO_NOTHING 0 | 92 | #define TLB_CONTROL_DO_NOTHING 0 |
91 | #define TLB_CONTROL_FLUSH_ALL_ASID 1 | 93 | #define TLB_CONTROL_FLUSH_ALL_ASID 1 |
94 | #define TLB_CONTROL_FLUSH_ASID 3 | ||
95 | #define TLB_CONTROL_FLUSH_ASID_LOCAL 7 | ||
92 | 96 | ||
93 | #define V_TPR_MASK 0x0f | 97 | #define V_TPR_MASK 0x0f |
94 | 98 | ||
@@ -204,19 +208,31 @@ struct __attribute__ ((__packed__)) vmcb { | |||
204 | #define SVM_SELECTOR_READ_MASK SVM_SELECTOR_WRITE_MASK | 208 | #define SVM_SELECTOR_READ_MASK SVM_SELECTOR_WRITE_MASK |
205 | #define SVM_SELECTOR_CODE_MASK (1 << 3) | 209 | #define SVM_SELECTOR_CODE_MASK (1 << 3) |
206 | 210 | ||
207 | #define INTERCEPT_CR0_MASK 1 | 211 | #define INTERCEPT_CR0_READ 0 |
208 | #define INTERCEPT_CR3_MASK (1 << 3) | 212 | #define INTERCEPT_CR3_READ 3 |
209 | #define INTERCEPT_CR4_MASK (1 << 4) | 213 | #define INTERCEPT_CR4_READ 4 |
210 | #define INTERCEPT_CR8_MASK (1 << 8) | 214 | #define INTERCEPT_CR8_READ 8 |
211 | 215 | #define INTERCEPT_CR0_WRITE (16 + 0) | |
212 | #define INTERCEPT_DR0_MASK 1 | 216 | #define INTERCEPT_CR3_WRITE (16 + 3) |
213 | #define INTERCEPT_DR1_MASK (1 << 1) | 217 | #define INTERCEPT_CR4_WRITE (16 + 4) |
214 | #define INTERCEPT_DR2_MASK (1 << 2) | 218 | #define INTERCEPT_CR8_WRITE (16 + 8) |
215 | #define INTERCEPT_DR3_MASK (1 << 3) | 219 | |
216 | #define INTERCEPT_DR4_MASK (1 << 4) | 220 | #define INTERCEPT_DR0_READ 0 |
217 | #define INTERCEPT_DR5_MASK (1 << 5) | 221 | #define INTERCEPT_DR1_READ 1 |
218 | #define INTERCEPT_DR6_MASK (1 << 6) | 222 | #define INTERCEPT_DR2_READ 2 |
219 | #define INTERCEPT_DR7_MASK (1 << 7) | 223 | #define INTERCEPT_DR3_READ 3 |
224 | #define INTERCEPT_DR4_READ 4 | ||
225 | #define INTERCEPT_DR5_READ 5 | ||
226 | #define INTERCEPT_DR6_READ 6 | ||
227 | #define INTERCEPT_DR7_READ 7 | ||
228 | #define INTERCEPT_DR0_WRITE (16 + 0) | ||
229 | #define INTERCEPT_DR1_WRITE (16 + 1) | ||
230 | #define INTERCEPT_DR2_WRITE (16 + 2) | ||
231 | #define INTERCEPT_DR3_WRITE (16 + 3) | ||
232 | #define INTERCEPT_DR4_WRITE (16 + 4) | ||
233 | #define INTERCEPT_DR5_WRITE (16 + 5) | ||
234 | #define INTERCEPT_DR6_WRITE (16 + 6) | ||
235 | #define INTERCEPT_DR7_WRITE (16 + 7) | ||
220 | 236 | ||
221 | #define SVM_EVTINJ_VEC_MASK 0xff | 237 | #define SVM_EVTINJ_VEC_MASK 0xff |
222 | 238 | ||
@@ -246,6 +262,8 @@ struct __attribute__ ((__packed__)) vmcb { | |||
246 | #define SVM_EXITINFOSHIFT_TS_REASON_JMP 38 | 262 | #define SVM_EXITINFOSHIFT_TS_REASON_JMP 38 |
247 | #define SVM_EXITINFOSHIFT_TS_HAS_ERROR_CODE 44 | 263 | #define SVM_EXITINFOSHIFT_TS_HAS_ERROR_CODE 44 |
248 | 264 | ||
265 | #define SVM_EXITINFO_REG_MASK 0x0F | ||
266 | |||
249 | #define SVM_EXIT_READ_CR0 0x000 | 267 | #define SVM_EXIT_READ_CR0 0x000 |
250 | #define SVM_EXIT_READ_CR3 0x003 | 268 | #define SVM_EXIT_READ_CR3 0x003 |
251 | #define SVM_EXIT_READ_CR4 0x004 | 269 | #define SVM_EXIT_READ_CR4 0x004 |
@@ -316,6 +334,7 @@ struct __attribute__ ((__packed__)) vmcb { | |||
316 | #define SVM_EXIT_MONITOR 0x08a | 334 | #define SVM_EXIT_MONITOR 0x08a |
317 | #define SVM_EXIT_MWAIT 0x08b | 335 | #define SVM_EXIT_MWAIT 0x08b |
318 | #define SVM_EXIT_MWAIT_COND 0x08c | 336 | #define SVM_EXIT_MWAIT_COND 0x08c |
337 | #define SVM_EXIT_XSETBV 0x08d | ||
319 | #define SVM_EXIT_NPF 0x400 | 338 | #define SVM_EXIT_NPF 0x400 |
320 | 339 | ||
321 | #define SVM_EXIT_ERR -1 | 340 | #define SVM_EXIT_ERR -1 |
diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h index f66cda56781d..0310da67307f 100644 --- a/arch/x86/include/asm/traps.h +++ b/arch/x86/include/asm/traps.h | |||
@@ -30,6 +30,7 @@ asmlinkage void segment_not_present(void); | |||
30 | asmlinkage void stack_segment(void); | 30 | asmlinkage void stack_segment(void); |
31 | asmlinkage void general_protection(void); | 31 | asmlinkage void general_protection(void); |
32 | asmlinkage void page_fault(void); | 32 | asmlinkage void page_fault(void); |
33 | asmlinkage void async_page_fault(void); | ||
33 | asmlinkage void spurious_interrupt_bug(void); | 34 | asmlinkage void spurious_interrupt_bug(void); |
34 | asmlinkage void coprocessor_error(void); | 35 | asmlinkage void coprocessor_error(void); |
35 | asmlinkage void alignment_check(void); | 36 | asmlinkage void alignment_check(void); |
diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h index 9f0cbd987d50..84471b810460 100644 --- a/arch/x86/include/asm/vmx.h +++ b/arch/x86/include/asm/vmx.h | |||
@@ -66,15 +66,23 @@ | |||
66 | #define PIN_BASED_NMI_EXITING 0x00000008 | 66 | #define PIN_BASED_NMI_EXITING 0x00000008 |
67 | #define PIN_BASED_VIRTUAL_NMIS 0x00000020 | 67 | #define PIN_BASED_VIRTUAL_NMIS 0x00000020 |
68 | 68 | ||
69 | #define VM_EXIT_SAVE_DEBUG_CONTROLS 0x00000002 | ||
69 | #define VM_EXIT_HOST_ADDR_SPACE_SIZE 0x00000200 | 70 | #define VM_EXIT_HOST_ADDR_SPACE_SIZE 0x00000200 |
71 | #define VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL 0x00001000 | ||
70 | #define VM_EXIT_ACK_INTR_ON_EXIT 0x00008000 | 72 | #define VM_EXIT_ACK_INTR_ON_EXIT 0x00008000 |
71 | #define VM_EXIT_SAVE_IA32_PAT 0x00040000 | 73 | #define VM_EXIT_SAVE_IA32_PAT 0x00040000 |
72 | #define VM_EXIT_LOAD_IA32_PAT 0x00080000 | 74 | #define VM_EXIT_LOAD_IA32_PAT 0x00080000 |
75 | #define VM_EXIT_SAVE_IA32_EFER 0x00100000 | ||
76 | #define VM_EXIT_LOAD_IA32_EFER 0x00200000 | ||
77 | #define VM_EXIT_SAVE_VMX_PREEMPTION_TIMER 0x00400000 | ||
73 | 78 | ||
79 | #define VM_ENTRY_LOAD_DEBUG_CONTROLS 0x00000002 | ||
74 | #define VM_ENTRY_IA32E_MODE 0x00000200 | 80 | #define VM_ENTRY_IA32E_MODE 0x00000200 |
75 | #define VM_ENTRY_SMM 0x00000400 | 81 | #define VM_ENTRY_SMM 0x00000400 |
76 | #define VM_ENTRY_DEACT_DUAL_MONITOR 0x00000800 | 82 | #define VM_ENTRY_DEACT_DUAL_MONITOR 0x00000800 |
83 | #define VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL 0x00002000 | ||
77 | #define VM_ENTRY_LOAD_IA32_PAT 0x00004000 | 84 | #define VM_ENTRY_LOAD_IA32_PAT 0x00004000 |
85 | #define VM_ENTRY_LOAD_IA32_EFER 0x00008000 | ||
78 | 86 | ||
79 | /* VMCS Encodings */ | 87 | /* VMCS Encodings */ |
80 | enum vmcs_field { | 88 | enum vmcs_field { |
@@ -239,6 +247,7 @@ enum vmcs_field { | |||
239 | #define EXIT_REASON_TASK_SWITCH 9 | 247 | #define EXIT_REASON_TASK_SWITCH 9 |
240 | #define EXIT_REASON_CPUID 10 | 248 | #define EXIT_REASON_CPUID 10 |
241 | #define EXIT_REASON_HLT 12 | 249 | #define EXIT_REASON_HLT 12 |
250 | #define EXIT_REASON_INVD 13 | ||
242 | #define EXIT_REASON_INVLPG 14 | 251 | #define EXIT_REASON_INVLPG 14 |
243 | #define EXIT_REASON_RDPMC 15 | 252 | #define EXIT_REASON_RDPMC 15 |
244 | #define EXIT_REASON_RDTSC 16 | 253 | #define EXIT_REASON_RDTSC 16 |
@@ -296,6 +305,12 @@ enum vmcs_field { | |||
296 | #define GUEST_INTR_STATE_SMI 0x00000004 | 305 | #define GUEST_INTR_STATE_SMI 0x00000004 |
297 | #define GUEST_INTR_STATE_NMI 0x00000008 | 306 | #define GUEST_INTR_STATE_NMI 0x00000008 |
298 | 307 | ||
308 | /* GUEST_ACTIVITY_STATE flags */ | ||
309 | #define GUEST_ACTIVITY_ACTIVE 0 | ||
310 | #define GUEST_ACTIVITY_HLT 1 | ||
311 | #define GUEST_ACTIVITY_SHUTDOWN 2 | ||
312 | #define GUEST_ACTIVITY_WAIT_SIPI 3 | ||
313 | |||
299 | /* | 314 | /* |
300 | * Exit Qualifications for MOV for Control Register Access | 315 | * Exit Qualifications for MOV for Control Register Access |
301 | */ | 316 | */ |
diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h index 8760cc60a21c..f25bdf238a33 100644 --- a/arch/x86/include/asm/xen/page.h +++ b/arch/x86/include/asm/xen/page.h | |||
@@ -42,6 +42,11 @@ extern unsigned int machine_to_phys_order; | |||
42 | extern unsigned long get_phys_to_machine(unsigned long pfn); | 42 | extern unsigned long get_phys_to_machine(unsigned long pfn); |
43 | extern bool set_phys_to_machine(unsigned long pfn, unsigned long mfn); | 43 | extern bool set_phys_to_machine(unsigned long pfn, unsigned long mfn); |
44 | 44 | ||
45 | extern int m2p_add_override(unsigned long mfn, struct page *page); | ||
46 | extern int m2p_remove_override(struct page *page); | ||
47 | extern struct page *m2p_find_override(unsigned long mfn); | ||
48 | extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn); | ||
49 | |||
45 | static inline unsigned long pfn_to_mfn(unsigned long pfn) | 50 | static inline unsigned long pfn_to_mfn(unsigned long pfn) |
46 | { | 51 | { |
47 | unsigned long mfn; | 52 | unsigned long mfn; |
@@ -72,9 +77,6 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn) | |||
72 | if (xen_feature(XENFEAT_auto_translated_physmap)) | 77 | if (xen_feature(XENFEAT_auto_translated_physmap)) |
73 | return mfn; | 78 | return mfn; |
74 | 79 | ||
75 | if (unlikely((mfn >> machine_to_phys_order) != 0)) | ||
76 | return ~0; | ||
77 | |||
78 | pfn = 0; | 80 | pfn = 0; |
79 | /* | 81 | /* |
80 | * The array access can fail (e.g., device space beyond end of RAM). | 82 | * The array access can fail (e.g., device space beyond end of RAM). |
@@ -83,6 +85,14 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn) | |||
83 | */ | 85 | */ |
84 | __get_user(pfn, &machine_to_phys_mapping[mfn]); | 86 | __get_user(pfn, &machine_to_phys_mapping[mfn]); |
85 | 87 | ||
88 | /* | ||
89 | * If this appears to be a foreign mfn (because the pfn | ||
90 | * doesn't map back to the mfn), then check the local override | ||
91 | * table to see if there's a better pfn to use. | ||
92 | */ | ||
93 | if (get_phys_to_machine(pfn) != mfn) | ||
94 | pfn = m2p_find_override_pfn(mfn, pfn); | ||
95 | |||
86 | return pfn; | 96 | return pfn; |
87 | } | 97 | } |
88 | 98 | ||
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index ec881c6bfee0..b3a71137983a 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
@@ -509,6 +509,7 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) | |||
509 | 509 | ||
510 | return 0; | 510 | return 0; |
511 | } | 511 | } |
512 | EXPORT_SYMBOL_GPL(acpi_gsi_to_irq); | ||
512 | 513 | ||
513 | int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi) | 514 | int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi) |
514 | { | 515 | { |
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index d2fdb0826df2..57ca77787220 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c | |||
@@ -1086,7 +1086,7 @@ static int alloc_new_range(struct dma_ops_domain *dma_dom, | |||
1086 | 1086 | ||
1087 | dma_dom->aperture_size += APERTURE_RANGE_SIZE; | 1087 | dma_dom->aperture_size += APERTURE_RANGE_SIZE; |
1088 | 1088 | ||
1089 | /* Intialize the exclusion range if necessary */ | 1089 | /* Initialize the exclusion range if necessary */ |
1090 | for_each_iommu(iommu) { | 1090 | for_each_iommu(iommu) { |
1091 | if (iommu->exclusion_start && | 1091 | if (iommu->exclusion_start && |
1092 | iommu->exclusion_start >= dma_dom->aperture[index]->offset | 1092 | iommu->exclusion_start >= dma_dom->aperture[index]->offset |
@@ -1353,7 +1353,7 @@ static void dma_ops_domain_free(struct dma_ops_domain *dom) | |||
1353 | 1353 | ||
1354 | /* | 1354 | /* |
1355 | * Allocates a new protection domain usable for the dma_ops functions. | 1355 | * Allocates a new protection domain usable for the dma_ops functions. |
1356 | * It also intializes the page table and the address allocator data | 1356 | * It also initializes the page table and the address allocator data |
1357 | * structures required for the dma_ops interface | 1357 | * structures required for the dma_ops interface |
1358 | */ | 1358 | */ |
1359 | static struct dma_ops_domain *dma_ops_domain_alloc(void) | 1359 | static struct dma_ops_domain *dma_ops_domain_alloc(void) |
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c index d6fb146c0d8b..df20723a6a1b 100644 --- a/arch/x86/kernel/dumpstack.c +++ b/arch/x86/kernel/dumpstack.c | |||
@@ -234,6 +234,7 @@ unsigned __kprobes long oops_begin(void) | |||
234 | bust_spinlocks(1); | 234 | bust_spinlocks(1); |
235 | return flags; | 235 | return flags; |
236 | } | 236 | } |
237 | EXPORT_SYMBOL_GPL(oops_begin); | ||
237 | 238 | ||
238 | void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr) | 239 | void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr) |
239 | { | 240 | { |
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 0c2b7ef7a34d..294f26da0c0c 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/bootmem.h> | 14 | #include <linux/bootmem.h> |
15 | #include <linux/pfn.h> | 15 | #include <linux/pfn.h> |
16 | #include <linux/suspend.h> | 16 | #include <linux/suspend.h> |
17 | #include <linux/acpi.h> | ||
17 | #include <linux/firmware-map.h> | 18 | #include <linux/firmware-map.h> |
18 | #include <linux/memblock.h> | 19 | #include <linux/memblock.h> |
19 | 20 | ||
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 591e60104278..c8b4efad7ebb 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S | |||
@@ -1406,6 +1406,16 @@ ENTRY(general_protection) | |||
1406 | CFI_ENDPROC | 1406 | CFI_ENDPROC |
1407 | END(general_protection) | 1407 | END(general_protection) |
1408 | 1408 | ||
1409 | #ifdef CONFIG_KVM_GUEST | ||
1410 | ENTRY(async_page_fault) | ||
1411 | RING0_EC_FRAME | ||
1412 | pushl $do_async_page_fault | ||
1413 | CFI_ADJUST_CFA_OFFSET 4 | ||
1414 | jmp error_code | ||
1415 | CFI_ENDPROC | ||
1416 | END(apf_page_fault) | ||
1417 | #endif | ||
1418 | |||
1409 | /* | 1419 | /* |
1410 | * End of kprobes section | 1420 | * End of kprobes section |
1411 | */ | 1421 | */ |
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index d3b895f375d3..aed1ffbeb0c9 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
@@ -1329,6 +1329,9 @@ errorentry xen_stack_segment do_stack_segment | |||
1329 | #endif | 1329 | #endif |
1330 | errorentry general_protection do_general_protection | 1330 | errorentry general_protection do_general_protection |
1331 | errorentry page_fault do_page_fault | 1331 | errorentry page_fault do_page_fault |
1332 | #ifdef CONFIG_KVM_GUEST | ||
1333 | errorentry async_page_fault do_async_page_fault | ||
1334 | #endif | ||
1332 | #ifdef CONFIG_X86_MCE | 1335 | #ifdef CONFIG_X86_MCE |
1333 | paranoidzeroentry machine_check *machine_check_vector(%rip) | 1336 | paranoidzeroentry machine_check *machine_check_vector(%rip) |
1334 | #endif | 1337 | #endif |
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index 9f54b209c378..fc293dc8dc35 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S | |||
@@ -126,7 +126,7 @@ ENTRY(startup_32) | |||
126 | movsl | 126 | movsl |
127 | movl pa(boot_params) + NEW_CL_POINTER,%esi | 127 | movl pa(boot_params) + NEW_CL_POINTER,%esi |
128 | andl %esi,%esi | 128 | andl %esi,%esi |
129 | jz 1f # No comand line | 129 | jz 1f # No command line |
130 | movl $pa(boot_command_line),%edi | 130 | movl $pa(boot_command_line),%edi |
131 | movl $(COMMAND_LINE_SIZE/4),%ecx | 131 | movl $(COMMAND_LINE_SIZE/4),%ecx |
132 | rep | 132 | rep |
diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c index 58bb239a2fd7..e60c38cc0eed 100644 --- a/arch/x86/kernel/i387.c +++ b/arch/x86/kernel/i387.c | |||
@@ -169,6 +169,7 @@ int init_fpu(struct task_struct *tsk) | |||
169 | set_stopped_child_used_math(tsk); | 169 | set_stopped_child_used_math(tsk); |
170 | return 0; | 170 | return 0; |
171 | } | 171 | } |
172 | EXPORT_SYMBOL_GPL(init_fpu); | ||
172 | 173 | ||
173 | /* | 174 | /* |
174 | * The xstateregs_active() routine is the same as the fpregs_active() routine, | 175 | * The xstateregs_active() routine is the same as the fpregs_active() routine, |
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 3a43caa3beb7..52945da52a94 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <linux/cpu.h> | 4 | #include <linux/cpu.h> |
5 | #include <linux/interrupt.h> | 5 | #include <linux/interrupt.h> |
6 | #include <linux/kernel_stat.h> | 6 | #include <linux/kernel_stat.h> |
7 | #include <linux/of.h> | ||
7 | #include <linux/seq_file.h> | 8 | #include <linux/seq_file.h> |
8 | #include <linux/smp.h> | 9 | #include <linux/smp.h> |
9 | #include <linux/ftrace.h> | 10 | #include <linux/ftrace.h> |
@@ -275,6 +276,15 @@ void smp_x86_platform_ipi(struct pt_regs *regs) | |||
275 | 276 | ||
276 | EXPORT_SYMBOL_GPL(vector_used_by_percpu_irq); | 277 | EXPORT_SYMBOL_GPL(vector_used_by_percpu_irq); |
277 | 278 | ||
279 | #ifdef CONFIG_OF | ||
280 | unsigned int irq_create_of_mapping(struct device_node *controller, | ||
281 | const u32 *intspec, unsigned int intsize) | ||
282 | { | ||
283 | return intspec[0]; | ||
284 | } | ||
285 | EXPORT_SYMBOL_GPL(irq_create_of_mapping); | ||
286 | #endif | ||
287 | |||
278 | #ifdef CONFIG_HOTPLUG_CPU | 288 | #ifdef CONFIG_HOTPLUG_CPU |
279 | /* A cpu has been removed from cpu_online_mask. Reset irq affinities. */ | 289 | /* A cpu has been removed from cpu_online_mask. Reset irq affinities. */ |
280 | void fixup_irqs(void) | 290 | void fixup_irqs(void) |
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index 63b0ec8d3d4a..8dc44662394b 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c | |||
@@ -27,16 +27,37 @@ | |||
27 | #include <linux/mm.h> | 27 | #include <linux/mm.h> |
28 | #include <linux/highmem.h> | 28 | #include <linux/highmem.h> |
29 | #include <linux/hardirq.h> | 29 | #include <linux/hardirq.h> |
30 | #include <linux/notifier.h> | ||
31 | #include <linux/reboot.h> | ||
32 | #include <linux/hash.h> | ||
33 | #include <linux/sched.h> | ||
34 | #include <linux/slab.h> | ||
35 | #include <linux/kprobes.h> | ||
30 | #include <asm/timer.h> | 36 | #include <asm/timer.h> |
37 | #include <asm/cpu.h> | ||
38 | #include <asm/traps.h> | ||
39 | #include <asm/desc.h> | ||
40 | #include <asm/tlbflush.h> | ||
31 | 41 | ||
32 | #define MMU_QUEUE_SIZE 1024 | 42 | #define MMU_QUEUE_SIZE 1024 |
33 | 43 | ||
44 | static int kvmapf = 1; | ||
45 | |||
46 | static int parse_no_kvmapf(char *arg) | ||
47 | { | ||
48 | kvmapf = 0; | ||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | early_param("no-kvmapf", parse_no_kvmapf); | ||
53 | |||
34 | struct kvm_para_state { | 54 | struct kvm_para_state { |
35 | u8 mmu_queue[MMU_QUEUE_SIZE]; | 55 | u8 mmu_queue[MMU_QUEUE_SIZE]; |
36 | int mmu_queue_len; | 56 | int mmu_queue_len; |
37 | }; | 57 | }; |
38 | 58 | ||
39 | static DEFINE_PER_CPU(struct kvm_para_state, para_state); | 59 | static DEFINE_PER_CPU(struct kvm_para_state, para_state); |
60 | static DEFINE_PER_CPU(struct kvm_vcpu_pv_apf_data, apf_reason) __aligned(64); | ||
40 | 61 | ||
41 | static struct kvm_para_state *kvm_para_state(void) | 62 | static struct kvm_para_state *kvm_para_state(void) |
42 | { | 63 | { |
@@ -50,6 +71,195 @@ static void kvm_io_delay(void) | |||
50 | { | 71 | { |
51 | } | 72 | } |
52 | 73 | ||
74 | #define KVM_TASK_SLEEP_HASHBITS 8 | ||
75 | #define KVM_TASK_SLEEP_HASHSIZE (1<<KVM_TASK_SLEEP_HASHBITS) | ||
76 | |||
77 | struct kvm_task_sleep_node { | ||
78 | struct hlist_node link; | ||
79 | wait_queue_head_t wq; | ||
80 | u32 token; | ||
81 | int cpu; | ||
82 | bool halted; | ||
83 | struct mm_struct *mm; | ||
84 | }; | ||
85 | |||
86 | static struct kvm_task_sleep_head { | ||
87 | spinlock_t lock; | ||
88 | struct hlist_head list; | ||
89 | } async_pf_sleepers[KVM_TASK_SLEEP_HASHSIZE]; | ||
90 | |||
91 | static struct kvm_task_sleep_node *_find_apf_task(struct kvm_task_sleep_head *b, | ||
92 | u32 token) | ||
93 | { | ||
94 | struct hlist_node *p; | ||
95 | |||
96 | hlist_for_each(p, &b->list) { | ||
97 | struct kvm_task_sleep_node *n = | ||
98 | hlist_entry(p, typeof(*n), link); | ||
99 | if (n->token == token) | ||
100 | return n; | ||
101 | } | ||
102 | |||
103 | return NULL; | ||
104 | } | ||
105 | |||
106 | void kvm_async_pf_task_wait(u32 token) | ||
107 | { | ||
108 | u32 key = hash_32(token, KVM_TASK_SLEEP_HASHBITS); | ||
109 | struct kvm_task_sleep_head *b = &async_pf_sleepers[key]; | ||
110 | struct kvm_task_sleep_node n, *e; | ||
111 | DEFINE_WAIT(wait); | ||
112 | int cpu, idle; | ||
113 | |||
114 | cpu = get_cpu(); | ||
115 | idle = idle_cpu(cpu); | ||
116 | put_cpu(); | ||
117 | |||
118 | spin_lock(&b->lock); | ||
119 | e = _find_apf_task(b, token); | ||
120 | if (e) { | ||
121 | /* dummy entry exist -> wake up was delivered ahead of PF */ | ||
122 | hlist_del(&e->link); | ||
123 | kfree(e); | ||
124 | spin_unlock(&b->lock); | ||
125 | return; | ||
126 | } | ||
127 | |||
128 | n.token = token; | ||
129 | n.cpu = smp_processor_id(); | ||
130 | n.mm = current->active_mm; | ||
131 | n.halted = idle || preempt_count() > 1; | ||
132 | atomic_inc(&n.mm->mm_count); | ||
133 | init_waitqueue_head(&n.wq); | ||
134 | hlist_add_head(&n.link, &b->list); | ||
135 | spin_unlock(&b->lock); | ||
136 | |||
137 | for (;;) { | ||
138 | if (!n.halted) | ||
139 | prepare_to_wait(&n.wq, &wait, TASK_UNINTERRUPTIBLE); | ||
140 | if (hlist_unhashed(&n.link)) | ||
141 | break; | ||
142 | |||
143 | if (!n.halted) { | ||
144 | local_irq_enable(); | ||
145 | schedule(); | ||
146 | local_irq_disable(); | ||
147 | } else { | ||
148 | /* | ||
149 | * We cannot reschedule. So halt. | ||
150 | */ | ||
151 | native_safe_halt(); | ||
152 | local_irq_disable(); | ||
153 | } | ||
154 | } | ||
155 | if (!n.halted) | ||
156 | finish_wait(&n.wq, &wait); | ||
157 | |||
158 | return; | ||
159 | } | ||
160 | EXPORT_SYMBOL_GPL(kvm_async_pf_task_wait); | ||
161 | |||
162 | static void apf_task_wake_one(struct kvm_task_sleep_node *n) | ||
163 | { | ||
164 | hlist_del_init(&n->link); | ||
165 | if (!n->mm) | ||
166 | return; | ||
167 | mmdrop(n->mm); | ||
168 | if (n->halted) | ||
169 | smp_send_reschedule(n->cpu); | ||
170 | else if (waitqueue_active(&n->wq)) | ||
171 | wake_up(&n->wq); | ||
172 | } | ||
173 | |||
174 | static void apf_task_wake_all(void) | ||
175 | { | ||
176 | int i; | ||
177 | |||
178 | for (i = 0; i < KVM_TASK_SLEEP_HASHSIZE; i++) { | ||
179 | struct hlist_node *p, *next; | ||
180 | struct kvm_task_sleep_head *b = &async_pf_sleepers[i]; | ||
181 | spin_lock(&b->lock); | ||
182 | hlist_for_each_safe(p, next, &b->list) { | ||
183 | struct kvm_task_sleep_node *n = | ||
184 | hlist_entry(p, typeof(*n), link); | ||
185 | if (n->cpu == smp_processor_id()) | ||
186 | apf_task_wake_one(n); | ||
187 | } | ||
188 | spin_unlock(&b->lock); | ||
189 | } | ||
190 | } | ||
191 | |||
192 | void kvm_async_pf_task_wake(u32 token) | ||
193 | { | ||
194 | u32 key = hash_32(token, KVM_TASK_SLEEP_HASHBITS); | ||
195 | struct kvm_task_sleep_head *b = &async_pf_sleepers[key]; | ||
196 | struct kvm_task_sleep_node *n; | ||
197 | |||
198 | if (token == ~0) { | ||
199 | apf_task_wake_all(); | ||
200 | return; | ||
201 | } | ||
202 | |||
203 | again: | ||
204 | spin_lock(&b->lock); | ||
205 | n = _find_apf_task(b, token); | ||
206 | if (!n) { | ||
207 | /* | ||
208 | * async PF was not yet handled. | ||
209 | * Add dummy entry for the token. | ||
210 | */ | ||
211 | n = kmalloc(sizeof(*n), GFP_ATOMIC); | ||
212 | if (!n) { | ||
213 | /* | ||
214 | * Allocation failed! Busy wait while other cpu | ||
215 | * handles async PF. | ||
216 | */ | ||
217 | spin_unlock(&b->lock); | ||
218 | cpu_relax(); | ||
219 | goto again; | ||
220 | } | ||
221 | n->token = token; | ||
222 | n->cpu = smp_processor_id(); | ||
223 | n->mm = NULL; | ||
224 | init_waitqueue_head(&n->wq); | ||
225 | hlist_add_head(&n->link, &b->list); | ||
226 | } else | ||
227 | apf_task_wake_one(n); | ||
228 | spin_unlock(&b->lock); | ||
229 | return; | ||
230 | } | ||
231 | EXPORT_SYMBOL_GPL(kvm_async_pf_task_wake); | ||
232 | |||
233 | u32 kvm_read_and_reset_pf_reason(void) | ||
234 | { | ||
235 | u32 reason = 0; | ||
236 | |||
237 | if (__get_cpu_var(apf_reason).enabled) { | ||
238 | reason = __get_cpu_var(apf_reason).reason; | ||
239 | __get_cpu_var(apf_reason).reason = 0; | ||
240 | } | ||
241 | |||
242 | return reason; | ||
243 | } | ||
244 | EXPORT_SYMBOL_GPL(kvm_read_and_reset_pf_reason); | ||
245 | |||
246 | dotraplinkage void __kprobes | ||
247 | do_async_page_fault(struct pt_regs *regs, unsigned long error_code) | ||
248 | { | ||
249 | switch (kvm_read_and_reset_pf_reason()) { | ||
250 | default: | ||
251 | do_page_fault(regs, error_code); | ||
252 | break; | ||
253 | case KVM_PV_REASON_PAGE_NOT_PRESENT: | ||
254 | /* page is swapped out by the host. */ | ||
255 | kvm_async_pf_task_wait((u32)read_cr2()); | ||
256 | break; | ||
257 | case KVM_PV_REASON_PAGE_READY: | ||
258 | kvm_async_pf_task_wake((u32)read_cr2()); | ||
259 | break; | ||
260 | } | ||
261 | } | ||
262 | |||
53 | static void kvm_mmu_op(void *buffer, unsigned len) | 263 | static void kvm_mmu_op(void *buffer, unsigned len) |
54 | { | 264 | { |
55 | int r; | 265 | int r; |
@@ -231,10 +441,117 @@ static void __init paravirt_ops_setup(void) | |||
231 | #endif | 441 | #endif |
232 | } | 442 | } |
233 | 443 | ||
444 | void __cpuinit kvm_guest_cpu_init(void) | ||
445 | { | ||
446 | if (!kvm_para_available()) | ||
447 | return; | ||
448 | |||
449 | if (kvm_para_has_feature(KVM_FEATURE_ASYNC_PF) && kvmapf) { | ||
450 | u64 pa = __pa(&__get_cpu_var(apf_reason)); | ||
451 | |||
452 | #ifdef CONFIG_PREEMPT | ||
453 | pa |= KVM_ASYNC_PF_SEND_ALWAYS; | ||
454 | #endif | ||
455 | wrmsrl(MSR_KVM_ASYNC_PF_EN, pa | KVM_ASYNC_PF_ENABLED); | ||
456 | __get_cpu_var(apf_reason).enabled = 1; | ||
457 | printk(KERN_INFO"KVM setup async PF for cpu %d\n", | ||
458 | smp_processor_id()); | ||
459 | } | ||
460 | } | ||
461 | |||
462 | static void kvm_pv_disable_apf(void *unused) | ||
463 | { | ||
464 | if (!__get_cpu_var(apf_reason).enabled) | ||
465 | return; | ||
466 | |||
467 | wrmsrl(MSR_KVM_ASYNC_PF_EN, 0); | ||
468 | __get_cpu_var(apf_reason).enabled = 0; | ||
469 | |||
470 | printk(KERN_INFO"Unregister pv shared memory for cpu %d\n", | ||
471 | smp_processor_id()); | ||
472 | } | ||
473 | |||
474 | static int kvm_pv_reboot_notify(struct notifier_block *nb, | ||
475 | unsigned long code, void *unused) | ||
476 | { | ||
477 | if (code == SYS_RESTART) | ||
478 | on_each_cpu(kvm_pv_disable_apf, NULL, 1); | ||
479 | return NOTIFY_DONE; | ||
480 | } | ||
481 | |||
482 | static struct notifier_block kvm_pv_reboot_nb = { | ||
483 | .notifier_call = kvm_pv_reboot_notify, | ||
484 | }; | ||
485 | |||
486 | #ifdef CONFIG_SMP | ||
487 | static void __init kvm_smp_prepare_boot_cpu(void) | ||
488 | { | ||
489 | #ifdef CONFIG_KVM_CLOCK | ||
490 | WARN_ON(kvm_register_clock("primary cpu clock")); | ||
491 | #endif | ||
492 | kvm_guest_cpu_init(); | ||
493 | native_smp_prepare_boot_cpu(); | ||
494 | } | ||
495 | |||
496 | static void kvm_guest_cpu_online(void *dummy) | ||
497 | { | ||
498 | kvm_guest_cpu_init(); | ||
499 | } | ||
500 | |||
501 | static void kvm_guest_cpu_offline(void *dummy) | ||
502 | { | ||
503 | kvm_pv_disable_apf(NULL); | ||
504 | apf_task_wake_all(); | ||
505 | } | ||
506 | |||
507 | static int __cpuinit kvm_cpu_notify(struct notifier_block *self, | ||
508 | unsigned long action, void *hcpu) | ||
509 | { | ||
510 | int cpu = (unsigned long)hcpu; | ||
511 | switch (action) { | ||
512 | case CPU_ONLINE: | ||
513 | case CPU_DOWN_FAILED: | ||
514 | case CPU_ONLINE_FROZEN: | ||
515 | smp_call_function_single(cpu, kvm_guest_cpu_online, NULL, 0); | ||
516 | break; | ||
517 | case CPU_DOWN_PREPARE: | ||
518 | case CPU_DOWN_PREPARE_FROZEN: | ||
519 | smp_call_function_single(cpu, kvm_guest_cpu_offline, NULL, 1); | ||
520 | break; | ||
521 | default: | ||
522 | break; | ||
523 | } | ||
524 | return NOTIFY_OK; | ||
525 | } | ||
526 | |||
527 | static struct notifier_block __cpuinitdata kvm_cpu_notifier = { | ||
528 | .notifier_call = kvm_cpu_notify, | ||
529 | }; | ||
530 | #endif | ||
531 | |||
532 | static void __init kvm_apf_trap_init(void) | ||
533 | { | ||
534 | set_intr_gate(14, &async_page_fault); | ||
535 | } | ||
536 | |||
234 | void __init kvm_guest_init(void) | 537 | void __init kvm_guest_init(void) |
235 | { | 538 | { |
539 | int i; | ||
540 | |||
236 | if (!kvm_para_available()) | 541 | if (!kvm_para_available()) |
237 | return; | 542 | return; |
238 | 543 | ||
239 | paravirt_ops_setup(); | 544 | paravirt_ops_setup(); |
545 | register_reboot_notifier(&kvm_pv_reboot_nb); | ||
546 | for (i = 0; i < KVM_TASK_SLEEP_HASHSIZE; i++) | ||
547 | spin_lock_init(&async_pf_sleepers[i].lock); | ||
548 | if (kvm_para_has_feature(KVM_FEATURE_ASYNC_PF)) | ||
549 | x86_init.irqs.trap_init = kvm_apf_trap_init; | ||
550 | |||
551 | #ifdef CONFIG_SMP | ||
552 | smp_ops.smp_prepare_boot_cpu = kvm_smp_prepare_boot_cpu; | ||
553 | register_cpu_notifier(&kvm_cpu_notifier); | ||
554 | #else | ||
555 | kvm_guest_cpu_init(); | ||
556 | #endif | ||
240 | } | 557 | } |
diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c index ca43ce31a19c..f98d3eafe07a 100644 --- a/arch/x86/kernel/kvmclock.c +++ b/arch/x86/kernel/kvmclock.c | |||
@@ -125,7 +125,7 @@ static struct clocksource kvm_clock = { | |||
125 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 125 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
126 | }; | 126 | }; |
127 | 127 | ||
128 | static int kvm_register_clock(char *txt) | 128 | int kvm_register_clock(char *txt) |
129 | { | 129 | { |
130 | int cpu = smp_processor_id(); | 130 | int cpu = smp_processor_id(); |
131 | int low, high, ret; | 131 | int low, high, ret; |
@@ -152,14 +152,6 @@ static void __cpuinit kvm_setup_secondary_clock(void) | |||
152 | } | 152 | } |
153 | #endif | 153 | #endif |
154 | 154 | ||
155 | #ifdef CONFIG_SMP | ||
156 | static void __init kvm_smp_prepare_boot_cpu(void) | ||
157 | { | ||
158 | WARN_ON(kvm_register_clock("primary cpu clock")); | ||
159 | native_smp_prepare_boot_cpu(); | ||
160 | } | ||
161 | #endif | ||
162 | |||
163 | /* | 155 | /* |
164 | * After the clock is registered, the host will keep writing to the | 156 | * After the clock is registered, the host will keep writing to the |
165 | * registered memory location. If the guest happens to shutdown, this memory | 157 | * registered memory location. If the guest happens to shutdown, this memory |
@@ -206,9 +198,6 @@ void __init kvmclock_init(void) | |||
206 | x86_cpuinit.setup_percpu_clockev = | 198 | x86_cpuinit.setup_percpu_clockev = |
207 | kvm_setup_secondary_clock; | 199 | kvm_setup_secondary_clock; |
208 | #endif | 200 | #endif |
209 | #ifdef CONFIG_SMP | ||
210 | smp_ops.smp_prepare_boot_cpu = kvm_smp_prepare_boot_cpu; | ||
211 | #endif | ||
212 | machine_ops.shutdown = kvm_shutdown; | 201 | machine_ops.shutdown = kvm_shutdown; |
213 | #ifdef CONFIG_KEXEC | 202 | #ifdef CONFIG_KEXEC |
214 | machine_ops.crash_shutdown = kvm_crash_shutdown; | 203 | machine_ops.crash_shutdown = kvm_crash_shutdown; |
diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c index 8f2956091735..ab23f1ad4bf1 100644 --- a/arch/x86/kernel/module.c +++ b/arch/x86/kernel/module.c | |||
@@ -37,20 +37,11 @@ | |||
37 | 37 | ||
38 | void *module_alloc(unsigned long size) | 38 | void *module_alloc(unsigned long size) |
39 | { | 39 | { |
40 | struct vm_struct *area; | 40 | if (PAGE_ALIGN(size) > MODULES_LEN) |
41 | |||
42 | if (!size) | ||
43 | return NULL; | ||
44 | size = PAGE_ALIGN(size); | ||
45 | if (size > MODULES_LEN) | ||
46 | return NULL; | 41 | return NULL; |
47 | 42 | return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END, | |
48 | area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END); | 43 | GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC, |
49 | if (!area) | 44 | -1, __builtin_return_address(0)); |
50 | return NULL; | ||
51 | |||
52 | return __vmalloc_area(area, GFP_KERNEL | __GFP_HIGHMEM, | ||
53 | PAGE_KERNEL_EXEC); | ||
54 | } | 45 | } |
55 | 46 | ||
56 | /* Free memory returned from module_alloc */ | 47 | /* Free memory returned from module_alloc */ |
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index c5b250011fd4..869e1aeeb71b 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c | |||
@@ -421,8 +421,11 @@ struct pv_mmu_ops pv_mmu_ops = { | |||
421 | .set_pte = native_set_pte, | 421 | .set_pte = native_set_pte, |
422 | .set_pte_at = native_set_pte_at, | 422 | .set_pte_at = native_set_pte_at, |
423 | .set_pmd = native_set_pmd, | 423 | .set_pmd = native_set_pmd, |
424 | .set_pmd_at = native_set_pmd_at, | ||
424 | .pte_update = paravirt_nop, | 425 | .pte_update = paravirt_nop, |
425 | .pte_update_defer = paravirt_nop, | 426 | .pte_update_defer = paravirt_nop, |
427 | .pmd_update = paravirt_nop, | ||
428 | .pmd_update_defer = paravirt_nop, | ||
426 | 429 | ||
427 | .ptep_modify_prot_start = __ptep_modify_prot_start, | 430 | .ptep_modify_prot_start = __ptep_modify_prot_start, |
428 | .ptep_modify_prot_commit = __ptep_modify_prot_commit, | 431 | .ptep_modify_prot_commit = __ptep_modify_prot_commit, |
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 09c08a1c706f..d8286ed54ffa 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c | |||
@@ -22,11 +22,6 @@ | |||
22 | #include <asm/i387.h> | 22 | #include <asm/i387.h> |
23 | #include <asm/debugreg.h> | 23 | #include <asm/debugreg.h> |
24 | 24 | ||
25 | unsigned long idle_halt; | ||
26 | EXPORT_SYMBOL(idle_halt); | ||
27 | unsigned long idle_nomwait; | ||
28 | EXPORT_SYMBOL(idle_nomwait); | ||
29 | |||
30 | struct kmem_cache *task_xstate_cachep; | 25 | struct kmem_cache *task_xstate_cachep; |
31 | EXPORT_SYMBOL_GPL(task_xstate_cachep); | 26 | EXPORT_SYMBOL_GPL(task_xstate_cachep); |
32 | 27 | ||
@@ -327,7 +322,7 @@ long sys_execve(const char __user *name, | |||
327 | /* | 322 | /* |
328 | * Idle related variables and functions | 323 | * Idle related variables and functions |
329 | */ | 324 | */ |
330 | unsigned long boot_option_idle_override = 0; | 325 | unsigned long boot_option_idle_override = IDLE_NO_OVERRIDE; |
331 | EXPORT_SYMBOL(boot_option_idle_override); | 326 | EXPORT_SYMBOL(boot_option_idle_override); |
332 | 327 | ||
333 | /* | 328 | /* |
@@ -386,6 +381,8 @@ void default_idle(void) | |||
386 | else | 381 | else |
387 | local_irq_enable(); | 382 | local_irq_enable(); |
388 | current_thread_info()->status |= TS_POLLING; | 383 | current_thread_info()->status |= TS_POLLING; |
384 | trace_power_end(smp_processor_id()); | ||
385 | trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id()); | ||
389 | } else { | 386 | } else { |
390 | local_irq_enable(); | 387 | local_irq_enable(); |
391 | /* loop is done by the caller */ | 388 | /* loop is done by the caller */ |
@@ -443,8 +440,6 @@ EXPORT_SYMBOL_GPL(cpu_idle_wait); | |||
443 | */ | 440 | */ |
444 | void mwait_idle_with_hints(unsigned long ax, unsigned long cx) | 441 | void mwait_idle_with_hints(unsigned long ax, unsigned long cx) |
445 | { | 442 | { |
446 | trace_power_start(POWER_CSTATE, (ax>>4)+1, smp_processor_id()); | ||
447 | trace_cpu_idle((ax>>4)+1, smp_processor_id()); | ||
448 | if (!need_resched()) { | 443 | if (!need_resched()) { |
449 | if (cpu_has(__this_cpu_ptr(&cpu_info), X86_FEATURE_CLFLUSH_MONITOR)) | 444 | if (cpu_has(__this_cpu_ptr(&cpu_info), X86_FEATURE_CLFLUSH_MONITOR)) |
450 | clflush((void *)¤t_thread_info()->flags); | 445 | clflush((void *)¤t_thread_info()->flags); |
@@ -471,6 +466,8 @@ static void mwait_idle(void) | |||
471 | __sti_mwait(0, 0); | 466 | __sti_mwait(0, 0); |
472 | else | 467 | else |
473 | local_irq_enable(); | 468 | local_irq_enable(); |
469 | trace_power_end(smp_processor_id()); | ||
470 | trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id()); | ||
474 | } else | 471 | } else |
475 | local_irq_enable(); | 472 | local_irq_enable(); |
476 | } | 473 | } |
@@ -503,7 +500,6 @@ static void poll_idle(void) | |||
503 | * | 500 | * |
504 | * idle=mwait overrides this decision and forces the usage of mwait. | 501 | * idle=mwait overrides this decision and forces the usage of mwait. |
505 | */ | 502 | */ |
506 | static int __cpuinitdata force_mwait; | ||
507 | 503 | ||
508 | #define MWAIT_INFO 0x05 | 504 | #define MWAIT_INFO 0x05 |
509 | #define MWAIT_ECX_EXTENDED_INFO 0x01 | 505 | #define MWAIT_ECX_EXTENDED_INFO 0x01 |
@@ -513,7 +509,7 @@ static int __cpuinit mwait_usable(const struct cpuinfo_x86 *c) | |||
513 | { | 509 | { |
514 | u32 eax, ebx, ecx, edx; | 510 | u32 eax, ebx, ecx, edx; |
515 | 511 | ||
516 | if (force_mwait) | 512 | if (boot_option_idle_override == IDLE_FORCE_MWAIT) |
517 | return 1; | 513 | return 1; |
518 | 514 | ||
519 | if (c->cpuid_level < MWAIT_INFO) | 515 | if (c->cpuid_level < MWAIT_INFO) |
@@ -633,9 +629,10 @@ static int __init idle_setup(char *str) | |||
633 | if (!strcmp(str, "poll")) { | 629 | if (!strcmp(str, "poll")) { |
634 | printk("using polling idle threads.\n"); | 630 | printk("using polling idle threads.\n"); |
635 | pm_idle = poll_idle; | 631 | pm_idle = poll_idle; |
636 | } else if (!strcmp(str, "mwait")) | 632 | boot_option_idle_override = IDLE_POLL; |
637 | force_mwait = 1; | 633 | } else if (!strcmp(str, "mwait")) { |
638 | else if (!strcmp(str, "halt")) { | 634 | boot_option_idle_override = IDLE_FORCE_MWAIT; |
635 | } else if (!strcmp(str, "halt")) { | ||
639 | /* | 636 | /* |
640 | * When the boot option of idle=halt is added, halt is | 637 | * When the boot option of idle=halt is added, halt is |
641 | * forced to be used for CPU idle. In such case CPU C2/C3 | 638 | * forced to be used for CPU idle. In such case CPU C2/C3 |
@@ -644,8 +641,7 @@ static int __init idle_setup(char *str) | |||
644 | * the boot_option_idle_override. | 641 | * the boot_option_idle_override. |
645 | */ | 642 | */ |
646 | pm_idle = default_idle; | 643 | pm_idle = default_idle; |
647 | idle_halt = 1; | 644 | boot_option_idle_override = IDLE_HALT; |
648 | return 0; | ||
649 | } else if (!strcmp(str, "nomwait")) { | 645 | } else if (!strcmp(str, "nomwait")) { |
650 | /* | 646 | /* |
651 | * If the boot option of "idle=nomwait" is added, | 647 | * If the boot option of "idle=nomwait" is added, |
@@ -653,12 +649,10 @@ static int __init idle_setup(char *str) | |||
653 | * states. In such case it won't touch the variable | 649 | * states. In such case it won't touch the variable |
654 | * of boot_option_idle_override. | 650 | * of boot_option_idle_override. |
655 | */ | 651 | */ |
656 | idle_nomwait = 1; | 652 | boot_option_idle_override = IDLE_NOMWAIT; |
657 | return 0; | ||
658 | } else | 653 | } else |
659 | return -1; | 654 | return -1; |
660 | 655 | ||
661 | boot_option_idle_override = 1; | ||
662 | return 0; | 656 | return 0; |
663 | } | 657 | } |
664 | early_param("idle", idle_setup); | 658 | early_param("idle", idle_setup); |
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 4b9befa0e347..8d128783af47 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c | |||
@@ -57,8 +57,6 @@ | |||
57 | #include <asm/syscalls.h> | 57 | #include <asm/syscalls.h> |
58 | #include <asm/debugreg.h> | 58 | #include <asm/debugreg.h> |
59 | 59 | ||
60 | #include <trace/events/power.h> | ||
61 | |||
62 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); | 60 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); |
63 | 61 | ||
64 | /* | 62 | /* |
@@ -113,8 +111,6 @@ void cpu_idle(void) | |||
113 | stop_critical_timings(); | 111 | stop_critical_timings(); |
114 | pm_idle(); | 112 | pm_idle(); |
115 | start_critical_timings(); | 113 | start_critical_timings(); |
116 | trace_power_end(smp_processor_id()); | ||
117 | trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id()); | ||
118 | } | 114 | } |
119 | tick_nohz_restart_sched_tick(); | 115 | tick_nohz_restart_sched_tick(); |
120 | preempt_enable_no_resched(); | 116 | preempt_enable_no_resched(); |
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 4c818a738396..bd387e8f73b4 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
@@ -51,8 +51,6 @@ | |||
51 | #include <asm/syscalls.h> | 51 | #include <asm/syscalls.h> |
52 | #include <asm/debugreg.h> | 52 | #include <asm/debugreg.h> |
53 | 53 | ||
54 | #include <trace/events/power.h> | ||
55 | |||
56 | asmlinkage extern void ret_from_fork(void); | 54 | asmlinkage extern void ret_from_fork(void); |
57 | 55 | ||
58 | DEFINE_PER_CPU(unsigned long, old_rsp); | 56 | DEFINE_PER_CPU(unsigned long, old_rsp); |
@@ -141,10 +139,6 @@ void cpu_idle(void) | |||
141 | pm_idle(); | 139 | pm_idle(); |
142 | start_critical_timings(); | 140 | start_critical_timings(); |
143 | 141 | ||
144 | trace_power_end(smp_processor_id()); | ||
145 | trace_cpu_idle(PWR_EVENT_EXIT, | ||
146 | smp_processor_id()); | ||
147 | |||
148 | /* In many cases the interrupt that ended idle | 142 | /* In many cases the interrupt that ended idle |
149 | has already called exit_idle. But some idle | 143 | has already called exit_idle. But some idle |
150 | loops can be woken up without interrupt. */ | 144 | loops can be woken up without interrupt. */ |
diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c index 1cfbbfc3ae26..6f39cab052d5 100644 --- a/arch/x86/kernel/rtc.c +++ b/arch/x86/kernel/rtc.c | |||
@@ -76,7 +76,7 @@ int mach_set_rtc_mmss(unsigned long nowtime) | |||
76 | CMOS_WRITE(real_seconds, RTC_SECONDS); | 76 | CMOS_WRITE(real_seconds, RTC_SECONDS); |
77 | CMOS_WRITE(real_minutes, RTC_MINUTES); | 77 | CMOS_WRITE(real_minutes, RTC_MINUTES); |
78 | } else { | 78 | } else { |
79 | printk(KERN_WARNING | 79 | printk_once(KERN_NOTICE |
80 | "set_rtc_mmss: can't update from %d to %d\n", | 80 | "set_rtc_mmss: can't update from %d to %d\n", |
81 | cmos_minutes, real_minutes); | 81 | cmos_minutes, real_minutes); |
82 | retval = -1; | 82 | retval = -1; |
diff --git a/arch/x86/kernel/tboot.c b/arch/x86/kernel/tboot.c index c2f1b26141e2..998e972f3b1a 100644 --- a/arch/x86/kernel/tboot.c +++ b/arch/x86/kernel/tboot.c | |||
@@ -133,7 +133,7 @@ static int map_tboot_page(unsigned long vaddr, unsigned long pfn, | |||
133 | pmd = pmd_alloc(&tboot_mm, pud, vaddr); | 133 | pmd = pmd_alloc(&tboot_mm, pud, vaddr); |
134 | if (!pmd) | 134 | if (!pmd) |
135 | return -1; | 135 | return -1; |
136 | pte = pte_alloc_map(&tboot_mm, pmd, vaddr); | 136 | pte = pte_alloc_map(&tboot_mm, NULL, pmd, vaddr); |
137 | if (!pte) | 137 | if (!pte) |
138 | return -1; | 138 | return -1; |
139 | set_pte_at(&tboot_mm, vaddr, pte, pfn_pte(pfn, prot)); | 139 | set_pte_at(&tboot_mm, vaddr, pte, pfn_pte(pfn, prot)); |
diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c index 61fb98519622..863f8753ab0a 100644 --- a/arch/x86/kernel/vm86_32.c +++ b/arch/x86/kernel/vm86_32.c | |||
@@ -179,6 +179,7 @@ static void mark_screen_rdonly(struct mm_struct *mm) | |||
179 | if (pud_none_or_clear_bad(pud)) | 179 | if (pud_none_or_clear_bad(pud)) |
180 | goto out; | 180 | goto out; |
181 | pmd = pmd_offset(pud, 0xA0000); | 181 | pmd = pmd_offset(pud, 0xA0000); |
182 | split_huge_page_pmd(mm, pmd); | ||
182 | if (pmd_none_or_clear_bad(pmd)) | 183 | if (pmd_none_or_clear_bad(pmd)) |
183 | goto out; | 184 | goto out; |
184 | pte = pte_offset_map_lock(mm, pmd, 0xA0000, &ptl); | 185 | pte = pte_offset_map_lock(mm, pmd, 0xA0000, &ptl); |
diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig index ddc131ff438f..50f63648ce1b 100644 --- a/arch/x86/kvm/Kconfig +++ b/arch/x86/kvm/Kconfig | |||
@@ -28,6 +28,7 @@ config KVM | |||
28 | select HAVE_KVM_IRQCHIP | 28 | select HAVE_KVM_IRQCHIP |
29 | select HAVE_KVM_EVENTFD | 29 | select HAVE_KVM_EVENTFD |
30 | select KVM_APIC_ARCHITECTURE | 30 | select KVM_APIC_ARCHITECTURE |
31 | select KVM_ASYNC_PF | ||
31 | select USER_RETURN_NOTIFIER | 32 | select USER_RETURN_NOTIFIER |
32 | select KVM_MMIO | 33 | select KVM_MMIO |
33 | ---help--- | 34 | ---help--- |
diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile index 31a7035c4bd9..f15501f431c8 100644 --- a/arch/x86/kvm/Makefile +++ b/arch/x86/kvm/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | 1 | ||
2 | EXTRA_CFLAGS += -Ivirt/kvm -Iarch/x86/kvm | 2 | ccflags-y += -Ivirt/kvm -Iarch/x86/kvm |
3 | 3 | ||
4 | CFLAGS_x86.o := -I. | 4 | CFLAGS_x86.o := -I. |
5 | CFLAGS_svm.o := -I. | 5 | CFLAGS_svm.o := -I. |
@@ -9,6 +9,7 @@ kvm-y += $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \ | |||
9 | coalesced_mmio.o irq_comm.o eventfd.o \ | 9 | coalesced_mmio.o irq_comm.o eventfd.o \ |
10 | assigned-dev.o) | 10 | assigned-dev.o) |
11 | kvm-$(CONFIG_IOMMU_API) += $(addprefix ../../../virt/kvm/, iommu.o) | 11 | kvm-$(CONFIG_IOMMU_API) += $(addprefix ../../../virt/kvm/, iommu.o) |
12 | kvm-$(CONFIG_KVM_ASYNC_PF) += $(addprefix ../../../virt/kvm/, async_pf.o) | ||
12 | 13 | ||
13 | kvm-y += x86.o mmu.o emulate.o i8259.o irq.o lapic.o \ | 14 | kvm-y += x86.o mmu.o emulate.o i8259.o irq.o lapic.o \ |
14 | i8254.o timer.o | 15 | i8254.o timer.o |
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 38b6e8dafaff..caf966781d25 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -20,16 +20,8 @@ | |||
20 | * From: xen-unstable 10676:af9809f51f81a3c43f276f00c81a52ef558afda4 | 20 | * From: xen-unstable 10676:af9809f51f81a3c43f276f00c81a52ef558afda4 |
21 | */ | 21 | */ |
22 | 22 | ||
23 | #ifndef __KERNEL__ | ||
24 | #include <stdio.h> | ||
25 | #include <stdint.h> | ||
26 | #include <public/xen.h> | ||
27 | #define DPRINTF(_f, _a ...) printf(_f , ## _a) | ||
28 | #else | ||
29 | #include <linux/kvm_host.h> | 23 | #include <linux/kvm_host.h> |
30 | #include "kvm_cache_regs.h" | 24 | #include "kvm_cache_regs.h" |
31 | #define DPRINTF(x...) do {} while (0) | ||
32 | #endif | ||
33 | #include <linux/module.h> | 25 | #include <linux/module.h> |
34 | #include <asm/kvm_emulate.h> | 26 | #include <asm/kvm_emulate.h> |
35 | 27 | ||
@@ -418,9 +410,9 @@ address_mask(struct decode_cache *c, unsigned long reg) | |||
418 | } | 410 | } |
419 | 411 | ||
420 | static inline unsigned long | 412 | static inline unsigned long |
421 | register_address(struct decode_cache *c, unsigned long base, unsigned long reg) | 413 | register_address(struct decode_cache *c, unsigned long reg) |
422 | { | 414 | { |
423 | return base + address_mask(c, reg); | 415 | return address_mask(c, reg); |
424 | } | 416 | } |
425 | 417 | ||
426 | static inline void | 418 | static inline void |
@@ -452,60 +444,55 @@ static unsigned long seg_base(struct x86_emulate_ctxt *ctxt, | |||
452 | return ops->get_cached_segment_base(seg, ctxt->vcpu); | 444 | return ops->get_cached_segment_base(seg, ctxt->vcpu); |
453 | } | 445 | } |
454 | 446 | ||
455 | static unsigned long seg_override_base(struct x86_emulate_ctxt *ctxt, | 447 | static unsigned seg_override(struct x86_emulate_ctxt *ctxt, |
456 | struct x86_emulate_ops *ops, | 448 | struct x86_emulate_ops *ops, |
457 | struct decode_cache *c) | 449 | struct decode_cache *c) |
458 | { | 450 | { |
459 | if (!c->has_seg_override) | 451 | if (!c->has_seg_override) |
460 | return 0; | 452 | return 0; |
461 | 453 | ||
462 | return seg_base(ctxt, ops, c->seg_override); | 454 | return c->seg_override; |
463 | } | 455 | } |
464 | 456 | ||
465 | static unsigned long es_base(struct x86_emulate_ctxt *ctxt, | 457 | static ulong linear(struct x86_emulate_ctxt *ctxt, |
466 | struct x86_emulate_ops *ops) | 458 | struct segmented_address addr) |
467 | { | 459 | { |
468 | return seg_base(ctxt, ops, VCPU_SREG_ES); | 460 | struct decode_cache *c = &ctxt->decode; |
469 | } | 461 | ulong la; |
470 | |||
471 | static unsigned long ss_base(struct x86_emulate_ctxt *ctxt, | ||
472 | struct x86_emulate_ops *ops) | ||
473 | { | ||
474 | return seg_base(ctxt, ops, VCPU_SREG_SS); | ||
475 | } | ||
476 | 462 | ||
477 | static void emulate_exception(struct x86_emulate_ctxt *ctxt, int vec, | 463 | la = seg_base(ctxt, ctxt->ops, addr.seg) + addr.ea; |
478 | u32 error, bool valid) | 464 | if (c->ad_bytes != 8) |
479 | { | 465 | la &= (u32)-1; |
480 | ctxt->exception = vec; | 466 | return la; |
481 | ctxt->error_code = error; | ||
482 | ctxt->error_code_valid = valid; | ||
483 | } | 467 | } |
484 | 468 | ||
485 | static void emulate_gp(struct x86_emulate_ctxt *ctxt, int err) | 469 | static int emulate_exception(struct x86_emulate_ctxt *ctxt, int vec, |
470 | u32 error, bool valid) | ||
486 | { | 471 | { |
487 | emulate_exception(ctxt, GP_VECTOR, err, true); | 472 | ctxt->exception.vector = vec; |
473 | ctxt->exception.error_code = error; | ||
474 | ctxt->exception.error_code_valid = valid; | ||
475 | return X86EMUL_PROPAGATE_FAULT; | ||
488 | } | 476 | } |
489 | 477 | ||
490 | static void emulate_pf(struct x86_emulate_ctxt *ctxt) | 478 | static int emulate_gp(struct x86_emulate_ctxt *ctxt, int err) |
491 | { | 479 | { |
492 | emulate_exception(ctxt, PF_VECTOR, 0, true); | 480 | return emulate_exception(ctxt, GP_VECTOR, err, true); |
493 | } | 481 | } |
494 | 482 | ||
495 | static void emulate_ud(struct x86_emulate_ctxt *ctxt) | 483 | static int emulate_ud(struct x86_emulate_ctxt *ctxt) |
496 | { | 484 | { |
497 | emulate_exception(ctxt, UD_VECTOR, 0, false); | 485 | return emulate_exception(ctxt, UD_VECTOR, 0, false); |
498 | } | 486 | } |
499 | 487 | ||
500 | static void emulate_ts(struct x86_emulate_ctxt *ctxt, int err) | 488 | static int emulate_ts(struct x86_emulate_ctxt *ctxt, int err) |
501 | { | 489 | { |
502 | emulate_exception(ctxt, TS_VECTOR, err, true); | 490 | return emulate_exception(ctxt, TS_VECTOR, err, true); |
503 | } | 491 | } |
504 | 492 | ||
505 | static int emulate_de(struct x86_emulate_ctxt *ctxt) | 493 | static int emulate_de(struct x86_emulate_ctxt *ctxt) |
506 | { | 494 | { |
507 | emulate_exception(ctxt, DE_VECTOR, 0, false); | 495 | return emulate_exception(ctxt, DE_VECTOR, 0, false); |
508 | return X86EMUL_PROPAGATE_FAULT; | ||
509 | } | 496 | } |
510 | 497 | ||
511 | static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt, | 498 | static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt, |
@@ -520,7 +507,7 @@ static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt, | |||
520 | cur_size = fc->end - fc->start; | 507 | cur_size = fc->end - fc->start; |
521 | size = min(15UL - cur_size, PAGE_SIZE - offset_in_page(eip)); | 508 | size = min(15UL - cur_size, PAGE_SIZE - offset_in_page(eip)); |
522 | rc = ops->fetch(ctxt->cs_base + eip, fc->data + cur_size, | 509 | rc = ops->fetch(ctxt->cs_base + eip, fc->data + cur_size, |
523 | size, ctxt->vcpu, NULL); | 510 | size, ctxt->vcpu, &ctxt->exception); |
524 | if (rc != X86EMUL_CONTINUE) | 511 | if (rc != X86EMUL_CONTINUE) |
525 | return rc; | 512 | return rc; |
526 | fc->end += size; | 513 | fc->end += size; |
@@ -564,7 +551,7 @@ static void *decode_register(u8 modrm_reg, unsigned long *regs, | |||
564 | 551 | ||
565 | static int read_descriptor(struct x86_emulate_ctxt *ctxt, | 552 | static int read_descriptor(struct x86_emulate_ctxt *ctxt, |
566 | struct x86_emulate_ops *ops, | 553 | struct x86_emulate_ops *ops, |
567 | ulong addr, | 554 | struct segmented_address addr, |
568 | u16 *size, unsigned long *address, int op_bytes) | 555 | u16 *size, unsigned long *address, int op_bytes) |
569 | { | 556 | { |
570 | int rc; | 557 | int rc; |
@@ -572,10 +559,13 @@ static int read_descriptor(struct x86_emulate_ctxt *ctxt, | |||
572 | if (op_bytes == 2) | 559 | if (op_bytes == 2) |
573 | op_bytes = 3; | 560 | op_bytes = 3; |
574 | *address = 0; | 561 | *address = 0; |
575 | rc = ops->read_std(addr, (unsigned long *)size, 2, ctxt->vcpu, NULL); | 562 | rc = ops->read_std(linear(ctxt, addr), (unsigned long *)size, 2, |
563 | ctxt->vcpu, &ctxt->exception); | ||
576 | if (rc != X86EMUL_CONTINUE) | 564 | if (rc != X86EMUL_CONTINUE) |
577 | return rc; | 565 | return rc; |
578 | rc = ops->read_std(addr + 2, address, op_bytes, ctxt->vcpu, NULL); | 566 | addr.ea += 2; |
567 | rc = ops->read_std(linear(ctxt, addr), address, op_bytes, | ||
568 | ctxt->vcpu, &ctxt->exception); | ||
579 | return rc; | 569 | return rc; |
580 | } | 570 | } |
581 | 571 | ||
@@ -768,7 +758,7 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt, | |||
768 | break; | 758 | break; |
769 | } | 759 | } |
770 | } | 760 | } |
771 | op->addr.mem = modrm_ea; | 761 | op->addr.mem.ea = modrm_ea; |
772 | done: | 762 | done: |
773 | return rc; | 763 | return rc; |
774 | } | 764 | } |
@@ -783,13 +773,13 @@ static int decode_abs(struct x86_emulate_ctxt *ctxt, | |||
783 | op->type = OP_MEM; | 773 | op->type = OP_MEM; |
784 | switch (c->ad_bytes) { | 774 | switch (c->ad_bytes) { |
785 | case 2: | 775 | case 2: |
786 | op->addr.mem = insn_fetch(u16, 2, c->eip); | 776 | op->addr.mem.ea = insn_fetch(u16, 2, c->eip); |
787 | break; | 777 | break; |
788 | case 4: | 778 | case 4: |
789 | op->addr.mem = insn_fetch(u32, 4, c->eip); | 779 | op->addr.mem.ea = insn_fetch(u32, 4, c->eip); |
790 | break; | 780 | break; |
791 | case 8: | 781 | case 8: |
792 | op->addr.mem = insn_fetch(u64, 8, c->eip); | 782 | op->addr.mem.ea = insn_fetch(u64, 8, c->eip); |
793 | break; | 783 | break; |
794 | } | 784 | } |
795 | done: | 785 | done: |
@@ -808,7 +798,7 @@ static void fetch_bit_operand(struct decode_cache *c) | |||
808 | else if (c->src.bytes == 4) | 798 | else if (c->src.bytes == 4) |
809 | sv = (s32)c->src.val & (s32)mask; | 799 | sv = (s32)c->src.val & (s32)mask; |
810 | 800 | ||
811 | c->dst.addr.mem += (sv >> 3); | 801 | c->dst.addr.mem.ea += (sv >> 3); |
812 | } | 802 | } |
813 | 803 | ||
814 | /* only subword offset */ | 804 | /* only subword offset */ |
@@ -821,7 +811,6 @@ static int read_emulated(struct x86_emulate_ctxt *ctxt, | |||
821 | { | 811 | { |
822 | int rc; | 812 | int rc; |
823 | struct read_cache *mc = &ctxt->decode.mem_read; | 813 | struct read_cache *mc = &ctxt->decode.mem_read; |
824 | u32 err; | ||
825 | 814 | ||
826 | while (size) { | 815 | while (size) { |
827 | int n = min(size, 8u); | 816 | int n = min(size, 8u); |
@@ -829,10 +818,8 @@ static int read_emulated(struct x86_emulate_ctxt *ctxt, | |||
829 | if (mc->pos < mc->end) | 818 | if (mc->pos < mc->end) |
830 | goto read_cached; | 819 | goto read_cached; |
831 | 820 | ||
832 | rc = ops->read_emulated(addr, mc->data + mc->end, n, &err, | 821 | rc = ops->read_emulated(addr, mc->data + mc->end, n, |
833 | ctxt->vcpu); | 822 | &ctxt->exception, ctxt->vcpu); |
834 | if (rc == X86EMUL_PROPAGATE_FAULT) | ||
835 | emulate_pf(ctxt); | ||
836 | if (rc != X86EMUL_CONTINUE) | 823 | if (rc != X86EMUL_CONTINUE) |
837 | return rc; | 824 | return rc; |
838 | mc->end += n; | 825 | mc->end += n; |
@@ -907,19 +894,15 @@ static int read_segment_descriptor(struct x86_emulate_ctxt *ctxt, | |||
907 | struct desc_ptr dt; | 894 | struct desc_ptr dt; |
908 | u16 index = selector >> 3; | 895 | u16 index = selector >> 3; |
909 | int ret; | 896 | int ret; |
910 | u32 err; | ||
911 | ulong addr; | 897 | ulong addr; |
912 | 898 | ||
913 | get_descriptor_table_ptr(ctxt, ops, selector, &dt); | 899 | get_descriptor_table_ptr(ctxt, ops, selector, &dt); |
914 | 900 | ||
915 | if (dt.size < index * 8 + 7) { | 901 | if (dt.size < index * 8 + 7) |
916 | emulate_gp(ctxt, selector & 0xfffc); | 902 | return emulate_gp(ctxt, selector & 0xfffc); |
917 | return X86EMUL_PROPAGATE_FAULT; | ||
918 | } | ||
919 | addr = dt.address + index * 8; | 903 | addr = dt.address + index * 8; |
920 | ret = ops->read_std(addr, desc, sizeof *desc, ctxt->vcpu, &err); | 904 | ret = ops->read_std(addr, desc, sizeof *desc, ctxt->vcpu, |
921 | if (ret == X86EMUL_PROPAGATE_FAULT) | 905 | &ctxt->exception); |
922 | emulate_pf(ctxt); | ||
923 | 906 | ||
924 | return ret; | 907 | return ret; |
925 | } | 908 | } |
@@ -931,21 +914,17 @@ static int write_segment_descriptor(struct x86_emulate_ctxt *ctxt, | |||
931 | { | 914 | { |
932 | struct desc_ptr dt; | 915 | struct desc_ptr dt; |
933 | u16 index = selector >> 3; | 916 | u16 index = selector >> 3; |
934 | u32 err; | ||
935 | ulong addr; | 917 | ulong addr; |
936 | int ret; | 918 | int ret; |
937 | 919 | ||
938 | get_descriptor_table_ptr(ctxt, ops, selector, &dt); | 920 | get_descriptor_table_ptr(ctxt, ops, selector, &dt); |
939 | 921 | ||
940 | if (dt.size < index * 8 + 7) { | 922 | if (dt.size < index * 8 + 7) |
941 | emulate_gp(ctxt, selector & 0xfffc); | 923 | return emulate_gp(ctxt, selector & 0xfffc); |
942 | return X86EMUL_PROPAGATE_FAULT; | ||
943 | } | ||
944 | 924 | ||
945 | addr = dt.address + index * 8; | 925 | addr = dt.address + index * 8; |
946 | ret = ops->write_std(addr, desc, sizeof *desc, ctxt->vcpu, &err); | 926 | ret = ops->write_std(addr, desc, sizeof *desc, ctxt->vcpu, |
947 | if (ret == X86EMUL_PROPAGATE_FAULT) | 927 | &ctxt->exception); |
948 | emulate_pf(ctxt); | ||
949 | 928 | ||
950 | return ret; | 929 | return ret; |
951 | } | 930 | } |
@@ -1092,7 +1071,6 @@ static inline int writeback(struct x86_emulate_ctxt *ctxt, | |||
1092 | { | 1071 | { |
1093 | int rc; | 1072 | int rc; |
1094 | struct decode_cache *c = &ctxt->decode; | 1073 | struct decode_cache *c = &ctxt->decode; |
1095 | u32 err; | ||
1096 | 1074 | ||
1097 | switch (c->dst.type) { | 1075 | switch (c->dst.type) { |
1098 | case OP_REG: | 1076 | case OP_REG: |
@@ -1101,21 +1079,19 @@ static inline int writeback(struct x86_emulate_ctxt *ctxt, | |||
1101 | case OP_MEM: | 1079 | case OP_MEM: |
1102 | if (c->lock_prefix) | 1080 | if (c->lock_prefix) |
1103 | rc = ops->cmpxchg_emulated( | 1081 | rc = ops->cmpxchg_emulated( |
1104 | c->dst.addr.mem, | 1082 | linear(ctxt, c->dst.addr.mem), |
1105 | &c->dst.orig_val, | 1083 | &c->dst.orig_val, |
1106 | &c->dst.val, | 1084 | &c->dst.val, |
1107 | c->dst.bytes, | 1085 | c->dst.bytes, |
1108 | &err, | 1086 | &ctxt->exception, |
1109 | ctxt->vcpu); | 1087 | ctxt->vcpu); |
1110 | else | 1088 | else |
1111 | rc = ops->write_emulated( | 1089 | rc = ops->write_emulated( |
1112 | c->dst.addr.mem, | 1090 | linear(ctxt, c->dst.addr.mem), |
1113 | &c->dst.val, | 1091 | &c->dst.val, |
1114 | c->dst.bytes, | 1092 | c->dst.bytes, |
1115 | &err, | 1093 | &ctxt->exception, |
1116 | ctxt->vcpu); | 1094 | ctxt->vcpu); |
1117 | if (rc == X86EMUL_PROPAGATE_FAULT) | ||
1118 | emulate_pf(ctxt); | ||
1119 | if (rc != X86EMUL_CONTINUE) | 1095 | if (rc != X86EMUL_CONTINUE) |
1120 | return rc; | 1096 | return rc; |
1121 | break; | 1097 | break; |
@@ -1137,8 +1113,8 @@ static inline void emulate_push(struct x86_emulate_ctxt *ctxt, | |||
1137 | c->dst.bytes = c->op_bytes; | 1113 | c->dst.bytes = c->op_bytes; |
1138 | c->dst.val = c->src.val; | 1114 | c->dst.val = c->src.val; |
1139 | register_address_increment(c, &c->regs[VCPU_REGS_RSP], -c->op_bytes); | 1115 | register_address_increment(c, &c->regs[VCPU_REGS_RSP], -c->op_bytes); |
1140 | c->dst.addr.mem = register_address(c, ss_base(ctxt, ops), | 1116 | c->dst.addr.mem.ea = register_address(c, c->regs[VCPU_REGS_RSP]); |
1141 | c->regs[VCPU_REGS_RSP]); | 1117 | c->dst.addr.mem.seg = VCPU_SREG_SS; |
1142 | } | 1118 | } |
1143 | 1119 | ||
1144 | static int emulate_pop(struct x86_emulate_ctxt *ctxt, | 1120 | static int emulate_pop(struct x86_emulate_ctxt *ctxt, |
@@ -1147,10 +1123,11 @@ static int emulate_pop(struct x86_emulate_ctxt *ctxt, | |||
1147 | { | 1123 | { |
1148 | struct decode_cache *c = &ctxt->decode; | 1124 | struct decode_cache *c = &ctxt->decode; |
1149 | int rc; | 1125 | int rc; |
1126 | struct segmented_address addr; | ||
1150 | 1127 | ||
1151 | rc = read_emulated(ctxt, ops, register_address(c, ss_base(ctxt, ops), | 1128 | addr.ea = register_address(c, c->regs[VCPU_REGS_RSP]); |
1152 | c->regs[VCPU_REGS_RSP]), | 1129 | addr.seg = VCPU_SREG_SS; |
1153 | dest, len); | 1130 | rc = read_emulated(ctxt, ops, linear(ctxt, addr), dest, len); |
1154 | if (rc != X86EMUL_CONTINUE) | 1131 | if (rc != X86EMUL_CONTINUE) |
1155 | return rc; | 1132 | return rc; |
1156 | 1133 | ||
@@ -1184,10 +1161,8 @@ static int emulate_popf(struct x86_emulate_ctxt *ctxt, | |||
1184 | change_mask |= EFLG_IF; | 1161 | change_mask |= EFLG_IF; |
1185 | break; | 1162 | break; |
1186 | case X86EMUL_MODE_VM86: | 1163 | case X86EMUL_MODE_VM86: |
1187 | if (iopl < 3) { | 1164 | if (iopl < 3) |
1188 | emulate_gp(ctxt, 0); | 1165 | return emulate_gp(ctxt, 0); |
1189 | return X86EMUL_PROPAGATE_FAULT; | ||
1190 | } | ||
1191 | change_mask |= EFLG_IF; | 1166 | change_mask |= EFLG_IF; |
1192 | break; | 1167 | break; |
1193 | default: /* real mode */ | 1168 | default: /* real mode */ |
@@ -1198,9 +1173,6 @@ static int emulate_popf(struct x86_emulate_ctxt *ctxt, | |||
1198 | *(unsigned long *)dest = | 1173 | *(unsigned long *)dest = |
1199 | (ctxt->eflags & ~change_mask) | (val & change_mask); | 1174 | (ctxt->eflags & ~change_mask) | (val & change_mask); |
1200 | 1175 | ||
1201 | if (rc == X86EMUL_PROPAGATE_FAULT) | ||
1202 | emulate_pf(ctxt); | ||
1203 | |||
1204 | return rc; | 1176 | return rc; |
1205 | } | 1177 | } |
1206 | 1178 | ||
@@ -1287,7 +1259,6 @@ int emulate_int_real(struct x86_emulate_ctxt *ctxt, | |||
1287 | gva_t cs_addr; | 1259 | gva_t cs_addr; |
1288 | gva_t eip_addr; | 1260 | gva_t eip_addr; |
1289 | u16 cs, eip; | 1261 | u16 cs, eip; |
1290 | u32 err; | ||
1291 | 1262 | ||
1292 | /* TODO: Add limit checks */ | 1263 | /* TODO: Add limit checks */ |
1293 | c->src.val = ctxt->eflags; | 1264 | c->src.val = ctxt->eflags; |
@@ -1317,11 +1288,11 @@ int emulate_int_real(struct x86_emulate_ctxt *ctxt, | |||
1317 | eip_addr = dt.address + (irq << 2); | 1288 | eip_addr = dt.address + (irq << 2); |
1318 | cs_addr = dt.address + (irq << 2) + 2; | 1289 | cs_addr = dt.address + (irq << 2) + 2; |
1319 | 1290 | ||
1320 | rc = ops->read_std(cs_addr, &cs, 2, ctxt->vcpu, &err); | 1291 | rc = ops->read_std(cs_addr, &cs, 2, ctxt->vcpu, &ctxt->exception); |
1321 | if (rc != X86EMUL_CONTINUE) | 1292 | if (rc != X86EMUL_CONTINUE) |
1322 | return rc; | 1293 | return rc; |
1323 | 1294 | ||
1324 | rc = ops->read_std(eip_addr, &eip, 2, ctxt->vcpu, &err); | 1295 | rc = ops->read_std(eip_addr, &eip, 2, ctxt->vcpu, &ctxt->exception); |
1325 | if (rc != X86EMUL_CONTINUE) | 1296 | if (rc != X86EMUL_CONTINUE) |
1326 | return rc; | 1297 | return rc; |
1327 | 1298 | ||
@@ -1370,10 +1341,8 @@ static int emulate_iret_real(struct x86_emulate_ctxt *ctxt, | |||
1370 | if (rc != X86EMUL_CONTINUE) | 1341 | if (rc != X86EMUL_CONTINUE) |
1371 | return rc; | 1342 | return rc; |
1372 | 1343 | ||
1373 | if (temp_eip & ~0xffff) { | 1344 | if (temp_eip & ~0xffff) |
1374 | emulate_gp(ctxt, 0); | 1345 | return emulate_gp(ctxt, 0); |
1375 | return X86EMUL_PROPAGATE_FAULT; | ||
1376 | } | ||
1377 | 1346 | ||
1378 | rc = emulate_pop(ctxt, ops, &cs, c->op_bytes); | 1347 | rc = emulate_pop(ctxt, ops, &cs, c->op_bytes); |
1379 | 1348 | ||
@@ -1624,10 +1593,8 @@ emulate_syscall(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | |||
1624 | 1593 | ||
1625 | /* syscall is not available in real mode */ | 1594 | /* syscall is not available in real mode */ |
1626 | if (ctxt->mode == X86EMUL_MODE_REAL || | 1595 | if (ctxt->mode == X86EMUL_MODE_REAL || |
1627 | ctxt->mode == X86EMUL_MODE_VM86) { | 1596 | ctxt->mode == X86EMUL_MODE_VM86) |
1628 | emulate_ud(ctxt); | 1597 | return emulate_ud(ctxt); |
1629 | return X86EMUL_PROPAGATE_FAULT; | ||
1630 | } | ||
1631 | 1598 | ||
1632 | setup_syscalls_segments(ctxt, ops, &cs, &ss); | 1599 | setup_syscalls_segments(ctxt, ops, &cs, &ss); |
1633 | 1600 | ||
@@ -1678,34 +1645,26 @@ emulate_sysenter(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | |||
1678 | u16 cs_sel, ss_sel; | 1645 | u16 cs_sel, ss_sel; |
1679 | 1646 | ||
1680 | /* inject #GP if in real mode */ | 1647 | /* inject #GP if in real mode */ |
1681 | if (ctxt->mode == X86EMUL_MODE_REAL) { | 1648 | if (ctxt->mode == X86EMUL_MODE_REAL) |
1682 | emulate_gp(ctxt, 0); | 1649 | return emulate_gp(ctxt, 0); |
1683 | return X86EMUL_PROPAGATE_FAULT; | ||
1684 | } | ||
1685 | 1650 | ||
1686 | /* XXX sysenter/sysexit have not been tested in 64bit mode. | 1651 | /* XXX sysenter/sysexit have not been tested in 64bit mode. |
1687 | * Therefore, we inject an #UD. | 1652 | * Therefore, we inject an #UD. |
1688 | */ | 1653 | */ |
1689 | if (ctxt->mode == X86EMUL_MODE_PROT64) { | 1654 | if (ctxt->mode == X86EMUL_MODE_PROT64) |
1690 | emulate_ud(ctxt); | 1655 | return emulate_ud(ctxt); |
1691 | return X86EMUL_PROPAGATE_FAULT; | ||
1692 | } | ||
1693 | 1656 | ||
1694 | setup_syscalls_segments(ctxt, ops, &cs, &ss); | 1657 | setup_syscalls_segments(ctxt, ops, &cs, &ss); |
1695 | 1658 | ||
1696 | ops->get_msr(ctxt->vcpu, MSR_IA32_SYSENTER_CS, &msr_data); | 1659 | ops->get_msr(ctxt->vcpu, MSR_IA32_SYSENTER_CS, &msr_data); |
1697 | switch (ctxt->mode) { | 1660 | switch (ctxt->mode) { |
1698 | case X86EMUL_MODE_PROT32: | 1661 | case X86EMUL_MODE_PROT32: |
1699 | if ((msr_data & 0xfffc) == 0x0) { | 1662 | if ((msr_data & 0xfffc) == 0x0) |
1700 | emulate_gp(ctxt, 0); | 1663 | return emulate_gp(ctxt, 0); |
1701 | return X86EMUL_PROPAGATE_FAULT; | ||
1702 | } | ||
1703 | break; | 1664 | break; |
1704 | case X86EMUL_MODE_PROT64: | 1665 | case X86EMUL_MODE_PROT64: |
1705 | if (msr_data == 0x0) { | 1666 | if (msr_data == 0x0) |
1706 | emulate_gp(ctxt, 0); | 1667 | return emulate_gp(ctxt, 0); |
1707 | return X86EMUL_PROPAGATE_FAULT; | ||
1708 | } | ||
1709 | break; | 1668 | break; |
1710 | } | 1669 | } |
1711 | 1670 | ||
@@ -1745,10 +1704,8 @@ emulate_sysexit(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | |||
1745 | 1704 | ||
1746 | /* inject #GP if in real mode or Virtual 8086 mode */ | 1705 | /* inject #GP if in real mode or Virtual 8086 mode */ |
1747 | if (ctxt->mode == X86EMUL_MODE_REAL || | 1706 | if (ctxt->mode == X86EMUL_MODE_REAL || |
1748 | ctxt->mode == X86EMUL_MODE_VM86) { | 1707 | ctxt->mode == X86EMUL_MODE_VM86) |
1749 | emulate_gp(ctxt, 0); | 1708 | return emulate_gp(ctxt, 0); |
1750 | return X86EMUL_PROPAGATE_FAULT; | ||
1751 | } | ||
1752 | 1709 | ||
1753 | setup_syscalls_segments(ctxt, ops, &cs, &ss); | 1710 | setup_syscalls_segments(ctxt, ops, &cs, &ss); |
1754 | 1711 | ||
@@ -1763,18 +1720,14 @@ emulate_sysexit(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | |||
1763 | switch (usermode) { | 1720 | switch (usermode) { |
1764 | case X86EMUL_MODE_PROT32: | 1721 | case X86EMUL_MODE_PROT32: |
1765 | cs_sel = (u16)(msr_data + 16); | 1722 | cs_sel = (u16)(msr_data + 16); |
1766 | if ((msr_data & 0xfffc) == 0x0) { | 1723 | if ((msr_data & 0xfffc) == 0x0) |
1767 | emulate_gp(ctxt, 0); | 1724 | return emulate_gp(ctxt, 0); |
1768 | return X86EMUL_PROPAGATE_FAULT; | ||
1769 | } | ||
1770 | ss_sel = (u16)(msr_data + 24); | 1725 | ss_sel = (u16)(msr_data + 24); |
1771 | break; | 1726 | break; |
1772 | case X86EMUL_MODE_PROT64: | 1727 | case X86EMUL_MODE_PROT64: |
1773 | cs_sel = (u16)(msr_data + 32); | 1728 | cs_sel = (u16)(msr_data + 32); |
1774 | if (msr_data == 0x0) { | 1729 | if (msr_data == 0x0) |
1775 | emulate_gp(ctxt, 0); | 1730 | return emulate_gp(ctxt, 0); |
1776 | return X86EMUL_PROPAGATE_FAULT; | ||
1777 | } | ||
1778 | ss_sel = cs_sel + 8; | 1731 | ss_sel = cs_sel + 8; |
1779 | cs.d = 0; | 1732 | cs.d = 0; |
1780 | cs.l = 1; | 1733 | cs.l = 1; |
@@ -1934,33 +1887,27 @@ static int task_switch_16(struct x86_emulate_ctxt *ctxt, | |||
1934 | { | 1887 | { |
1935 | struct tss_segment_16 tss_seg; | 1888 | struct tss_segment_16 tss_seg; |
1936 | int ret; | 1889 | int ret; |
1937 | u32 err, new_tss_base = get_desc_base(new_desc); | 1890 | u32 new_tss_base = get_desc_base(new_desc); |
1938 | 1891 | ||
1939 | ret = ops->read_std(old_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu, | 1892 | ret = ops->read_std(old_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu, |
1940 | &err); | 1893 | &ctxt->exception); |
1941 | if (ret == X86EMUL_PROPAGATE_FAULT) { | 1894 | if (ret != X86EMUL_CONTINUE) |
1942 | /* FIXME: need to provide precise fault address */ | 1895 | /* FIXME: need to provide precise fault address */ |
1943 | emulate_pf(ctxt); | ||
1944 | return ret; | 1896 | return ret; |
1945 | } | ||
1946 | 1897 | ||
1947 | save_state_to_tss16(ctxt, ops, &tss_seg); | 1898 | save_state_to_tss16(ctxt, ops, &tss_seg); |
1948 | 1899 | ||
1949 | ret = ops->write_std(old_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu, | 1900 | ret = ops->write_std(old_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu, |
1950 | &err); | 1901 | &ctxt->exception); |
1951 | if (ret == X86EMUL_PROPAGATE_FAULT) { | 1902 | if (ret != X86EMUL_CONTINUE) |
1952 | /* FIXME: need to provide precise fault address */ | 1903 | /* FIXME: need to provide precise fault address */ |
1953 | emulate_pf(ctxt); | ||
1954 | return ret; | 1904 | return ret; |
1955 | } | ||
1956 | 1905 | ||
1957 | ret = ops->read_std(new_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu, | 1906 | ret = ops->read_std(new_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu, |
1958 | &err); | 1907 | &ctxt->exception); |
1959 | if (ret == X86EMUL_PROPAGATE_FAULT) { | 1908 | if (ret != X86EMUL_CONTINUE) |
1960 | /* FIXME: need to provide precise fault address */ | 1909 | /* FIXME: need to provide precise fault address */ |
1961 | emulate_pf(ctxt); | ||
1962 | return ret; | 1910 | return ret; |
1963 | } | ||
1964 | 1911 | ||
1965 | if (old_tss_sel != 0xffff) { | 1912 | if (old_tss_sel != 0xffff) { |
1966 | tss_seg.prev_task_link = old_tss_sel; | 1913 | tss_seg.prev_task_link = old_tss_sel; |
@@ -1968,12 +1915,10 @@ static int task_switch_16(struct x86_emulate_ctxt *ctxt, | |||
1968 | ret = ops->write_std(new_tss_base, | 1915 | ret = ops->write_std(new_tss_base, |
1969 | &tss_seg.prev_task_link, | 1916 | &tss_seg.prev_task_link, |
1970 | sizeof tss_seg.prev_task_link, | 1917 | sizeof tss_seg.prev_task_link, |
1971 | ctxt->vcpu, &err); | 1918 | ctxt->vcpu, &ctxt->exception); |
1972 | if (ret == X86EMUL_PROPAGATE_FAULT) { | 1919 | if (ret != X86EMUL_CONTINUE) |
1973 | /* FIXME: need to provide precise fault address */ | 1920 | /* FIXME: need to provide precise fault address */ |
1974 | emulate_pf(ctxt); | ||
1975 | return ret; | 1921 | return ret; |
1976 | } | ||
1977 | } | 1922 | } |
1978 | 1923 | ||
1979 | return load_state_from_tss16(ctxt, ops, &tss_seg); | 1924 | return load_state_from_tss16(ctxt, ops, &tss_seg); |
@@ -2013,10 +1958,8 @@ static int load_state_from_tss32(struct x86_emulate_ctxt *ctxt, | |||
2013 | struct decode_cache *c = &ctxt->decode; | 1958 | struct decode_cache *c = &ctxt->decode; |
2014 | int ret; | 1959 | int ret; |
2015 | 1960 | ||
2016 | if (ops->set_cr(3, tss->cr3, ctxt->vcpu)) { | 1961 | if (ops->set_cr(3, tss->cr3, ctxt->vcpu)) |
2017 | emulate_gp(ctxt, 0); | 1962 | return emulate_gp(ctxt, 0); |
2018 | return X86EMUL_PROPAGATE_FAULT; | ||
2019 | } | ||
2020 | c->eip = tss->eip; | 1963 | c->eip = tss->eip; |
2021 | ctxt->eflags = tss->eflags | 2; | 1964 | ctxt->eflags = tss->eflags | 2; |
2022 | c->regs[VCPU_REGS_RAX] = tss->eax; | 1965 | c->regs[VCPU_REGS_RAX] = tss->eax; |
@@ -2076,33 +2019,27 @@ static int task_switch_32(struct x86_emulate_ctxt *ctxt, | |||
2076 | { | 2019 | { |
2077 | struct tss_segment_32 tss_seg; | 2020 | struct tss_segment_32 tss_seg; |
2078 | int ret; | 2021 | int ret; |
2079 | u32 err, new_tss_base = get_desc_base(new_desc); | 2022 | u32 new_tss_base = get_desc_base(new_desc); |
2080 | 2023 | ||
2081 | ret = ops->read_std(old_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu, | 2024 | ret = ops->read_std(old_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu, |
2082 | &err); | 2025 | &ctxt->exception); |
2083 | if (ret == X86EMUL_PROPAGATE_FAULT) { | 2026 | if (ret != X86EMUL_CONTINUE) |
2084 | /* FIXME: need to provide precise fault address */ | 2027 | /* FIXME: need to provide precise fault address */ |
2085 | emulate_pf(ctxt); | ||
2086 | return ret; | 2028 | return ret; |
2087 | } | ||
2088 | 2029 | ||
2089 | save_state_to_tss32(ctxt, ops, &tss_seg); | 2030 | save_state_to_tss32(ctxt, ops, &tss_seg); |
2090 | 2031 | ||
2091 | ret = ops->write_std(old_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu, | 2032 | ret = ops->write_std(old_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu, |
2092 | &err); | 2033 | &ctxt->exception); |
2093 | if (ret == X86EMUL_PROPAGATE_FAULT) { | 2034 | if (ret != X86EMUL_CONTINUE) |
2094 | /* FIXME: need to provide precise fault address */ | 2035 | /* FIXME: need to provide precise fault address */ |
2095 | emulate_pf(ctxt); | ||
2096 | return ret; | 2036 | return ret; |
2097 | } | ||
2098 | 2037 | ||
2099 | ret = ops->read_std(new_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu, | 2038 | ret = ops->read_std(new_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu, |
2100 | &err); | 2039 | &ctxt->exception); |
2101 | if (ret == X86EMUL_PROPAGATE_FAULT) { | 2040 | if (ret != X86EMUL_CONTINUE) |
2102 | /* FIXME: need to provide precise fault address */ | 2041 | /* FIXME: need to provide precise fault address */ |
2103 | emulate_pf(ctxt); | ||
2104 | return ret; | 2042 | return ret; |
2105 | } | ||
2106 | 2043 | ||
2107 | if (old_tss_sel != 0xffff) { | 2044 | if (old_tss_sel != 0xffff) { |
2108 | tss_seg.prev_task_link = old_tss_sel; | 2045 | tss_seg.prev_task_link = old_tss_sel; |
@@ -2110,12 +2047,10 @@ static int task_switch_32(struct x86_emulate_ctxt *ctxt, | |||
2110 | ret = ops->write_std(new_tss_base, | 2047 | ret = ops->write_std(new_tss_base, |
2111 | &tss_seg.prev_task_link, | 2048 | &tss_seg.prev_task_link, |
2112 | sizeof tss_seg.prev_task_link, | 2049 | sizeof tss_seg.prev_task_link, |
2113 | ctxt->vcpu, &err); | 2050 | ctxt->vcpu, &ctxt->exception); |
2114 | if (ret == X86EMUL_PROPAGATE_FAULT) { | 2051 | if (ret != X86EMUL_CONTINUE) |
2115 | /* FIXME: need to provide precise fault address */ | 2052 | /* FIXME: need to provide precise fault address */ |
2116 | emulate_pf(ctxt); | ||
2117 | return ret; | 2053 | return ret; |
2118 | } | ||
2119 | } | 2054 | } |
2120 | 2055 | ||
2121 | return load_state_from_tss32(ctxt, ops, &tss_seg); | 2056 | return load_state_from_tss32(ctxt, ops, &tss_seg); |
@@ -2146,10 +2081,8 @@ static int emulator_do_task_switch(struct x86_emulate_ctxt *ctxt, | |||
2146 | 2081 | ||
2147 | if (reason != TASK_SWITCH_IRET) { | 2082 | if (reason != TASK_SWITCH_IRET) { |
2148 | if ((tss_selector & 3) > next_tss_desc.dpl || | 2083 | if ((tss_selector & 3) > next_tss_desc.dpl || |
2149 | ops->cpl(ctxt->vcpu) > next_tss_desc.dpl) { | 2084 | ops->cpl(ctxt->vcpu) > next_tss_desc.dpl) |
2150 | emulate_gp(ctxt, 0); | 2085 | return emulate_gp(ctxt, 0); |
2151 | return X86EMUL_PROPAGATE_FAULT; | ||
2152 | } | ||
2153 | } | 2086 | } |
2154 | 2087 | ||
2155 | desc_limit = desc_limit_scaled(&next_tss_desc); | 2088 | desc_limit = desc_limit_scaled(&next_tss_desc); |
@@ -2231,14 +2164,15 @@ int emulator_task_switch(struct x86_emulate_ctxt *ctxt, | |||
2231 | return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0; | 2164 | return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0; |
2232 | } | 2165 | } |
2233 | 2166 | ||
2234 | static void string_addr_inc(struct x86_emulate_ctxt *ctxt, unsigned long base, | 2167 | static void string_addr_inc(struct x86_emulate_ctxt *ctxt, unsigned seg, |
2235 | int reg, struct operand *op) | 2168 | int reg, struct operand *op) |
2236 | { | 2169 | { |
2237 | struct decode_cache *c = &ctxt->decode; | 2170 | struct decode_cache *c = &ctxt->decode; |
2238 | int df = (ctxt->eflags & EFLG_DF) ? -1 : 1; | 2171 | int df = (ctxt->eflags & EFLG_DF) ? -1 : 1; |
2239 | 2172 | ||
2240 | register_address_increment(c, &c->regs[reg], df * op->bytes); | 2173 | register_address_increment(c, &c->regs[reg], df * op->bytes); |
2241 | op->addr.mem = register_address(c, base, c->regs[reg]); | 2174 | op->addr.mem.ea = register_address(c, c->regs[reg]); |
2175 | op->addr.mem.seg = seg; | ||
2242 | } | 2176 | } |
2243 | 2177 | ||
2244 | static int em_push(struct x86_emulate_ctxt *ctxt) | 2178 | static int em_push(struct x86_emulate_ctxt *ctxt) |
@@ -2369,10 +2303,8 @@ static int em_rdtsc(struct x86_emulate_ctxt *ctxt) | |||
2369 | struct decode_cache *c = &ctxt->decode; | 2303 | struct decode_cache *c = &ctxt->decode; |
2370 | u64 tsc = 0; | 2304 | u64 tsc = 0; |
2371 | 2305 | ||
2372 | if (cpl > 0 && (ctxt->ops->get_cr(4, ctxt->vcpu) & X86_CR4_TSD)) { | 2306 | if (cpl > 0 && (ctxt->ops->get_cr(4, ctxt->vcpu) & X86_CR4_TSD)) |
2373 | emulate_gp(ctxt, 0); | 2307 | return emulate_gp(ctxt, 0); |
2374 | return X86EMUL_PROPAGATE_FAULT; | ||
2375 | } | ||
2376 | ctxt->ops->get_msr(ctxt->vcpu, MSR_IA32_TSC, &tsc); | 2308 | ctxt->ops->get_msr(ctxt->vcpu, MSR_IA32_TSC, &tsc); |
2377 | c->regs[VCPU_REGS_RAX] = (u32)tsc; | 2309 | c->regs[VCPU_REGS_RAX] = (u32)tsc; |
2378 | c->regs[VCPU_REGS_RDX] = tsc >> 32; | 2310 | c->regs[VCPU_REGS_RDX] = tsc >> 32; |
@@ -2647,7 +2579,7 @@ static int decode_imm(struct x86_emulate_ctxt *ctxt, struct operand *op, | |||
2647 | 2579 | ||
2648 | op->type = OP_IMM; | 2580 | op->type = OP_IMM; |
2649 | op->bytes = size; | 2581 | op->bytes = size; |
2650 | op->addr.mem = c->eip; | 2582 | op->addr.mem.ea = c->eip; |
2651 | /* NB. Immediates are sign-extended as necessary. */ | 2583 | /* NB. Immediates are sign-extended as necessary. */ |
2652 | switch (op->bytes) { | 2584 | switch (op->bytes) { |
2653 | case 1: | 2585 | case 1: |
@@ -2678,7 +2610,7 @@ done: | |||
2678 | } | 2610 | } |
2679 | 2611 | ||
2680 | int | 2612 | int |
2681 | x86_decode_insn(struct x86_emulate_ctxt *ctxt) | 2613 | x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len) |
2682 | { | 2614 | { |
2683 | struct x86_emulate_ops *ops = ctxt->ops; | 2615 | struct x86_emulate_ops *ops = ctxt->ops; |
2684 | struct decode_cache *c = &ctxt->decode; | 2616 | struct decode_cache *c = &ctxt->decode; |
@@ -2689,7 +2621,10 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt) | |||
2689 | struct operand memop = { .type = OP_NONE }; | 2621 | struct operand memop = { .type = OP_NONE }; |
2690 | 2622 | ||
2691 | c->eip = ctxt->eip; | 2623 | c->eip = ctxt->eip; |
2692 | c->fetch.start = c->fetch.end = c->eip; | 2624 | c->fetch.start = c->eip; |
2625 | c->fetch.end = c->fetch.start + insn_len; | ||
2626 | if (insn_len > 0) | ||
2627 | memcpy(c->fetch.data, insn, insn_len); | ||
2693 | ctxt->cs_base = seg_base(ctxt, ops, VCPU_SREG_CS); | 2628 | ctxt->cs_base = seg_base(ctxt, ops, VCPU_SREG_CS); |
2694 | 2629 | ||
2695 | switch (mode) { | 2630 | switch (mode) { |
@@ -2803,10 +2738,8 @@ done_prefixes: | |||
2803 | c->execute = opcode.u.execute; | 2738 | c->execute = opcode.u.execute; |
2804 | 2739 | ||
2805 | /* Unrecognised? */ | 2740 | /* Unrecognised? */ |
2806 | if (c->d == 0 || (c->d & Undefined)) { | 2741 | if (c->d == 0 || (c->d & Undefined)) |
2807 | DPRINTF("Cannot emulate %02x\n", c->b); | ||
2808 | return -1; | 2742 | return -1; |
2809 | } | ||
2810 | 2743 | ||
2811 | if (mode == X86EMUL_MODE_PROT64 && (c->d & Stack)) | 2744 | if (mode == X86EMUL_MODE_PROT64 && (c->d & Stack)) |
2812 | c->op_bytes = 8; | 2745 | c->op_bytes = 8; |
@@ -2831,14 +2764,13 @@ done_prefixes: | |||
2831 | if (!c->has_seg_override) | 2764 | if (!c->has_seg_override) |
2832 | set_seg_override(c, VCPU_SREG_DS); | 2765 | set_seg_override(c, VCPU_SREG_DS); |
2833 | 2766 | ||
2834 | if (memop.type == OP_MEM && !(!c->twobyte && c->b == 0x8d)) | 2767 | memop.addr.mem.seg = seg_override(ctxt, ops, c); |
2835 | memop.addr.mem += seg_override_base(ctxt, ops, c); | ||
2836 | 2768 | ||
2837 | if (memop.type == OP_MEM && c->ad_bytes != 8) | 2769 | if (memop.type == OP_MEM && c->ad_bytes != 8) |
2838 | memop.addr.mem = (u32)memop.addr.mem; | 2770 | memop.addr.mem.ea = (u32)memop.addr.mem.ea; |
2839 | 2771 | ||
2840 | if (memop.type == OP_MEM && c->rip_relative) | 2772 | if (memop.type == OP_MEM && c->rip_relative) |
2841 | memop.addr.mem += c->eip; | 2773 | memop.addr.mem.ea += c->eip; |
2842 | 2774 | ||
2843 | /* | 2775 | /* |
2844 | * Decode and fetch the source operand: register, memory | 2776 | * Decode and fetch the source operand: register, memory |
@@ -2890,14 +2822,14 @@ done_prefixes: | |||
2890 | case SrcSI: | 2822 | case SrcSI: |
2891 | c->src.type = OP_MEM; | 2823 | c->src.type = OP_MEM; |
2892 | c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; | 2824 | c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; |
2893 | c->src.addr.mem = | 2825 | c->src.addr.mem.ea = |
2894 | register_address(c, seg_override_base(ctxt, ops, c), | 2826 | register_address(c, c->regs[VCPU_REGS_RSI]); |
2895 | c->regs[VCPU_REGS_RSI]); | 2827 | c->src.addr.mem.seg = seg_override(ctxt, ops, c), |
2896 | c->src.val = 0; | 2828 | c->src.val = 0; |
2897 | break; | 2829 | break; |
2898 | case SrcImmFAddr: | 2830 | case SrcImmFAddr: |
2899 | c->src.type = OP_IMM; | 2831 | c->src.type = OP_IMM; |
2900 | c->src.addr.mem = c->eip; | 2832 | c->src.addr.mem.ea = c->eip; |
2901 | c->src.bytes = c->op_bytes + 2; | 2833 | c->src.bytes = c->op_bytes + 2; |
2902 | insn_fetch_arr(c->src.valptr, c->src.bytes, c->eip); | 2834 | insn_fetch_arr(c->src.valptr, c->src.bytes, c->eip); |
2903 | break; | 2835 | break; |
@@ -2944,7 +2876,7 @@ done_prefixes: | |||
2944 | break; | 2876 | break; |
2945 | case DstImmUByte: | 2877 | case DstImmUByte: |
2946 | c->dst.type = OP_IMM; | 2878 | c->dst.type = OP_IMM; |
2947 | c->dst.addr.mem = c->eip; | 2879 | c->dst.addr.mem.ea = c->eip; |
2948 | c->dst.bytes = 1; | 2880 | c->dst.bytes = 1; |
2949 | c->dst.val = insn_fetch(u8, 1, c->eip); | 2881 | c->dst.val = insn_fetch(u8, 1, c->eip); |
2950 | break; | 2882 | break; |
@@ -2969,9 +2901,9 @@ done_prefixes: | |||
2969 | case DstDI: | 2901 | case DstDI: |
2970 | c->dst.type = OP_MEM; | 2902 | c->dst.type = OP_MEM; |
2971 | c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; | 2903 | c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; |
2972 | c->dst.addr.mem = | 2904 | c->dst.addr.mem.ea = |
2973 | register_address(c, es_base(ctxt, ops), | 2905 | register_address(c, c->regs[VCPU_REGS_RDI]); |
2974 | c->regs[VCPU_REGS_RDI]); | 2906 | c->dst.addr.mem.seg = VCPU_SREG_ES; |
2975 | c->dst.val = 0; | 2907 | c->dst.val = 0; |
2976 | break; | 2908 | break; |
2977 | case ImplicitOps: | 2909 | case ImplicitOps: |
@@ -3020,24 +2952,24 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt) | |||
3020 | ctxt->decode.mem_read.pos = 0; | 2952 | ctxt->decode.mem_read.pos = 0; |
3021 | 2953 | ||
3022 | if (ctxt->mode == X86EMUL_MODE_PROT64 && (c->d & No64)) { | 2954 | if (ctxt->mode == X86EMUL_MODE_PROT64 && (c->d & No64)) { |
3023 | emulate_ud(ctxt); | 2955 | rc = emulate_ud(ctxt); |
3024 | goto done; | 2956 | goto done; |
3025 | } | 2957 | } |
3026 | 2958 | ||
3027 | /* LOCK prefix is allowed only with some instructions */ | 2959 | /* LOCK prefix is allowed only with some instructions */ |
3028 | if (c->lock_prefix && (!(c->d & Lock) || c->dst.type != OP_MEM)) { | 2960 | if (c->lock_prefix && (!(c->d & Lock) || c->dst.type != OP_MEM)) { |
3029 | emulate_ud(ctxt); | 2961 | rc = emulate_ud(ctxt); |
3030 | goto done; | 2962 | goto done; |
3031 | } | 2963 | } |
3032 | 2964 | ||
3033 | if ((c->d & SrcMask) == SrcMemFAddr && c->src.type != OP_MEM) { | 2965 | if ((c->d & SrcMask) == SrcMemFAddr && c->src.type != OP_MEM) { |
3034 | emulate_ud(ctxt); | 2966 | rc = emulate_ud(ctxt); |
3035 | goto done; | 2967 | goto done; |
3036 | } | 2968 | } |
3037 | 2969 | ||
3038 | /* Privileged instruction can be executed only in CPL=0 */ | 2970 | /* Privileged instruction can be executed only in CPL=0 */ |
3039 | if ((c->d & Priv) && ops->cpl(ctxt->vcpu)) { | 2971 | if ((c->d & Priv) && ops->cpl(ctxt->vcpu)) { |
3040 | emulate_gp(ctxt, 0); | 2972 | rc = emulate_gp(ctxt, 0); |
3041 | goto done; | 2973 | goto done; |
3042 | } | 2974 | } |
3043 | 2975 | ||
@@ -3050,7 +2982,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt) | |||
3050 | } | 2982 | } |
3051 | 2983 | ||
3052 | if ((c->src.type == OP_MEM) && !(c->d & NoAccess)) { | 2984 | if ((c->src.type == OP_MEM) && !(c->d & NoAccess)) { |
3053 | rc = read_emulated(ctxt, ops, c->src.addr.mem, | 2985 | rc = read_emulated(ctxt, ops, linear(ctxt, c->src.addr.mem), |
3054 | c->src.valptr, c->src.bytes); | 2986 | c->src.valptr, c->src.bytes); |
3055 | if (rc != X86EMUL_CONTINUE) | 2987 | if (rc != X86EMUL_CONTINUE) |
3056 | goto done; | 2988 | goto done; |
@@ -3058,7 +2990,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt) | |||
3058 | } | 2990 | } |
3059 | 2991 | ||
3060 | if (c->src2.type == OP_MEM) { | 2992 | if (c->src2.type == OP_MEM) { |
3061 | rc = read_emulated(ctxt, ops, c->src2.addr.mem, | 2993 | rc = read_emulated(ctxt, ops, linear(ctxt, c->src2.addr.mem), |
3062 | &c->src2.val, c->src2.bytes); | 2994 | &c->src2.val, c->src2.bytes); |
3063 | if (rc != X86EMUL_CONTINUE) | 2995 | if (rc != X86EMUL_CONTINUE) |
3064 | goto done; | 2996 | goto done; |
@@ -3070,7 +3002,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt) | |||
3070 | 3002 | ||
3071 | if ((c->dst.type == OP_MEM) && !(c->d & Mov)) { | 3003 | if ((c->dst.type == OP_MEM) && !(c->d & Mov)) { |
3072 | /* optimisation - avoid slow emulated read if Mov */ | 3004 | /* optimisation - avoid slow emulated read if Mov */ |
3073 | rc = read_emulated(ctxt, ops, c->dst.addr.mem, | 3005 | rc = read_emulated(ctxt, ops, linear(ctxt, c->dst.addr.mem), |
3074 | &c->dst.val, c->dst.bytes); | 3006 | &c->dst.val, c->dst.bytes); |
3075 | if (rc != X86EMUL_CONTINUE) | 3007 | if (rc != X86EMUL_CONTINUE) |
3076 | goto done; | 3008 | goto done; |
@@ -3215,13 +3147,13 @@ special_insn: | |||
3215 | break; | 3147 | break; |
3216 | case 0x8c: /* mov r/m, sreg */ | 3148 | case 0x8c: /* mov r/m, sreg */ |
3217 | if (c->modrm_reg > VCPU_SREG_GS) { | 3149 | if (c->modrm_reg > VCPU_SREG_GS) { |
3218 | emulate_ud(ctxt); | 3150 | rc = emulate_ud(ctxt); |
3219 | goto done; | 3151 | goto done; |
3220 | } | 3152 | } |
3221 | c->dst.val = ops->get_segment_selector(c->modrm_reg, ctxt->vcpu); | 3153 | c->dst.val = ops->get_segment_selector(c->modrm_reg, ctxt->vcpu); |
3222 | break; | 3154 | break; |
3223 | case 0x8d: /* lea r16/r32, m */ | 3155 | case 0x8d: /* lea r16/r32, m */ |
3224 | c->dst.val = c->src.addr.mem; | 3156 | c->dst.val = c->src.addr.mem.ea; |
3225 | break; | 3157 | break; |
3226 | case 0x8e: { /* mov seg, r/m16 */ | 3158 | case 0x8e: { /* mov seg, r/m16 */ |
3227 | uint16_t sel; | 3159 | uint16_t sel; |
@@ -3230,7 +3162,7 @@ special_insn: | |||
3230 | 3162 | ||
3231 | if (c->modrm_reg == VCPU_SREG_CS || | 3163 | if (c->modrm_reg == VCPU_SREG_CS || |
3232 | c->modrm_reg > VCPU_SREG_GS) { | 3164 | c->modrm_reg > VCPU_SREG_GS) { |
3233 | emulate_ud(ctxt); | 3165 | rc = emulate_ud(ctxt); |
3234 | goto done; | 3166 | goto done; |
3235 | } | 3167 | } |
3236 | 3168 | ||
@@ -3268,7 +3200,6 @@ special_insn: | |||
3268 | break; | 3200 | break; |
3269 | case 0xa6 ... 0xa7: /* cmps */ | 3201 | case 0xa6 ... 0xa7: /* cmps */ |
3270 | c->dst.type = OP_NONE; /* Disable writeback. */ | 3202 | c->dst.type = OP_NONE; /* Disable writeback. */ |
3271 | DPRINTF("cmps: mem1=0x%p mem2=0x%p\n", c->src.addr.mem, c->dst.addr.mem); | ||
3272 | goto cmp; | 3203 | goto cmp; |
3273 | case 0xa8 ... 0xa9: /* test ax, imm */ | 3204 | case 0xa8 ... 0xa9: /* test ax, imm */ |
3274 | goto test; | 3205 | goto test; |
@@ -3363,7 +3294,7 @@ special_insn: | |||
3363 | do_io_in: | 3294 | do_io_in: |
3364 | c->dst.bytes = min(c->dst.bytes, 4u); | 3295 | c->dst.bytes = min(c->dst.bytes, 4u); |
3365 | if (!emulator_io_permited(ctxt, ops, c->src.val, c->dst.bytes)) { | 3296 | if (!emulator_io_permited(ctxt, ops, c->src.val, c->dst.bytes)) { |
3366 | emulate_gp(ctxt, 0); | 3297 | rc = emulate_gp(ctxt, 0); |
3367 | goto done; | 3298 | goto done; |
3368 | } | 3299 | } |
3369 | if (!pio_in_emulated(ctxt, ops, c->dst.bytes, c->src.val, | 3300 | if (!pio_in_emulated(ctxt, ops, c->dst.bytes, c->src.val, |
@@ -3377,7 +3308,7 @@ special_insn: | |||
3377 | c->src.bytes = min(c->src.bytes, 4u); | 3308 | c->src.bytes = min(c->src.bytes, 4u); |
3378 | if (!emulator_io_permited(ctxt, ops, c->dst.val, | 3309 | if (!emulator_io_permited(ctxt, ops, c->dst.val, |
3379 | c->src.bytes)) { | 3310 | c->src.bytes)) { |
3380 | emulate_gp(ctxt, 0); | 3311 | rc = emulate_gp(ctxt, 0); |
3381 | goto done; | 3312 | goto done; |
3382 | } | 3313 | } |
3383 | ops->pio_out_emulated(c->src.bytes, c->dst.val, | 3314 | ops->pio_out_emulated(c->src.bytes, c->dst.val, |
@@ -3402,14 +3333,14 @@ special_insn: | |||
3402 | break; | 3333 | break; |
3403 | case 0xfa: /* cli */ | 3334 | case 0xfa: /* cli */ |
3404 | if (emulator_bad_iopl(ctxt, ops)) { | 3335 | if (emulator_bad_iopl(ctxt, ops)) { |
3405 | emulate_gp(ctxt, 0); | 3336 | rc = emulate_gp(ctxt, 0); |
3406 | goto done; | 3337 | goto done; |
3407 | } else | 3338 | } else |
3408 | ctxt->eflags &= ~X86_EFLAGS_IF; | 3339 | ctxt->eflags &= ~X86_EFLAGS_IF; |
3409 | break; | 3340 | break; |
3410 | case 0xfb: /* sti */ | 3341 | case 0xfb: /* sti */ |
3411 | if (emulator_bad_iopl(ctxt, ops)) { | 3342 | if (emulator_bad_iopl(ctxt, ops)) { |
3412 | emulate_gp(ctxt, 0); | 3343 | rc = emulate_gp(ctxt, 0); |
3413 | goto done; | 3344 | goto done; |
3414 | } else { | 3345 | } else { |
3415 | ctxt->interruptibility = KVM_X86_SHADOW_INT_STI; | 3346 | ctxt->interruptibility = KVM_X86_SHADOW_INT_STI; |
@@ -3449,11 +3380,11 @@ writeback: | |||
3449 | c->dst.type = saved_dst_type; | 3380 | c->dst.type = saved_dst_type; |
3450 | 3381 | ||
3451 | if ((c->d & SrcMask) == SrcSI) | 3382 | if ((c->d & SrcMask) == SrcSI) |
3452 | string_addr_inc(ctxt, seg_override_base(ctxt, ops, c), | 3383 | string_addr_inc(ctxt, seg_override(ctxt, ops, c), |
3453 | VCPU_REGS_RSI, &c->src); | 3384 | VCPU_REGS_RSI, &c->src); |
3454 | 3385 | ||
3455 | if ((c->d & DstMask) == DstDI) | 3386 | if ((c->d & DstMask) == DstDI) |
3456 | string_addr_inc(ctxt, es_base(ctxt, ops), VCPU_REGS_RDI, | 3387 | string_addr_inc(ctxt, VCPU_SREG_ES, VCPU_REGS_RDI, |
3457 | &c->dst); | 3388 | &c->dst); |
3458 | 3389 | ||
3459 | if (c->rep_prefix && (c->d & String)) { | 3390 | if (c->rep_prefix && (c->d & String)) { |
@@ -3482,6 +3413,8 @@ writeback: | |||
3482 | ctxt->eip = c->eip; | 3413 | ctxt->eip = c->eip; |
3483 | 3414 | ||
3484 | done: | 3415 | done: |
3416 | if (rc == X86EMUL_PROPAGATE_FAULT) | ||
3417 | ctxt->have_exception = true; | ||
3485 | return (rc == X86EMUL_UNHANDLEABLE) ? EMULATION_FAILED : EMULATION_OK; | 3418 | return (rc == X86EMUL_UNHANDLEABLE) ? EMULATION_FAILED : EMULATION_OK; |
3486 | 3419 | ||
3487 | twobyte_insn: | 3420 | twobyte_insn: |
@@ -3544,9 +3477,11 @@ twobyte_insn: | |||
3544 | break; | 3477 | break; |
3545 | case 5: /* not defined */ | 3478 | case 5: /* not defined */ |
3546 | emulate_ud(ctxt); | 3479 | emulate_ud(ctxt); |
3480 | rc = X86EMUL_PROPAGATE_FAULT; | ||
3547 | goto done; | 3481 | goto done; |
3548 | case 7: /* invlpg*/ | 3482 | case 7: /* invlpg*/ |
3549 | emulate_invlpg(ctxt->vcpu, c->src.addr.mem); | 3483 | emulate_invlpg(ctxt->vcpu, |
3484 | linear(ctxt, c->src.addr.mem)); | ||
3550 | /* Disable writeback. */ | 3485 | /* Disable writeback. */ |
3551 | c->dst.type = OP_NONE; | 3486 | c->dst.type = OP_NONE; |
3552 | break; | 3487 | break; |
@@ -3573,6 +3508,7 @@ twobyte_insn: | |||
3573 | case 5 ... 7: | 3508 | case 5 ... 7: |
3574 | case 9 ... 15: | 3509 | case 9 ... 15: |
3575 | emulate_ud(ctxt); | 3510 | emulate_ud(ctxt); |
3511 | rc = X86EMUL_PROPAGATE_FAULT; | ||
3576 | goto done; | 3512 | goto done; |
3577 | } | 3513 | } |
3578 | c->dst.val = ops->get_cr(c->modrm_reg, ctxt->vcpu); | 3514 | c->dst.val = ops->get_cr(c->modrm_reg, ctxt->vcpu); |
@@ -3581,6 +3517,7 @@ twobyte_insn: | |||
3581 | if ((ops->get_cr(4, ctxt->vcpu) & X86_CR4_DE) && | 3517 | if ((ops->get_cr(4, ctxt->vcpu) & X86_CR4_DE) && |
3582 | (c->modrm_reg == 4 || c->modrm_reg == 5)) { | 3518 | (c->modrm_reg == 4 || c->modrm_reg == 5)) { |
3583 | emulate_ud(ctxt); | 3519 | emulate_ud(ctxt); |
3520 | rc = X86EMUL_PROPAGATE_FAULT; | ||
3584 | goto done; | 3521 | goto done; |
3585 | } | 3522 | } |
3586 | ops->get_dr(c->modrm_reg, &c->dst.val, ctxt->vcpu); | 3523 | ops->get_dr(c->modrm_reg, &c->dst.val, ctxt->vcpu); |
@@ -3588,6 +3525,7 @@ twobyte_insn: | |||
3588 | case 0x22: /* mov reg, cr */ | 3525 | case 0x22: /* mov reg, cr */ |
3589 | if (ops->set_cr(c->modrm_reg, c->src.val, ctxt->vcpu)) { | 3526 | if (ops->set_cr(c->modrm_reg, c->src.val, ctxt->vcpu)) { |
3590 | emulate_gp(ctxt, 0); | 3527 | emulate_gp(ctxt, 0); |
3528 | rc = X86EMUL_PROPAGATE_FAULT; | ||
3591 | goto done; | 3529 | goto done; |
3592 | } | 3530 | } |
3593 | c->dst.type = OP_NONE; | 3531 | c->dst.type = OP_NONE; |
@@ -3596,6 +3534,7 @@ twobyte_insn: | |||
3596 | if ((ops->get_cr(4, ctxt->vcpu) & X86_CR4_DE) && | 3534 | if ((ops->get_cr(4, ctxt->vcpu) & X86_CR4_DE) && |
3597 | (c->modrm_reg == 4 || c->modrm_reg == 5)) { | 3535 | (c->modrm_reg == 4 || c->modrm_reg == 5)) { |
3598 | emulate_ud(ctxt); | 3536 | emulate_ud(ctxt); |
3537 | rc = X86EMUL_PROPAGATE_FAULT; | ||
3599 | goto done; | 3538 | goto done; |
3600 | } | 3539 | } |
3601 | 3540 | ||
@@ -3604,6 +3543,7 @@ twobyte_insn: | |||
3604 | ~0ULL : ~0U), ctxt->vcpu) < 0) { | 3543 | ~0ULL : ~0U), ctxt->vcpu) < 0) { |
3605 | /* #UD condition is already handled by the code above */ | 3544 | /* #UD condition is already handled by the code above */ |
3606 | emulate_gp(ctxt, 0); | 3545 | emulate_gp(ctxt, 0); |
3546 | rc = X86EMUL_PROPAGATE_FAULT; | ||
3607 | goto done; | 3547 | goto done; |
3608 | } | 3548 | } |
3609 | 3549 | ||
@@ -3615,6 +3555,7 @@ twobyte_insn: | |||
3615 | | ((u64)c->regs[VCPU_REGS_RDX] << 32); | 3555 | | ((u64)c->regs[VCPU_REGS_RDX] << 32); |
3616 | if (ops->set_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], msr_data)) { | 3556 | if (ops->set_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], msr_data)) { |
3617 | emulate_gp(ctxt, 0); | 3557 | emulate_gp(ctxt, 0); |
3558 | rc = X86EMUL_PROPAGATE_FAULT; | ||
3618 | goto done; | 3559 | goto done; |
3619 | } | 3560 | } |
3620 | rc = X86EMUL_CONTINUE; | 3561 | rc = X86EMUL_CONTINUE; |
@@ -3623,6 +3564,7 @@ twobyte_insn: | |||
3623 | /* rdmsr */ | 3564 | /* rdmsr */ |
3624 | if (ops->get_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], &msr_data)) { | 3565 | if (ops->get_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], &msr_data)) { |
3625 | emulate_gp(ctxt, 0); | 3566 | emulate_gp(ctxt, 0); |
3567 | rc = X86EMUL_PROPAGATE_FAULT; | ||
3626 | goto done; | 3568 | goto done; |
3627 | } else { | 3569 | } else { |
3628 | c->regs[VCPU_REGS_RAX] = (u32)msr_data; | 3570 | c->regs[VCPU_REGS_RAX] = (u32)msr_data; |
@@ -3785,6 +3727,5 @@ twobyte_insn: | |||
3785 | goto writeback; | 3727 | goto writeback; |
3786 | 3728 | ||
3787 | cannot_emulate: | 3729 | cannot_emulate: |
3788 | DPRINTF("Cannot emulate %02x\n", c->b); | ||
3789 | return -1; | 3730 | return -1; |
3790 | } | 3731 | } |
diff --git a/arch/x86/kvm/kvm_cache_regs.h b/arch/x86/kvm/kvm_cache_regs.h index 975bb45329a1..3377d53fcd36 100644 --- a/arch/x86/kvm/kvm_cache_regs.h +++ b/arch/x86/kvm/kvm_cache_regs.h | |||
@@ -73,6 +73,13 @@ static inline ulong kvm_read_cr4_bits(struct kvm_vcpu *vcpu, ulong mask) | |||
73 | return vcpu->arch.cr4 & mask; | 73 | return vcpu->arch.cr4 & mask; |
74 | } | 74 | } |
75 | 75 | ||
76 | static inline ulong kvm_read_cr3(struct kvm_vcpu *vcpu) | ||
77 | { | ||
78 | if (!test_bit(VCPU_EXREG_CR3, (ulong *)&vcpu->arch.regs_avail)) | ||
79 | kvm_x86_ops->decache_cr3(vcpu); | ||
80 | return vcpu->arch.cr3; | ||
81 | } | ||
82 | |||
76 | static inline ulong kvm_read_cr4(struct kvm_vcpu *vcpu) | 83 | static inline ulong kvm_read_cr4(struct kvm_vcpu *vcpu) |
77 | { | 84 | { |
78 | return kvm_read_cr4_bits(vcpu, ~0UL); | 85 | return kvm_read_cr4_bits(vcpu, ~0UL); |
@@ -84,4 +91,19 @@ static inline u64 kvm_read_edx_eax(struct kvm_vcpu *vcpu) | |||
84 | | ((u64)(kvm_register_read(vcpu, VCPU_REGS_RDX) & -1u) << 32); | 91 | | ((u64)(kvm_register_read(vcpu, VCPU_REGS_RDX) & -1u) << 32); |
85 | } | 92 | } |
86 | 93 | ||
94 | static inline void enter_guest_mode(struct kvm_vcpu *vcpu) | ||
95 | { | ||
96 | vcpu->arch.hflags |= HF_GUEST_MASK; | ||
97 | } | ||
98 | |||
99 | static inline void leave_guest_mode(struct kvm_vcpu *vcpu) | ||
100 | { | ||
101 | vcpu->arch.hflags &= ~HF_GUEST_MASK; | ||
102 | } | ||
103 | |||
104 | static inline bool is_guest_mode(struct kvm_vcpu *vcpu) | ||
105 | { | ||
106 | return vcpu->arch.hflags & HF_GUEST_MASK; | ||
107 | } | ||
108 | |||
87 | #endif | 109 | #endif |
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 413f8973a855..93cf9d0d3653 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c | |||
@@ -277,7 +277,8 @@ static void apic_update_ppr(struct kvm_lapic *apic) | |||
277 | 277 | ||
278 | if (old_ppr != ppr) { | 278 | if (old_ppr != ppr) { |
279 | apic_set_reg(apic, APIC_PROCPRI, ppr); | 279 | apic_set_reg(apic, APIC_PROCPRI, ppr); |
280 | kvm_make_request(KVM_REQ_EVENT, apic->vcpu); | 280 | if (ppr < old_ppr) |
281 | kvm_make_request(KVM_REQ_EVENT, apic->vcpu); | ||
281 | } | 282 | } |
282 | } | 283 | } |
283 | 284 | ||
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index fbb04aee8301..f02b8edc3d44 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
@@ -18,9 +18,11 @@ | |||
18 | * | 18 | * |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include "irq.h" | ||
21 | #include "mmu.h" | 22 | #include "mmu.h" |
22 | #include "x86.h" | 23 | #include "x86.h" |
23 | #include "kvm_cache_regs.h" | 24 | #include "kvm_cache_regs.h" |
25 | #include "x86.h" | ||
24 | 26 | ||
25 | #include <linux/kvm_host.h> | 27 | #include <linux/kvm_host.h> |
26 | #include <linux/types.h> | 28 | #include <linux/types.h> |
@@ -194,7 +196,6 @@ static struct percpu_counter kvm_total_used_mmu_pages; | |||
194 | 196 | ||
195 | static u64 __read_mostly shadow_trap_nonpresent_pte; | 197 | static u64 __read_mostly shadow_trap_nonpresent_pte; |
196 | static u64 __read_mostly shadow_notrap_nonpresent_pte; | 198 | static u64 __read_mostly shadow_notrap_nonpresent_pte; |
197 | static u64 __read_mostly shadow_base_present_pte; | ||
198 | static u64 __read_mostly shadow_nx_mask; | 199 | static u64 __read_mostly shadow_nx_mask; |
199 | static u64 __read_mostly shadow_x_mask; /* mutual exclusive with nx_mask */ | 200 | static u64 __read_mostly shadow_x_mask; /* mutual exclusive with nx_mask */ |
200 | static u64 __read_mostly shadow_user_mask; | 201 | static u64 __read_mostly shadow_user_mask; |
@@ -213,12 +214,6 @@ void kvm_mmu_set_nonpresent_ptes(u64 trap_pte, u64 notrap_pte) | |||
213 | } | 214 | } |
214 | EXPORT_SYMBOL_GPL(kvm_mmu_set_nonpresent_ptes); | 215 | EXPORT_SYMBOL_GPL(kvm_mmu_set_nonpresent_ptes); |
215 | 216 | ||
216 | void kvm_mmu_set_base_ptes(u64 base_pte) | ||
217 | { | ||
218 | shadow_base_present_pte = base_pte; | ||
219 | } | ||
220 | EXPORT_SYMBOL_GPL(kvm_mmu_set_base_ptes); | ||
221 | |||
222 | void kvm_mmu_set_mask_ptes(u64 user_mask, u64 accessed_mask, | 217 | void kvm_mmu_set_mask_ptes(u64 user_mask, u64 accessed_mask, |
223 | u64 dirty_mask, u64 nx_mask, u64 x_mask) | 218 | u64 dirty_mask, u64 nx_mask, u64 x_mask) |
224 | { | 219 | { |
@@ -482,46 +477,46 @@ static void kvm_mmu_page_set_gfn(struct kvm_mmu_page *sp, int index, gfn_t gfn) | |||
482 | } | 477 | } |
483 | 478 | ||
484 | /* | 479 | /* |
485 | * Return the pointer to the largepage write count for a given | 480 | * Return the pointer to the large page information for a given gfn, |
486 | * gfn, handling slots that are not large page aligned. | 481 | * handling slots that are not large page aligned. |
487 | */ | 482 | */ |
488 | static int *slot_largepage_idx(gfn_t gfn, | 483 | static struct kvm_lpage_info *lpage_info_slot(gfn_t gfn, |
489 | struct kvm_memory_slot *slot, | 484 | struct kvm_memory_slot *slot, |
490 | int level) | 485 | int level) |
491 | { | 486 | { |
492 | unsigned long idx; | 487 | unsigned long idx; |
493 | 488 | ||
494 | idx = (gfn >> KVM_HPAGE_GFN_SHIFT(level)) - | 489 | idx = (gfn >> KVM_HPAGE_GFN_SHIFT(level)) - |
495 | (slot->base_gfn >> KVM_HPAGE_GFN_SHIFT(level)); | 490 | (slot->base_gfn >> KVM_HPAGE_GFN_SHIFT(level)); |
496 | return &slot->lpage_info[level - 2][idx].write_count; | 491 | return &slot->lpage_info[level - 2][idx]; |
497 | } | 492 | } |
498 | 493 | ||
499 | static void account_shadowed(struct kvm *kvm, gfn_t gfn) | 494 | static void account_shadowed(struct kvm *kvm, gfn_t gfn) |
500 | { | 495 | { |
501 | struct kvm_memory_slot *slot; | 496 | struct kvm_memory_slot *slot; |
502 | int *write_count; | 497 | struct kvm_lpage_info *linfo; |
503 | int i; | 498 | int i; |
504 | 499 | ||
505 | slot = gfn_to_memslot(kvm, gfn); | 500 | slot = gfn_to_memslot(kvm, gfn); |
506 | for (i = PT_DIRECTORY_LEVEL; | 501 | for (i = PT_DIRECTORY_LEVEL; |
507 | i < PT_PAGE_TABLE_LEVEL + KVM_NR_PAGE_SIZES; ++i) { | 502 | i < PT_PAGE_TABLE_LEVEL + KVM_NR_PAGE_SIZES; ++i) { |
508 | write_count = slot_largepage_idx(gfn, slot, i); | 503 | linfo = lpage_info_slot(gfn, slot, i); |
509 | *write_count += 1; | 504 | linfo->write_count += 1; |
510 | } | 505 | } |
511 | } | 506 | } |
512 | 507 | ||
513 | static void unaccount_shadowed(struct kvm *kvm, gfn_t gfn) | 508 | static void unaccount_shadowed(struct kvm *kvm, gfn_t gfn) |
514 | { | 509 | { |
515 | struct kvm_memory_slot *slot; | 510 | struct kvm_memory_slot *slot; |
516 | int *write_count; | 511 | struct kvm_lpage_info *linfo; |
517 | int i; | 512 | int i; |
518 | 513 | ||
519 | slot = gfn_to_memslot(kvm, gfn); | 514 | slot = gfn_to_memslot(kvm, gfn); |
520 | for (i = PT_DIRECTORY_LEVEL; | 515 | for (i = PT_DIRECTORY_LEVEL; |
521 | i < PT_PAGE_TABLE_LEVEL + KVM_NR_PAGE_SIZES; ++i) { | 516 | i < PT_PAGE_TABLE_LEVEL + KVM_NR_PAGE_SIZES; ++i) { |
522 | write_count = slot_largepage_idx(gfn, slot, i); | 517 | linfo = lpage_info_slot(gfn, slot, i); |
523 | *write_count -= 1; | 518 | linfo->write_count -= 1; |
524 | WARN_ON(*write_count < 0); | 519 | WARN_ON(linfo->write_count < 0); |
525 | } | 520 | } |
526 | } | 521 | } |
527 | 522 | ||
@@ -530,12 +525,12 @@ static int has_wrprotected_page(struct kvm *kvm, | |||
530 | int level) | 525 | int level) |
531 | { | 526 | { |
532 | struct kvm_memory_slot *slot; | 527 | struct kvm_memory_slot *slot; |
533 | int *largepage_idx; | 528 | struct kvm_lpage_info *linfo; |
534 | 529 | ||
535 | slot = gfn_to_memslot(kvm, gfn); | 530 | slot = gfn_to_memslot(kvm, gfn); |
536 | if (slot) { | 531 | if (slot) { |
537 | largepage_idx = slot_largepage_idx(gfn, slot, level); | 532 | linfo = lpage_info_slot(gfn, slot, level); |
538 | return *largepage_idx; | 533 | return linfo->write_count; |
539 | } | 534 | } |
540 | 535 | ||
541 | return 1; | 536 | return 1; |
@@ -559,14 +554,18 @@ static int host_mapping_level(struct kvm *kvm, gfn_t gfn) | |||
559 | return ret; | 554 | return ret; |
560 | } | 555 | } |
561 | 556 | ||
562 | static int mapping_level(struct kvm_vcpu *vcpu, gfn_t large_gfn) | 557 | static bool mapping_level_dirty_bitmap(struct kvm_vcpu *vcpu, gfn_t large_gfn) |
563 | { | 558 | { |
564 | struct kvm_memory_slot *slot; | 559 | struct kvm_memory_slot *slot; |
565 | int host_level, level, max_level; | ||
566 | |||
567 | slot = gfn_to_memslot(vcpu->kvm, large_gfn); | 560 | slot = gfn_to_memslot(vcpu->kvm, large_gfn); |
568 | if (slot && slot->dirty_bitmap) | 561 | if (slot && slot->dirty_bitmap) |
569 | return PT_PAGE_TABLE_LEVEL; | 562 | return true; |
563 | return false; | ||
564 | } | ||
565 | |||
566 | static int mapping_level(struct kvm_vcpu *vcpu, gfn_t large_gfn) | ||
567 | { | ||
568 | int host_level, level, max_level; | ||
570 | 569 | ||
571 | host_level = host_mapping_level(vcpu->kvm, large_gfn); | 570 | host_level = host_mapping_level(vcpu->kvm, large_gfn); |
572 | 571 | ||
@@ -590,16 +589,15 @@ static int mapping_level(struct kvm_vcpu *vcpu, gfn_t large_gfn) | |||
590 | static unsigned long *gfn_to_rmap(struct kvm *kvm, gfn_t gfn, int level) | 589 | static unsigned long *gfn_to_rmap(struct kvm *kvm, gfn_t gfn, int level) |
591 | { | 590 | { |
592 | struct kvm_memory_slot *slot; | 591 | struct kvm_memory_slot *slot; |
593 | unsigned long idx; | 592 | struct kvm_lpage_info *linfo; |
594 | 593 | ||
595 | slot = gfn_to_memslot(kvm, gfn); | 594 | slot = gfn_to_memslot(kvm, gfn); |
596 | if (likely(level == PT_PAGE_TABLE_LEVEL)) | 595 | if (likely(level == PT_PAGE_TABLE_LEVEL)) |
597 | return &slot->rmap[gfn - slot->base_gfn]; | 596 | return &slot->rmap[gfn - slot->base_gfn]; |
598 | 597 | ||
599 | idx = (gfn >> KVM_HPAGE_GFN_SHIFT(level)) - | 598 | linfo = lpage_info_slot(gfn, slot, level); |
600 | (slot->base_gfn >> KVM_HPAGE_GFN_SHIFT(level)); | ||
601 | 599 | ||
602 | return &slot->lpage_info[level - 2][idx].rmap_pde; | 600 | return &linfo->rmap_pde; |
603 | } | 601 | } |
604 | 602 | ||
605 | /* | 603 | /* |
@@ -887,19 +885,16 @@ static int kvm_handle_hva(struct kvm *kvm, unsigned long hva, | |||
887 | end = start + (memslot->npages << PAGE_SHIFT); | 885 | end = start + (memslot->npages << PAGE_SHIFT); |
888 | if (hva >= start && hva < end) { | 886 | if (hva >= start && hva < end) { |
889 | gfn_t gfn_offset = (hva - start) >> PAGE_SHIFT; | 887 | gfn_t gfn_offset = (hva - start) >> PAGE_SHIFT; |
888 | gfn_t gfn = memslot->base_gfn + gfn_offset; | ||
890 | 889 | ||
891 | ret = handler(kvm, &memslot->rmap[gfn_offset], data); | 890 | ret = handler(kvm, &memslot->rmap[gfn_offset], data); |
892 | 891 | ||
893 | for (j = 0; j < KVM_NR_PAGE_SIZES - 1; ++j) { | 892 | for (j = 0; j < KVM_NR_PAGE_SIZES - 1; ++j) { |
894 | unsigned long idx; | 893 | struct kvm_lpage_info *linfo; |
895 | int sh; | 894 | |
896 | 895 | linfo = lpage_info_slot(gfn, memslot, | |
897 | sh = KVM_HPAGE_GFN_SHIFT(PT_DIRECTORY_LEVEL+j); | 896 | PT_DIRECTORY_LEVEL + j); |
898 | idx = ((memslot->base_gfn+gfn_offset) >> sh) - | 897 | ret |= handler(kvm, &linfo->rmap_pde, data); |
899 | (memslot->base_gfn >> sh); | ||
900 | ret |= handler(kvm, | ||
901 | &memslot->lpage_info[j][idx].rmap_pde, | ||
902 | data); | ||
903 | } | 898 | } |
904 | trace_kvm_age_page(hva, memslot, ret); | 899 | trace_kvm_age_page(hva, memslot, ret); |
905 | retval |= ret; | 900 | retval |= ret; |
@@ -950,6 +945,35 @@ static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp, | |||
950 | return young; | 945 | return young; |
951 | } | 946 | } |
952 | 947 | ||
948 | static int kvm_test_age_rmapp(struct kvm *kvm, unsigned long *rmapp, | ||
949 | unsigned long data) | ||
950 | { | ||
951 | u64 *spte; | ||
952 | int young = 0; | ||
953 | |||
954 | /* | ||
955 | * If there's no access bit in the secondary pte set by the | ||
956 | * hardware it's up to gup-fast/gup to set the access bit in | ||
957 | * the primary pte or in the page structure. | ||
958 | */ | ||
959 | if (!shadow_accessed_mask) | ||
960 | goto out; | ||
961 | |||
962 | spte = rmap_next(kvm, rmapp, NULL); | ||
963 | while (spte) { | ||
964 | u64 _spte = *spte; | ||
965 | BUG_ON(!(_spte & PT_PRESENT_MASK)); | ||
966 | young = _spte & PT_ACCESSED_MASK; | ||
967 | if (young) { | ||
968 | young = 1; | ||
969 | break; | ||
970 | } | ||
971 | spte = rmap_next(kvm, rmapp, spte); | ||
972 | } | ||
973 | out: | ||
974 | return young; | ||
975 | } | ||
976 | |||
953 | #define RMAP_RECYCLE_THRESHOLD 1000 | 977 | #define RMAP_RECYCLE_THRESHOLD 1000 |
954 | 978 | ||
955 | static void rmap_recycle(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn) | 979 | static void rmap_recycle(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn) |
@@ -970,6 +994,11 @@ int kvm_age_hva(struct kvm *kvm, unsigned long hva) | |||
970 | return kvm_handle_hva(kvm, hva, 0, kvm_age_rmapp); | 994 | return kvm_handle_hva(kvm, hva, 0, kvm_age_rmapp); |
971 | } | 995 | } |
972 | 996 | ||
997 | int kvm_test_age_hva(struct kvm *kvm, unsigned long hva) | ||
998 | { | ||
999 | return kvm_handle_hva(kvm, hva, 0, kvm_test_age_rmapp); | ||
1000 | } | ||
1001 | |||
973 | #ifdef MMU_DEBUG | 1002 | #ifdef MMU_DEBUG |
974 | static int is_empty_shadow_page(u64 *spt) | 1003 | static int is_empty_shadow_page(u64 *spt) |
975 | { | 1004 | { |
@@ -1161,7 +1190,7 @@ static void nonpaging_prefetch_page(struct kvm_vcpu *vcpu, | |||
1161 | } | 1190 | } |
1162 | 1191 | ||
1163 | static int nonpaging_sync_page(struct kvm_vcpu *vcpu, | 1192 | static int nonpaging_sync_page(struct kvm_vcpu *vcpu, |
1164 | struct kvm_mmu_page *sp, bool clear_unsync) | 1193 | struct kvm_mmu_page *sp) |
1165 | { | 1194 | { |
1166 | return 1; | 1195 | return 1; |
1167 | } | 1196 | } |
@@ -1291,7 +1320,7 @@ static int __kvm_sync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, | |||
1291 | if (clear_unsync) | 1320 | if (clear_unsync) |
1292 | kvm_unlink_unsync_page(vcpu->kvm, sp); | 1321 | kvm_unlink_unsync_page(vcpu->kvm, sp); |
1293 | 1322 | ||
1294 | if (vcpu->arch.mmu.sync_page(vcpu, sp, clear_unsync)) { | 1323 | if (vcpu->arch.mmu.sync_page(vcpu, sp)) { |
1295 | kvm_mmu_prepare_zap_page(vcpu->kvm, sp, invalid_list); | 1324 | kvm_mmu_prepare_zap_page(vcpu->kvm, sp, invalid_list); |
1296 | return 1; | 1325 | return 1; |
1297 | } | 1326 | } |
@@ -1332,12 +1361,12 @@ static void kvm_sync_pages(struct kvm_vcpu *vcpu, gfn_t gfn) | |||
1332 | continue; | 1361 | continue; |
1333 | 1362 | ||
1334 | WARN_ON(s->role.level != PT_PAGE_TABLE_LEVEL); | 1363 | WARN_ON(s->role.level != PT_PAGE_TABLE_LEVEL); |
1364 | kvm_unlink_unsync_page(vcpu->kvm, s); | ||
1335 | if ((s->role.cr4_pae != !!is_pae(vcpu)) || | 1365 | if ((s->role.cr4_pae != !!is_pae(vcpu)) || |
1336 | (vcpu->arch.mmu.sync_page(vcpu, s, true))) { | 1366 | (vcpu->arch.mmu.sync_page(vcpu, s))) { |
1337 | kvm_mmu_prepare_zap_page(vcpu->kvm, s, &invalid_list); | 1367 | kvm_mmu_prepare_zap_page(vcpu->kvm, s, &invalid_list); |
1338 | continue; | 1368 | continue; |
1339 | } | 1369 | } |
1340 | kvm_unlink_unsync_page(vcpu->kvm, s); | ||
1341 | flush = true; | 1370 | flush = true; |
1342 | } | 1371 | } |
1343 | 1372 | ||
@@ -1963,9 +1992,9 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep, | |||
1963 | unsigned pte_access, int user_fault, | 1992 | unsigned pte_access, int user_fault, |
1964 | int write_fault, int dirty, int level, | 1993 | int write_fault, int dirty, int level, |
1965 | gfn_t gfn, pfn_t pfn, bool speculative, | 1994 | gfn_t gfn, pfn_t pfn, bool speculative, |
1966 | bool can_unsync, bool reset_host_protection) | 1995 | bool can_unsync, bool host_writable) |
1967 | { | 1996 | { |
1968 | u64 spte; | 1997 | u64 spte, entry = *sptep; |
1969 | int ret = 0; | 1998 | int ret = 0; |
1970 | 1999 | ||
1971 | /* | 2000 | /* |
@@ -1973,7 +2002,7 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep, | |||
1973 | * whether the guest actually used the pte (in order to detect | 2002 | * whether the guest actually used the pte (in order to detect |
1974 | * demand paging). | 2003 | * demand paging). |
1975 | */ | 2004 | */ |
1976 | spte = shadow_base_present_pte; | 2005 | spte = PT_PRESENT_MASK; |
1977 | if (!speculative) | 2006 | if (!speculative) |
1978 | spte |= shadow_accessed_mask; | 2007 | spte |= shadow_accessed_mask; |
1979 | if (!dirty) | 2008 | if (!dirty) |
@@ -1990,8 +2019,10 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep, | |||
1990 | spte |= kvm_x86_ops->get_mt_mask(vcpu, gfn, | 2019 | spte |= kvm_x86_ops->get_mt_mask(vcpu, gfn, |
1991 | kvm_is_mmio_pfn(pfn)); | 2020 | kvm_is_mmio_pfn(pfn)); |
1992 | 2021 | ||
1993 | if (reset_host_protection) | 2022 | if (host_writable) |
1994 | spte |= SPTE_HOST_WRITEABLE; | 2023 | spte |= SPTE_HOST_WRITEABLE; |
2024 | else | ||
2025 | pte_access &= ~ACC_WRITE_MASK; | ||
1995 | 2026 | ||
1996 | spte |= (u64)pfn << PAGE_SHIFT; | 2027 | spte |= (u64)pfn << PAGE_SHIFT; |
1997 | 2028 | ||
@@ -2036,6 +2067,14 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep, | |||
2036 | 2067 | ||
2037 | set_pte: | 2068 | set_pte: |
2038 | update_spte(sptep, spte); | 2069 | update_spte(sptep, spte); |
2070 | /* | ||
2071 | * If we overwrite a writable spte with a read-only one we | ||
2072 | * should flush remote TLBs. Otherwise rmap_write_protect | ||
2073 | * will find a read-only spte, even though the writable spte | ||
2074 | * might be cached on a CPU's TLB. | ||
2075 | */ | ||
2076 | if (is_writable_pte(entry) && !is_writable_pte(*sptep)) | ||
2077 | kvm_flush_remote_tlbs(vcpu->kvm); | ||
2039 | done: | 2078 | done: |
2040 | return ret; | 2079 | return ret; |
2041 | } | 2080 | } |
@@ -2045,7 +2084,7 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep, | |||
2045 | int user_fault, int write_fault, int dirty, | 2084 | int user_fault, int write_fault, int dirty, |
2046 | int *ptwrite, int level, gfn_t gfn, | 2085 | int *ptwrite, int level, gfn_t gfn, |
2047 | pfn_t pfn, bool speculative, | 2086 | pfn_t pfn, bool speculative, |
2048 | bool reset_host_protection) | 2087 | bool host_writable) |
2049 | { | 2088 | { |
2050 | int was_rmapped = 0; | 2089 | int was_rmapped = 0; |
2051 | int rmap_count; | 2090 | int rmap_count; |
@@ -2080,7 +2119,7 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep, | |||
2080 | 2119 | ||
2081 | if (set_spte(vcpu, sptep, pte_access, user_fault, write_fault, | 2120 | if (set_spte(vcpu, sptep, pte_access, user_fault, write_fault, |
2082 | dirty, level, gfn, pfn, speculative, true, | 2121 | dirty, level, gfn, pfn, speculative, true, |
2083 | reset_host_protection)) { | 2122 | host_writable)) { |
2084 | if (write_fault) | 2123 | if (write_fault) |
2085 | *ptwrite = 1; | 2124 | *ptwrite = 1; |
2086 | kvm_mmu_flush_tlb(vcpu); | 2125 | kvm_mmu_flush_tlb(vcpu); |
@@ -2211,7 +2250,8 @@ static void direct_pte_prefetch(struct kvm_vcpu *vcpu, u64 *sptep) | |||
2211 | } | 2250 | } |
2212 | 2251 | ||
2213 | static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write, | 2252 | static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write, |
2214 | int level, gfn_t gfn, pfn_t pfn) | 2253 | int map_writable, int level, gfn_t gfn, pfn_t pfn, |
2254 | bool prefault) | ||
2215 | { | 2255 | { |
2216 | struct kvm_shadow_walk_iterator iterator; | 2256 | struct kvm_shadow_walk_iterator iterator; |
2217 | struct kvm_mmu_page *sp; | 2257 | struct kvm_mmu_page *sp; |
@@ -2220,9 +2260,11 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write, | |||
2220 | 2260 | ||
2221 | for_each_shadow_entry(vcpu, (u64)gfn << PAGE_SHIFT, iterator) { | 2261 | for_each_shadow_entry(vcpu, (u64)gfn << PAGE_SHIFT, iterator) { |
2222 | if (iterator.level == level) { | 2262 | if (iterator.level == level) { |
2223 | mmu_set_spte(vcpu, iterator.sptep, ACC_ALL, ACC_ALL, | 2263 | unsigned pte_access = ACC_ALL; |
2264 | |||
2265 | mmu_set_spte(vcpu, iterator.sptep, ACC_ALL, pte_access, | ||
2224 | 0, write, 1, &pt_write, | 2266 | 0, write, 1, &pt_write, |
2225 | level, gfn, pfn, false, true); | 2267 | level, gfn, pfn, prefault, map_writable); |
2226 | direct_pte_prefetch(vcpu, iterator.sptep); | 2268 | direct_pte_prefetch(vcpu, iterator.sptep); |
2227 | ++vcpu->stat.pf_fixed; | 2269 | ++vcpu->stat.pf_fixed; |
2228 | break; | 2270 | break; |
@@ -2277,27 +2319,81 @@ static int kvm_handle_bad_page(struct kvm *kvm, gfn_t gfn, pfn_t pfn) | |||
2277 | return 1; | 2319 | return 1; |
2278 | } | 2320 | } |
2279 | 2321 | ||
2280 | static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn) | 2322 | static void transparent_hugepage_adjust(struct kvm_vcpu *vcpu, |
2323 | gfn_t *gfnp, pfn_t *pfnp, int *levelp) | ||
2324 | { | ||
2325 | pfn_t pfn = *pfnp; | ||
2326 | gfn_t gfn = *gfnp; | ||
2327 | int level = *levelp; | ||
2328 | |||
2329 | /* | ||
2330 | * Check if it's a transparent hugepage. If this would be an | ||
2331 | * hugetlbfs page, level wouldn't be set to | ||
2332 | * PT_PAGE_TABLE_LEVEL and there would be no adjustment done | ||
2333 | * here. | ||
2334 | */ | ||
2335 | if (!is_error_pfn(pfn) && !kvm_is_mmio_pfn(pfn) && | ||
2336 | level == PT_PAGE_TABLE_LEVEL && | ||
2337 | PageTransCompound(pfn_to_page(pfn)) && | ||
2338 | !has_wrprotected_page(vcpu->kvm, gfn, PT_DIRECTORY_LEVEL)) { | ||
2339 | unsigned long mask; | ||
2340 | /* | ||
2341 | * mmu_notifier_retry was successful and we hold the | ||
2342 | * mmu_lock here, so the pmd can't become splitting | ||
2343 | * from under us, and in turn | ||
2344 | * __split_huge_page_refcount() can't run from under | ||
2345 | * us and we can safely transfer the refcount from | ||
2346 | * PG_tail to PG_head as we switch the pfn to tail to | ||
2347 | * head. | ||
2348 | */ | ||
2349 | *levelp = level = PT_DIRECTORY_LEVEL; | ||
2350 | mask = KVM_PAGES_PER_HPAGE(level) - 1; | ||
2351 | VM_BUG_ON((gfn & mask) != (pfn & mask)); | ||
2352 | if (pfn & mask) { | ||
2353 | gfn &= ~mask; | ||
2354 | *gfnp = gfn; | ||
2355 | kvm_release_pfn_clean(pfn); | ||
2356 | pfn &= ~mask; | ||
2357 | if (!get_page_unless_zero(pfn_to_page(pfn))) | ||
2358 | BUG(); | ||
2359 | *pfnp = pfn; | ||
2360 | } | ||
2361 | } | ||
2362 | } | ||
2363 | |||
2364 | static bool try_async_pf(struct kvm_vcpu *vcpu, bool prefault, gfn_t gfn, | ||
2365 | gva_t gva, pfn_t *pfn, bool write, bool *writable); | ||
2366 | |||
2367 | static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn, | ||
2368 | bool prefault) | ||
2281 | { | 2369 | { |
2282 | int r; | 2370 | int r; |
2283 | int level; | 2371 | int level; |
2372 | int force_pt_level; | ||
2284 | pfn_t pfn; | 2373 | pfn_t pfn; |
2285 | unsigned long mmu_seq; | 2374 | unsigned long mmu_seq; |
2375 | bool map_writable; | ||
2286 | 2376 | ||
2287 | level = mapping_level(vcpu, gfn); | 2377 | force_pt_level = mapping_level_dirty_bitmap(vcpu, gfn); |
2288 | 2378 | if (likely(!force_pt_level)) { | |
2289 | /* | 2379 | level = mapping_level(vcpu, gfn); |
2290 | * This path builds a PAE pagetable - so we can map 2mb pages at | 2380 | /* |
2291 | * maximum. Therefore check if the level is larger than that. | 2381 | * This path builds a PAE pagetable - so we can map |
2292 | */ | 2382 | * 2mb pages at maximum. Therefore check if the level |
2293 | if (level > PT_DIRECTORY_LEVEL) | 2383 | * is larger than that. |
2294 | level = PT_DIRECTORY_LEVEL; | 2384 | */ |
2385 | if (level > PT_DIRECTORY_LEVEL) | ||
2386 | level = PT_DIRECTORY_LEVEL; | ||
2295 | 2387 | ||
2296 | gfn &= ~(KVM_PAGES_PER_HPAGE(level) - 1); | 2388 | gfn &= ~(KVM_PAGES_PER_HPAGE(level) - 1); |
2389 | } else | ||
2390 | level = PT_PAGE_TABLE_LEVEL; | ||
2297 | 2391 | ||
2298 | mmu_seq = vcpu->kvm->mmu_notifier_seq; | 2392 | mmu_seq = vcpu->kvm->mmu_notifier_seq; |
2299 | smp_rmb(); | 2393 | smp_rmb(); |
2300 | pfn = gfn_to_pfn(vcpu->kvm, gfn); | 2394 | |
2395 | if (try_async_pf(vcpu, prefault, gfn, v, &pfn, write, &map_writable)) | ||
2396 | return 0; | ||
2301 | 2397 | ||
2302 | /* mmio */ | 2398 | /* mmio */ |
2303 | if (is_error_pfn(pfn)) | 2399 | if (is_error_pfn(pfn)) |
@@ -2307,7 +2403,10 @@ static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn) | |||
2307 | if (mmu_notifier_retry(vcpu, mmu_seq)) | 2403 | if (mmu_notifier_retry(vcpu, mmu_seq)) |
2308 | goto out_unlock; | 2404 | goto out_unlock; |
2309 | kvm_mmu_free_some_pages(vcpu); | 2405 | kvm_mmu_free_some_pages(vcpu); |
2310 | r = __direct_map(vcpu, v, write, level, gfn, pfn); | 2406 | if (likely(!force_pt_level)) |
2407 | transparent_hugepage_adjust(vcpu, &gfn, &pfn, &level); | ||
2408 | r = __direct_map(vcpu, v, write, map_writable, level, gfn, pfn, | ||
2409 | prefault); | ||
2311 | spin_unlock(&vcpu->kvm->mmu_lock); | 2410 | spin_unlock(&vcpu->kvm->mmu_lock); |
2312 | 2411 | ||
2313 | 2412 | ||
@@ -2530,6 +2629,7 @@ static void mmu_sync_roots(struct kvm_vcpu *vcpu) | |||
2530 | hpa_t root = vcpu->arch.mmu.root_hpa; | 2629 | hpa_t root = vcpu->arch.mmu.root_hpa; |
2531 | sp = page_header(root); | 2630 | sp = page_header(root); |
2532 | mmu_sync_children(vcpu, sp); | 2631 | mmu_sync_children(vcpu, sp); |
2632 | trace_kvm_mmu_audit(vcpu, AUDIT_POST_SYNC); | ||
2533 | return; | 2633 | return; |
2534 | } | 2634 | } |
2535 | for (i = 0; i < 4; ++i) { | 2635 | for (i = 0; i < 4; ++i) { |
@@ -2552,23 +2652,24 @@ void kvm_mmu_sync_roots(struct kvm_vcpu *vcpu) | |||
2552 | } | 2652 | } |
2553 | 2653 | ||
2554 | static gpa_t nonpaging_gva_to_gpa(struct kvm_vcpu *vcpu, gva_t vaddr, | 2654 | static gpa_t nonpaging_gva_to_gpa(struct kvm_vcpu *vcpu, gva_t vaddr, |
2555 | u32 access, u32 *error) | 2655 | u32 access, struct x86_exception *exception) |
2556 | { | 2656 | { |
2557 | if (error) | 2657 | if (exception) |
2558 | *error = 0; | 2658 | exception->error_code = 0; |
2559 | return vaddr; | 2659 | return vaddr; |
2560 | } | 2660 | } |
2561 | 2661 | ||
2562 | static gpa_t nonpaging_gva_to_gpa_nested(struct kvm_vcpu *vcpu, gva_t vaddr, | 2662 | static gpa_t nonpaging_gva_to_gpa_nested(struct kvm_vcpu *vcpu, gva_t vaddr, |
2563 | u32 access, u32 *error) | 2663 | u32 access, |
2664 | struct x86_exception *exception) | ||
2564 | { | 2665 | { |
2565 | if (error) | 2666 | if (exception) |
2566 | *error = 0; | 2667 | exception->error_code = 0; |
2567 | return vcpu->arch.nested_mmu.translate_gpa(vcpu, vaddr, access); | 2668 | return vcpu->arch.nested_mmu.translate_gpa(vcpu, vaddr, access); |
2568 | } | 2669 | } |
2569 | 2670 | ||
2570 | static int nonpaging_page_fault(struct kvm_vcpu *vcpu, gva_t gva, | 2671 | static int nonpaging_page_fault(struct kvm_vcpu *vcpu, gva_t gva, |
2571 | u32 error_code) | 2672 | u32 error_code, bool prefault) |
2572 | { | 2673 | { |
2573 | gfn_t gfn; | 2674 | gfn_t gfn; |
2574 | int r; | 2675 | int r; |
@@ -2584,17 +2685,68 @@ static int nonpaging_page_fault(struct kvm_vcpu *vcpu, gva_t gva, | |||
2584 | gfn = gva >> PAGE_SHIFT; | 2685 | gfn = gva >> PAGE_SHIFT; |
2585 | 2686 | ||
2586 | return nonpaging_map(vcpu, gva & PAGE_MASK, | 2687 | return nonpaging_map(vcpu, gva & PAGE_MASK, |
2587 | error_code & PFERR_WRITE_MASK, gfn); | 2688 | error_code & PFERR_WRITE_MASK, gfn, prefault); |
2689 | } | ||
2690 | |||
2691 | static int kvm_arch_setup_async_pf(struct kvm_vcpu *vcpu, gva_t gva, gfn_t gfn) | ||
2692 | { | ||
2693 | struct kvm_arch_async_pf arch; | ||
2694 | |||
2695 | arch.token = (vcpu->arch.apf.id++ << 12) | vcpu->vcpu_id; | ||
2696 | arch.gfn = gfn; | ||
2697 | arch.direct_map = vcpu->arch.mmu.direct_map; | ||
2698 | arch.cr3 = vcpu->arch.mmu.get_cr3(vcpu); | ||
2699 | |||
2700 | return kvm_setup_async_pf(vcpu, gva, gfn, &arch); | ||
2701 | } | ||
2702 | |||
2703 | static bool can_do_async_pf(struct kvm_vcpu *vcpu) | ||
2704 | { | ||
2705 | if (unlikely(!irqchip_in_kernel(vcpu->kvm) || | ||
2706 | kvm_event_needs_reinjection(vcpu))) | ||
2707 | return false; | ||
2708 | |||
2709 | return kvm_x86_ops->interrupt_allowed(vcpu); | ||
2588 | } | 2710 | } |
2589 | 2711 | ||
2590 | static int tdp_page_fault(struct kvm_vcpu *vcpu, gva_t gpa, | 2712 | static bool try_async_pf(struct kvm_vcpu *vcpu, bool prefault, gfn_t gfn, |
2591 | u32 error_code) | 2713 | gva_t gva, pfn_t *pfn, bool write, bool *writable) |
2714 | { | ||
2715 | bool async; | ||
2716 | |||
2717 | *pfn = gfn_to_pfn_async(vcpu->kvm, gfn, &async, write, writable); | ||
2718 | |||
2719 | if (!async) | ||
2720 | return false; /* *pfn has correct page already */ | ||
2721 | |||
2722 | put_page(pfn_to_page(*pfn)); | ||
2723 | |||
2724 | if (!prefault && can_do_async_pf(vcpu)) { | ||
2725 | trace_kvm_try_async_get_page(gva, gfn); | ||
2726 | if (kvm_find_async_pf_gfn(vcpu, gfn)) { | ||
2727 | trace_kvm_async_pf_doublefault(gva, gfn); | ||
2728 | kvm_make_request(KVM_REQ_APF_HALT, vcpu); | ||
2729 | return true; | ||
2730 | } else if (kvm_arch_setup_async_pf(vcpu, gva, gfn)) | ||
2731 | return true; | ||
2732 | } | ||
2733 | |||
2734 | *pfn = gfn_to_pfn_prot(vcpu->kvm, gfn, write, writable); | ||
2735 | |||
2736 | return false; | ||
2737 | } | ||
2738 | |||
2739 | static int tdp_page_fault(struct kvm_vcpu *vcpu, gva_t gpa, u32 error_code, | ||
2740 | bool prefault) | ||
2592 | { | 2741 | { |
2593 | pfn_t pfn; | 2742 | pfn_t pfn; |
2594 | int r; | 2743 | int r; |
2595 | int level; | 2744 | int level; |
2745 | int force_pt_level; | ||
2596 | gfn_t gfn = gpa >> PAGE_SHIFT; | 2746 | gfn_t gfn = gpa >> PAGE_SHIFT; |
2597 | unsigned long mmu_seq; | 2747 | unsigned long mmu_seq; |
2748 | int write = error_code & PFERR_WRITE_MASK; | ||
2749 | bool map_writable; | ||
2598 | 2750 | ||
2599 | ASSERT(vcpu); | 2751 | ASSERT(vcpu); |
2600 | ASSERT(VALID_PAGE(vcpu->arch.mmu.root_hpa)); | 2752 | ASSERT(VALID_PAGE(vcpu->arch.mmu.root_hpa)); |
@@ -2603,21 +2755,30 @@ static int tdp_page_fault(struct kvm_vcpu *vcpu, gva_t gpa, | |||
2603 | if (r) | 2755 | if (r) |
2604 | return r; | 2756 | return r; |
2605 | 2757 | ||
2606 | level = mapping_level(vcpu, gfn); | 2758 | force_pt_level = mapping_level_dirty_bitmap(vcpu, gfn); |
2607 | 2759 | if (likely(!force_pt_level)) { | |
2608 | gfn &= ~(KVM_PAGES_PER_HPAGE(level) - 1); | 2760 | level = mapping_level(vcpu, gfn); |
2761 | gfn &= ~(KVM_PAGES_PER_HPAGE(level) - 1); | ||
2762 | } else | ||
2763 | level = PT_PAGE_TABLE_LEVEL; | ||
2609 | 2764 | ||
2610 | mmu_seq = vcpu->kvm->mmu_notifier_seq; | 2765 | mmu_seq = vcpu->kvm->mmu_notifier_seq; |
2611 | smp_rmb(); | 2766 | smp_rmb(); |
2612 | pfn = gfn_to_pfn(vcpu->kvm, gfn); | 2767 | |
2768 | if (try_async_pf(vcpu, prefault, gfn, gpa, &pfn, write, &map_writable)) | ||
2769 | return 0; | ||
2770 | |||
2771 | /* mmio */ | ||
2613 | if (is_error_pfn(pfn)) | 2772 | if (is_error_pfn(pfn)) |
2614 | return kvm_handle_bad_page(vcpu->kvm, gfn, pfn); | 2773 | return kvm_handle_bad_page(vcpu->kvm, gfn, pfn); |
2615 | spin_lock(&vcpu->kvm->mmu_lock); | 2774 | spin_lock(&vcpu->kvm->mmu_lock); |
2616 | if (mmu_notifier_retry(vcpu, mmu_seq)) | 2775 | if (mmu_notifier_retry(vcpu, mmu_seq)) |
2617 | goto out_unlock; | 2776 | goto out_unlock; |
2618 | kvm_mmu_free_some_pages(vcpu); | 2777 | kvm_mmu_free_some_pages(vcpu); |
2619 | r = __direct_map(vcpu, gpa, error_code & PFERR_WRITE_MASK, | 2778 | if (likely(!force_pt_level)) |
2620 | level, gfn, pfn); | 2779 | transparent_hugepage_adjust(vcpu, &gfn, &pfn, &level); |
2780 | r = __direct_map(vcpu, gpa, write, map_writable, | ||
2781 | level, gfn, pfn, prefault); | ||
2621 | spin_unlock(&vcpu->kvm->mmu_lock); | 2782 | spin_unlock(&vcpu->kvm->mmu_lock); |
2622 | 2783 | ||
2623 | return r; | 2784 | return r; |
@@ -2659,18 +2820,19 @@ void kvm_mmu_flush_tlb(struct kvm_vcpu *vcpu) | |||
2659 | 2820 | ||
2660 | static void paging_new_cr3(struct kvm_vcpu *vcpu) | 2821 | static void paging_new_cr3(struct kvm_vcpu *vcpu) |
2661 | { | 2822 | { |
2662 | pgprintk("%s: cr3 %lx\n", __func__, vcpu->arch.cr3); | 2823 | pgprintk("%s: cr3 %lx\n", __func__, kvm_read_cr3(vcpu)); |
2663 | mmu_free_roots(vcpu); | 2824 | mmu_free_roots(vcpu); |
2664 | } | 2825 | } |
2665 | 2826 | ||
2666 | static unsigned long get_cr3(struct kvm_vcpu *vcpu) | 2827 | static unsigned long get_cr3(struct kvm_vcpu *vcpu) |
2667 | { | 2828 | { |
2668 | return vcpu->arch.cr3; | 2829 | return kvm_read_cr3(vcpu); |
2669 | } | 2830 | } |
2670 | 2831 | ||
2671 | static void inject_page_fault(struct kvm_vcpu *vcpu) | 2832 | static void inject_page_fault(struct kvm_vcpu *vcpu, |
2833 | struct x86_exception *fault) | ||
2672 | { | 2834 | { |
2673 | vcpu->arch.mmu.inject_page_fault(vcpu); | 2835 | vcpu->arch.mmu.inject_page_fault(vcpu, fault); |
2674 | } | 2836 | } |
2675 | 2837 | ||
2676 | static void paging_free(struct kvm_vcpu *vcpu) | 2838 | static void paging_free(struct kvm_vcpu *vcpu) |
@@ -2816,6 +2978,7 @@ static int init_kvm_tdp_mmu(struct kvm_vcpu *vcpu) | |||
2816 | { | 2978 | { |
2817 | struct kvm_mmu *context = vcpu->arch.walk_mmu; | 2979 | struct kvm_mmu *context = vcpu->arch.walk_mmu; |
2818 | 2980 | ||
2981 | context->base_role.word = 0; | ||
2819 | context->new_cr3 = nonpaging_new_cr3; | 2982 | context->new_cr3 = nonpaging_new_cr3; |
2820 | context->page_fault = tdp_page_fault; | 2983 | context->page_fault = tdp_page_fault; |
2821 | context->free = nonpaging_free; | 2984 | context->free = nonpaging_free; |
@@ -3008,9 +3171,6 @@ static void mmu_pte_write_new_pte(struct kvm_vcpu *vcpu, | |||
3008 | return; | 3171 | return; |
3009 | } | 3172 | } |
3010 | 3173 | ||
3011 | if (is_rsvd_bits_set(&vcpu->arch.mmu, *(u64 *)new, PT_PAGE_TABLE_LEVEL)) | ||
3012 | return; | ||
3013 | |||
3014 | ++vcpu->kvm->stat.mmu_pte_updated; | 3174 | ++vcpu->kvm->stat.mmu_pte_updated; |
3015 | if (!sp->role.cr4_pae) | 3175 | if (!sp->role.cr4_pae) |
3016 | paging32_update_pte(vcpu, sp, spte, new); | 3176 | paging32_update_pte(vcpu, sp, spte, new); |
@@ -3264,12 +3424,13 @@ void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu) | |||
3264 | } | 3424 | } |
3265 | } | 3425 | } |
3266 | 3426 | ||
3267 | int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t cr2, u32 error_code) | 3427 | int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t cr2, u32 error_code, |
3428 | void *insn, int insn_len) | ||
3268 | { | 3429 | { |
3269 | int r; | 3430 | int r; |
3270 | enum emulation_result er; | 3431 | enum emulation_result er; |
3271 | 3432 | ||
3272 | r = vcpu->arch.mmu.page_fault(vcpu, cr2, error_code); | 3433 | r = vcpu->arch.mmu.page_fault(vcpu, cr2, error_code, false); |
3273 | if (r < 0) | 3434 | if (r < 0) |
3274 | goto out; | 3435 | goto out; |
3275 | 3436 | ||
@@ -3282,7 +3443,7 @@ int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t cr2, u32 error_code) | |||
3282 | if (r) | 3443 | if (r) |
3283 | goto out; | 3444 | goto out; |
3284 | 3445 | ||
3285 | er = emulate_instruction(vcpu, cr2, error_code, 0); | 3446 | er = x86_emulate_instruction(vcpu, cr2, 0, insn, insn_len); |
3286 | 3447 | ||
3287 | switch (er) { | 3448 | switch (er) { |
3288 | case EMULATE_DONE: | 3449 | case EMULATE_DONE: |
@@ -3377,11 +3538,14 @@ void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot) | |||
3377 | if (!test_bit(slot, sp->slot_bitmap)) | 3538 | if (!test_bit(slot, sp->slot_bitmap)) |
3378 | continue; | 3539 | continue; |
3379 | 3540 | ||
3541 | if (sp->role.level != PT_PAGE_TABLE_LEVEL) | ||
3542 | continue; | ||
3543 | |||
3380 | pt = sp->spt; | 3544 | pt = sp->spt; |
3381 | for (i = 0; i < PT64_ENT_PER_PAGE; ++i) | 3545 | for (i = 0; i < PT64_ENT_PER_PAGE; ++i) |
3382 | /* avoid RMW */ | 3546 | /* avoid RMW */ |
3383 | if (is_writable_pte(pt[i])) | 3547 | if (is_writable_pte(pt[i])) |
3384 | pt[i] &= ~PT_WRITABLE_MASK; | 3548 | update_spte(&pt[i], pt[i] & ~PT_WRITABLE_MASK); |
3385 | } | 3549 | } |
3386 | kvm_flush_remote_tlbs(kvm); | 3550 | kvm_flush_remote_tlbs(kvm); |
3387 | } | 3551 | } |
@@ -3463,13 +3627,6 @@ static void mmu_destroy_caches(void) | |||
3463 | kmem_cache_destroy(mmu_page_header_cache); | 3627 | kmem_cache_destroy(mmu_page_header_cache); |
3464 | } | 3628 | } |
3465 | 3629 | ||
3466 | void kvm_mmu_module_exit(void) | ||
3467 | { | ||
3468 | mmu_destroy_caches(); | ||
3469 | percpu_counter_destroy(&kvm_total_used_mmu_pages); | ||
3470 | unregister_shrinker(&mmu_shrinker); | ||
3471 | } | ||
3472 | |||
3473 | int kvm_mmu_module_init(void) | 3630 | int kvm_mmu_module_init(void) |
3474 | { | 3631 | { |
3475 | pte_chain_cache = kmem_cache_create("kvm_pte_chain", | 3632 | pte_chain_cache = kmem_cache_create("kvm_pte_chain", |
@@ -3566,7 +3723,7 @@ static int kvm_pv_mmu_write(struct kvm_vcpu *vcpu, | |||
3566 | 3723 | ||
3567 | static int kvm_pv_mmu_flush_tlb(struct kvm_vcpu *vcpu) | 3724 | static int kvm_pv_mmu_flush_tlb(struct kvm_vcpu *vcpu) |
3568 | { | 3725 | { |
3569 | (void)kvm_set_cr3(vcpu, vcpu->arch.cr3); | 3726 | (void)kvm_set_cr3(vcpu, kvm_read_cr3(vcpu)); |
3570 | return 1; | 3727 | return 1; |
3571 | } | 3728 | } |
3572 | 3729 | ||
@@ -3662,12 +3819,6 @@ int kvm_mmu_get_spte_hierarchy(struct kvm_vcpu *vcpu, u64 addr, u64 sptes[4]) | |||
3662 | } | 3819 | } |
3663 | EXPORT_SYMBOL_GPL(kvm_mmu_get_spte_hierarchy); | 3820 | EXPORT_SYMBOL_GPL(kvm_mmu_get_spte_hierarchy); |
3664 | 3821 | ||
3665 | #ifdef CONFIG_KVM_MMU_AUDIT | ||
3666 | #include "mmu_audit.c" | ||
3667 | #else | ||
3668 | static void mmu_audit_disable(void) { } | ||
3669 | #endif | ||
3670 | |||
3671 | void kvm_mmu_destroy(struct kvm_vcpu *vcpu) | 3822 | void kvm_mmu_destroy(struct kvm_vcpu *vcpu) |
3672 | { | 3823 | { |
3673 | ASSERT(vcpu); | 3824 | ASSERT(vcpu); |
@@ -3675,5 +3826,18 @@ void kvm_mmu_destroy(struct kvm_vcpu *vcpu) | |||
3675 | destroy_kvm_mmu(vcpu); | 3826 | destroy_kvm_mmu(vcpu); |
3676 | free_mmu_pages(vcpu); | 3827 | free_mmu_pages(vcpu); |
3677 | mmu_free_memory_caches(vcpu); | 3828 | mmu_free_memory_caches(vcpu); |
3829 | } | ||
3830 | |||
3831 | #ifdef CONFIG_KVM_MMU_AUDIT | ||
3832 | #include "mmu_audit.c" | ||
3833 | #else | ||
3834 | static void mmu_audit_disable(void) { } | ||
3835 | #endif | ||
3836 | |||
3837 | void kvm_mmu_module_exit(void) | ||
3838 | { | ||
3839 | mmu_destroy_caches(); | ||
3840 | percpu_counter_destroy(&kvm_total_used_mmu_pages); | ||
3841 | unregister_shrinker(&mmu_shrinker); | ||
3678 | mmu_audit_disable(); | 3842 | mmu_audit_disable(); |
3679 | } | 3843 | } |
diff --git a/arch/x86/kvm/mmu_audit.c b/arch/x86/kvm/mmu_audit.c index ba2bcdde6221..5f6223b8bcf7 100644 --- a/arch/x86/kvm/mmu_audit.c +++ b/arch/x86/kvm/mmu_audit.c | |||
@@ -19,11 +19,9 @@ | |||
19 | 19 | ||
20 | #include <linux/ratelimit.h> | 20 | #include <linux/ratelimit.h> |
21 | 21 | ||
22 | static int audit_point; | 22 | #define audit_printk(kvm, fmt, args...) \ |
23 | |||
24 | #define audit_printk(fmt, args...) \ | ||
25 | printk(KERN_ERR "audit: (%s) error: " \ | 23 | printk(KERN_ERR "audit: (%s) error: " \ |
26 | fmt, audit_point_name[audit_point], ##args) | 24 | fmt, audit_point_name[kvm->arch.audit_point], ##args) |
27 | 25 | ||
28 | typedef void (*inspect_spte_fn) (struct kvm_vcpu *vcpu, u64 *sptep, int level); | 26 | typedef void (*inspect_spte_fn) (struct kvm_vcpu *vcpu, u64 *sptep, int level); |
29 | 27 | ||
@@ -97,18 +95,21 @@ static void audit_mappings(struct kvm_vcpu *vcpu, u64 *sptep, int level) | |||
97 | 95 | ||
98 | if (sp->unsync) { | 96 | if (sp->unsync) { |
99 | if (level != PT_PAGE_TABLE_LEVEL) { | 97 | if (level != PT_PAGE_TABLE_LEVEL) { |
100 | audit_printk("unsync sp: %p level = %d\n", sp, level); | 98 | audit_printk(vcpu->kvm, "unsync sp: %p " |
99 | "level = %d\n", sp, level); | ||
101 | return; | 100 | return; |
102 | } | 101 | } |
103 | 102 | ||
104 | if (*sptep == shadow_notrap_nonpresent_pte) { | 103 | if (*sptep == shadow_notrap_nonpresent_pte) { |
105 | audit_printk("notrap spte in unsync sp: %p\n", sp); | 104 | audit_printk(vcpu->kvm, "notrap spte in unsync " |
105 | "sp: %p\n", sp); | ||
106 | return; | 106 | return; |
107 | } | 107 | } |
108 | } | 108 | } |
109 | 109 | ||
110 | if (sp->role.direct && *sptep == shadow_notrap_nonpresent_pte) { | 110 | if (sp->role.direct && *sptep == shadow_notrap_nonpresent_pte) { |
111 | audit_printk("notrap spte in direct sp: %p\n", sp); | 111 | audit_printk(vcpu->kvm, "notrap spte in direct sp: %p\n", |
112 | sp); | ||
112 | return; | 113 | return; |
113 | } | 114 | } |
114 | 115 | ||
@@ -125,8 +126,9 @@ static void audit_mappings(struct kvm_vcpu *vcpu, u64 *sptep, int level) | |||
125 | 126 | ||
126 | hpa = pfn << PAGE_SHIFT; | 127 | hpa = pfn << PAGE_SHIFT; |
127 | if ((*sptep & PT64_BASE_ADDR_MASK) != hpa) | 128 | if ((*sptep & PT64_BASE_ADDR_MASK) != hpa) |
128 | audit_printk("levels %d pfn %llx hpa %llx ent %llxn", | 129 | audit_printk(vcpu->kvm, "levels %d pfn %llx hpa %llx " |
129 | vcpu->arch.mmu.root_level, pfn, hpa, *sptep); | 130 | "ent %llxn", vcpu->arch.mmu.root_level, pfn, |
131 | hpa, *sptep); | ||
130 | } | 132 | } |
131 | 133 | ||
132 | static void inspect_spte_has_rmap(struct kvm *kvm, u64 *sptep) | 134 | static void inspect_spte_has_rmap(struct kvm *kvm, u64 *sptep) |
@@ -142,8 +144,8 @@ static void inspect_spte_has_rmap(struct kvm *kvm, u64 *sptep) | |||
142 | if (!gfn_to_memslot(kvm, gfn)) { | 144 | if (!gfn_to_memslot(kvm, gfn)) { |
143 | if (!printk_ratelimit()) | 145 | if (!printk_ratelimit()) |
144 | return; | 146 | return; |
145 | audit_printk("no memslot for gfn %llx\n", gfn); | 147 | audit_printk(kvm, "no memslot for gfn %llx\n", gfn); |
146 | audit_printk("index %ld of sp (gfn=%llx)\n", | 148 | audit_printk(kvm, "index %ld of sp (gfn=%llx)\n", |
147 | (long int)(sptep - rev_sp->spt), rev_sp->gfn); | 149 | (long int)(sptep - rev_sp->spt), rev_sp->gfn); |
148 | dump_stack(); | 150 | dump_stack(); |
149 | return; | 151 | return; |
@@ -153,7 +155,8 @@ static void inspect_spte_has_rmap(struct kvm *kvm, u64 *sptep) | |||
153 | if (!*rmapp) { | 155 | if (!*rmapp) { |
154 | if (!printk_ratelimit()) | 156 | if (!printk_ratelimit()) |
155 | return; | 157 | return; |
156 | audit_printk("no rmap for writable spte %llx\n", *sptep); | 158 | audit_printk(kvm, "no rmap for writable spte %llx\n", |
159 | *sptep); | ||
157 | dump_stack(); | 160 | dump_stack(); |
158 | } | 161 | } |
159 | } | 162 | } |
@@ -168,8 +171,9 @@ static void audit_spte_after_sync(struct kvm_vcpu *vcpu, u64 *sptep, int level) | |||
168 | { | 171 | { |
169 | struct kvm_mmu_page *sp = page_header(__pa(sptep)); | 172 | struct kvm_mmu_page *sp = page_header(__pa(sptep)); |
170 | 173 | ||
171 | if (audit_point == AUDIT_POST_SYNC && sp->unsync) | 174 | if (vcpu->kvm->arch.audit_point == AUDIT_POST_SYNC && sp->unsync) |
172 | audit_printk("meet unsync sp(%p) after sync root.\n", sp); | 175 | audit_printk(vcpu->kvm, "meet unsync sp(%p) after sync " |
176 | "root.\n", sp); | ||
173 | } | 177 | } |
174 | 178 | ||
175 | static void check_mappings_rmap(struct kvm *kvm, struct kvm_mmu_page *sp) | 179 | static void check_mappings_rmap(struct kvm *kvm, struct kvm_mmu_page *sp) |
@@ -202,8 +206,9 @@ static void audit_write_protection(struct kvm *kvm, struct kvm_mmu_page *sp) | |||
202 | spte = rmap_next(kvm, rmapp, NULL); | 206 | spte = rmap_next(kvm, rmapp, NULL); |
203 | while (spte) { | 207 | while (spte) { |
204 | if (is_writable_pte(*spte)) | 208 | if (is_writable_pte(*spte)) |
205 | audit_printk("shadow page has writable mappings: gfn " | 209 | audit_printk(kvm, "shadow page has writable " |
206 | "%llx role %x\n", sp->gfn, sp->role.word); | 210 | "mappings: gfn %llx role %x\n", |
211 | sp->gfn, sp->role.word); | ||
207 | spte = rmap_next(kvm, rmapp, spte); | 212 | spte = rmap_next(kvm, rmapp, spte); |
208 | } | 213 | } |
209 | } | 214 | } |
@@ -238,7 +243,7 @@ static void kvm_mmu_audit(void *ignore, struct kvm_vcpu *vcpu, int point) | |||
238 | if (!__ratelimit(&ratelimit_state)) | 243 | if (!__ratelimit(&ratelimit_state)) |
239 | return; | 244 | return; |
240 | 245 | ||
241 | audit_point = point; | 246 | vcpu->kvm->arch.audit_point = point; |
242 | audit_all_active_sps(vcpu->kvm); | 247 | audit_all_active_sps(vcpu->kvm); |
243 | audit_vcpu_spte(vcpu); | 248 | audit_vcpu_spte(vcpu); |
244 | } | 249 | } |
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index cd7a833a3b52..6bccc24c4181 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h | |||
@@ -72,7 +72,7 @@ struct guest_walker { | |||
72 | unsigned pt_access; | 72 | unsigned pt_access; |
73 | unsigned pte_access; | 73 | unsigned pte_access; |
74 | gfn_t gfn; | 74 | gfn_t gfn; |
75 | u32 error_code; | 75 | struct x86_exception fault; |
76 | }; | 76 | }; |
77 | 77 | ||
78 | static gfn_t gpte_to_gfn_lvl(pt_element_t gpte, int lvl) | 78 | static gfn_t gpte_to_gfn_lvl(pt_element_t gpte, int lvl) |
@@ -266,21 +266,23 @@ walk: | |||
266 | return 1; | 266 | return 1; |
267 | 267 | ||
268 | error: | 268 | error: |
269 | walker->error_code = 0; | 269 | walker->fault.vector = PF_VECTOR; |
270 | walker->fault.error_code_valid = true; | ||
271 | walker->fault.error_code = 0; | ||
270 | if (present) | 272 | if (present) |
271 | walker->error_code |= PFERR_PRESENT_MASK; | 273 | walker->fault.error_code |= PFERR_PRESENT_MASK; |
272 | 274 | ||
273 | walker->error_code |= write_fault | user_fault; | 275 | walker->fault.error_code |= write_fault | user_fault; |
274 | 276 | ||
275 | if (fetch_fault && mmu->nx) | 277 | if (fetch_fault && mmu->nx) |
276 | walker->error_code |= PFERR_FETCH_MASK; | 278 | walker->fault.error_code |= PFERR_FETCH_MASK; |
277 | if (rsvd_fault) | 279 | if (rsvd_fault) |
278 | walker->error_code |= PFERR_RSVD_MASK; | 280 | walker->fault.error_code |= PFERR_RSVD_MASK; |
279 | 281 | ||
280 | vcpu->arch.fault.address = addr; | 282 | walker->fault.address = addr; |
281 | vcpu->arch.fault.error_code = walker->error_code; | 283 | walker->fault.nested_page_fault = mmu != vcpu->arch.walk_mmu; |
282 | 284 | ||
283 | trace_kvm_mmu_walker_error(walker->error_code); | 285 | trace_kvm_mmu_walker_error(walker->fault.error_code); |
284 | return 0; | 286 | return 0; |
285 | } | 287 | } |
286 | 288 | ||
@@ -299,25 +301,42 @@ static int FNAME(walk_addr_nested)(struct guest_walker *walker, | |||
299 | addr, access); | 301 | addr, access); |
300 | } | 302 | } |
301 | 303 | ||
304 | static bool FNAME(prefetch_invalid_gpte)(struct kvm_vcpu *vcpu, | ||
305 | struct kvm_mmu_page *sp, u64 *spte, | ||
306 | pt_element_t gpte) | ||
307 | { | ||
308 | u64 nonpresent = shadow_trap_nonpresent_pte; | ||
309 | |||
310 | if (is_rsvd_bits_set(&vcpu->arch.mmu, gpte, PT_PAGE_TABLE_LEVEL)) | ||
311 | goto no_present; | ||
312 | |||
313 | if (!is_present_gpte(gpte)) { | ||
314 | if (!sp->unsync) | ||
315 | nonpresent = shadow_notrap_nonpresent_pte; | ||
316 | goto no_present; | ||
317 | } | ||
318 | |||
319 | if (!(gpte & PT_ACCESSED_MASK)) | ||
320 | goto no_present; | ||
321 | |||
322 | return false; | ||
323 | |||
324 | no_present: | ||
325 | drop_spte(vcpu->kvm, spte, nonpresent); | ||
326 | return true; | ||
327 | } | ||
328 | |||
302 | static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, | 329 | static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, |
303 | u64 *spte, const void *pte) | 330 | u64 *spte, const void *pte) |
304 | { | 331 | { |
305 | pt_element_t gpte; | 332 | pt_element_t gpte; |
306 | unsigned pte_access; | 333 | unsigned pte_access; |
307 | pfn_t pfn; | 334 | pfn_t pfn; |
308 | u64 new_spte; | ||
309 | 335 | ||
310 | gpte = *(const pt_element_t *)pte; | 336 | gpte = *(const pt_element_t *)pte; |
311 | if (~gpte & (PT_PRESENT_MASK | PT_ACCESSED_MASK)) { | 337 | if (FNAME(prefetch_invalid_gpte)(vcpu, sp, spte, gpte)) |
312 | if (!is_present_gpte(gpte)) { | ||
313 | if (sp->unsync) | ||
314 | new_spte = shadow_trap_nonpresent_pte; | ||
315 | else | ||
316 | new_spte = shadow_notrap_nonpresent_pte; | ||
317 | __set_spte(spte, new_spte); | ||
318 | } | ||
319 | return; | 338 | return; |
320 | } | 339 | |
321 | pgprintk("%s: gpte %llx spte %p\n", __func__, (u64)gpte, spte); | 340 | pgprintk("%s: gpte %llx spte %p\n", __func__, (u64)gpte, spte); |
322 | pte_access = sp->role.access & FNAME(gpte_access)(vcpu, gpte); | 341 | pte_access = sp->role.access & FNAME(gpte_access)(vcpu, gpte); |
323 | if (gpte_to_gfn(gpte) != vcpu->arch.update_pte.gfn) | 342 | if (gpte_to_gfn(gpte) != vcpu->arch.update_pte.gfn) |
@@ -329,7 +348,7 @@ static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, | |||
329 | return; | 348 | return; |
330 | kvm_get_pfn(pfn); | 349 | kvm_get_pfn(pfn); |
331 | /* | 350 | /* |
332 | * we call mmu_set_spte() with reset_host_protection = true beacuse that | 351 | * we call mmu_set_spte() with host_writable = true beacuse that |
333 | * vcpu->arch.update_pte.pfn was fetched from get_user_pages(write = 1). | 352 | * vcpu->arch.update_pte.pfn was fetched from get_user_pages(write = 1). |
334 | */ | 353 | */ |
335 | mmu_set_spte(vcpu, spte, sp->role.access, pte_access, 0, 0, | 354 | mmu_set_spte(vcpu, spte, sp->role.access, pte_access, 0, 0, |
@@ -364,7 +383,6 @@ static void FNAME(pte_prefetch)(struct kvm_vcpu *vcpu, struct guest_walker *gw, | |||
364 | u64 *sptep) | 383 | u64 *sptep) |
365 | { | 384 | { |
366 | struct kvm_mmu_page *sp; | 385 | struct kvm_mmu_page *sp; |
367 | struct kvm_mmu *mmu = &vcpu->arch.mmu; | ||
368 | pt_element_t *gptep = gw->prefetch_ptes; | 386 | pt_element_t *gptep = gw->prefetch_ptes; |
369 | u64 *spte; | 387 | u64 *spte; |
370 | int i; | 388 | int i; |
@@ -395,14 +413,7 @@ static void FNAME(pte_prefetch)(struct kvm_vcpu *vcpu, struct guest_walker *gw, | |||
395 | 413 | ||
396 | gpte = gptep[i]; | 414 | gpte = gptep[i]; |
397 | 415 | ||
398 | if (!is_present_gpte(gpte) || | 416 | if (FNAME(prefetch_invalid_gpte)(vcpu, sp, spte, gpte)) |
399 | is_rsvd_bits_set(mmu, gpte, PT_PAGE_TABLE_LEVEL)) { | ||
400 | if (!sp->unsync) | ||
401 | __set_spte(spte, shadow_notrap_nonpresent_pte); | ||
402 | continue; | ||
403 | } | ||
404 | |||
405 | if (!(gpte & PT_ACCESSED_MASK)) | ||
406 | continue; | 417 | continue; |
407 | 418 | ||
408 | pte_access = sp->role.access & FNAME(gpte_access)(vcpu, gpte); | 419 | pte_access = sp->role.access & FNAME(gpte_access)(vcpu, gpte); |
@@ -427,7 +438,8 @@ static void FNAME(pte_prefetch)(struct kvm_vcpu *vcpu, struct guest_walker *gw, | |||
427 | static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr, | 438 | static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr, |
428 | struct guest_walker *gw, | 439 | struct guest_walker *gw, |
429 | int user_fault, int write_fault, int hlevel, | 440 | int user_fault, int write_fault, int hlevel, |
430 | int *ptwrite, pfn_t pfn) | 441 | int *ptwrite, pfn_t pfn, bool map_writable, |
442 | bool prefault) | ||
431 | { | 443 | { |
432 | unsigned access = gw->pt_access; | 444 | unsigned access = gw->pt_access; |
433 | struct kvm_mmu_page *sp = NULL; | 445 | struct kvm_mmu_page *sp = NULL; |
@@ -501,7 +513,7 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr, | |||
501 | 513 | ||
502 | mmu_set_spte(vcpu, it.sptep, access, gw->pte_access & access, | 514 | mmu_set_spte(vcpu, it.sptep, access, gw->pte_access & access, |
503 | user_fault, write_fault, dirty, ptwrite, it.level, | 515 | user_fault, write_fault, dirty, ptwrite, it.level, |
504 | gw->gfn, pfn, false, true); | 516 | gw->gfn, pfn, prefault, map_writable); |
505 | FNAME(pte_prefetch)(vcpu, gw, it.sptep); | 517 | FNAME(pte_prefetch)(vcpu, gw, it.sptep); |
506 | 518 | ||
507 | return it.sptep; | 519 | return it.sptep; |
@@ -527,8 +539,8 @@ out_gpte_changed: | |||
527 | * Returns: 1 if we need to emulate the instruction, 0 otherwise, or | 539 | * Returns: 1 if we need to emulate the instruction, 0 otherwise, or |
528 | * a negative value on error. | 540 | * a negative value on error. |
529 | */ | 541 | */ |
530 | static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, | 542 | static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, u32 error_code, |
531 | u32 error_code) | 543 | bool prefault) |
532 | { | 544 | { |
533 | int write_fault = error_code & PFERR_WRITE_MASK; | 545 | int write_fault = error_code & PFERR_WRITE_MASK; |
534 | int user_fault = error_code & PFERR_USER_MASK; | 546 | int user_fault = error_code & PFERR_USER_MASK; |
@@ -538,7 +550,9 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, | |||
538 | int r; | 550 | int r; |
539 | pfn_t pfn; | 551 | pfn_t pfn; |
540 | int level = PT_PAGE_TABLE_LEVEL; | 552 | int level = PT_PAGE_TABLE_LEVEL; |
553 | int force_pt_level; | ||
541 | unsigned long mmu_seq; | 554 | unsigned long mmu_seq; |
555 | bool map_writable; | ||
542 | 556 | ||
543 | pgprintk("%s: addr %lx err %x\n", __func__, addr, error_code); | 557 | pgprintk("%s: addr %lx err %x\n", __func__, addr, error_code); |
544 | 558 | ||
@@ -556,19 +570,29 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, | |||
556 | */ | 570 | */ |
557 | if (!r) { | 571 | if (!r) { |
558 | pgprintk("%s: guest page fault\n", __func__); | 572 | pgprintk("%s: guest page fault\n", __func__); |
559 | inject_page_fault(vcpu); | 573 | if (!prefault) { |
560 | vcpu->arch.last_pt_write_count = 0; /* reset fork detector */ | 574 | inject_page_fault(vcpu, &walker.fault); |
575 | /* reset fork detector */ | ||
576 | vcpu->arch.last_pt_write_count = 0; | ||
577 | } | ||
561 | return 0; | 578 | return 0; |
562 | } | 579 | } |
563 | 580 | ||
564 | if (walker.level >= PT_DIRECTORY_LEVEL) { | 581 | if (walker.level >= PT_DIRECTORY_LEVEL) |
582 | force_pt_level = mapping_level_dirty_bitmap(vcpu, walker.gfn); | ||
583 | else | ||
584 | force_pt_level = 1; | ||
585 | if (!force_pt_level) { | ||
565 | level = min(walker.level, mapping_level(vcpu, walker.gfn)); | 586 | level = min(walker.level, mapping_level(vcpu, walker.gfn)); |
566 | walker.gfn = walker.gfn & ~(KVM_PAGES_PER_HPAGE(level) - 1); | 587 | walker.gfn = walker.gfn & ~(KVM_PAGES_PER_HPAGE(level) - 1); |
567 | } | 588 | } |
568 | 589 | ||
569 | mmu_seq = vcpu->kvm->mmu_notifier_seq; | 590 | mmu_seq = vcpu->kvm->mmu_notifier_seq; |
570 | smp_rmb(); | 591 | smp_rmb(); |
571 | pfn = gfn_to_pfn(vcpu->kvm, walker.gfn); | 592 | |
593 | if (try_async_pf(vcpu, prefault, walker.gfn, addr, &pfn, write_fault, | ||
594 | &map_writable)) | ||
595 | return 0; | ||
572 | 596 | ||
573 | /* mmio */ | 597 | /* mmio */ |
574 | if (is_error_pfn(pfn)) | 598 | if (is_error_pfn(pfn)) |
@@ -580,8 +604,10 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, | |||
580 | 604 | ||
581 | trace_kvm_mmu_audit(vcpu, AUDIT_PRE_PAGE_FAULT); | 605 | trace_kvm_mmu_audit(vcpu, AUDIT_PRE_PAGE_FAULT); |
582 | kvm_mmu_free_some_pages(vcpu); | 606 | kvm_mmu_free_some_pages(vcpu); |
607 | if (!force_pt_level) | ||
608 | transparent_hugepage_adjust(vcpu, &walker.gfn, &pfn, &level); | ||
583 | sptep = FNAME(fetch)(vcpu, addr, &walker, user_fault, write_fault, | 609 | sptep = FNAME(fetch)(vcpu, addr, &walker, user_fault, write_fault, |
584 | level, &write_pt, pfn); | 610 | level, &write_pt, pfn, map_writable, prefault); |
585 | (void)sptep; | 611 | (void)sptep; |
586 | pgprintk("%s: shadow pte %p %llx ptwrite %d\n", __func__, | 612 | pgprintk("%s: shadow pte %p %llx ptwrite %d\n", __func__, |
587 | sptep, *sptep, write_pt); | 613 | sptep, *sptep, write_pt); |
@@ -661,7 +687,7 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) | |||
661 | } | 687 | } |
662 | 688 | ||
663 | static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr, u32 access, | 689 | static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr, u32 access, |
664 | u32 *error) | 690 | struct x86_exception *exception) |
665 | { | 691 | { |
666 | struct guest_walker walker; | 692 | struct guest_walker walker; |
667 | gpa_t gpa = UNMAPPED_GVA; | 693 | gpa_t gpa = UNMAPPED_GVA; |
@@ -672,14 +698,15 @@ static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr, u32 access, | |||
672 | if (r) { | 698 | if (r) { |
673 | gpa = gfn_to_gpa(walker.gfn); | 699 | gpa = gfn_to_gpa(walker.gfn); |
674 | gpa |= vaddr & ~PAGE_MASK; | 700 | gpa |= vaddr & ~PAGE_MASK; |
675 | } else if (error) | 701 | } else if (exception) |
676 | *error = walker.error_code; | 702 | *exception = walker.fault; |
677 | 703 | ||
678 | return gpa; | 704 | return gpa; |
679 | } | 705 | } |
680 | 706 | ||
681 | static gpa_t FNAME(gva_to_gpa_nested)(struct kvm_vcpu *vcpu, gva_t vaddr, | 707 | static gpa_t FNAME(gva_to_gpa_nested)(struct kvm_vcpu *vcpu, gva_t vaddr, |
682 | u32 access, u32 *error) | 708 | u32 access, |
709 | struct x86_exception *exception) | ||
683 | { | 710 | { |
684 | struct guest_walker walker; | 711 | struct guest_walker walker; |
685 | gpa_t gpa = UNMAPPED_GVA; | 712 | gpa_t gpa = UNMAPPED_GVA; |
@@ -690,8 +717,8 @@ static gpa_t FNAME(gva_to_gpa_nested)(struct kvm_vcpu *vcpu, gva_t vaddr, | |||
690 | if (r) { | 717 | if (r) { |
691 | gpa = gfn_to_gpa(walker.gfn); | 718 | gpa = gfn_to_gpa(walker.gfn); |
692 | gpa |= vaddr & ~PAGE_MASK; | 719 | gpa |= vaddr & ~PAGE_MASK; |
693 | } else if (error) | 720 | } else if (exception) |
694 | *error = walker.error_code; | 721 | *exception = walker.fault; |
695 | 722 | ||
696 | return gpa; | 723 | return gpa; |
697 | } | 724 | } |
@@ -730,12 +757,19 @@ static void FNAME(prefetch_page)(struct kvm_vcpu *vcpu, | |||
730 | * Using the cached information from sp->gfns is safe because: | 757 | * Using the cached information from sp->gfns is safe because: |
731 | * - The spte has a reference to the struct page, so the pfn for a given gfn | 758 | * - The spte has a reference to the struct page, so the pfn for a given gfn |
732 | * can't change unless all sptes pointing to it are nuked first. | 759 | * can't change unless all sptes pointing to it are nuked first. |
760 | * | ||
761 | * Note: | ||
762 | * We should flush all tlbs if spte is dropped even though guest is | ||
763 | * responsible for it. Since if we don't, kvm_mmu_notifier_invalidate_page | ||
764 | * and kvm_mmu_notifier_invalidate_range_start detect the mapping page isn't | ||
765 | * used by guest then tlbs are not flushed, so guest is allowed to access the | ||
766 | * freed pages. | ||
767 | * And we increase kvm->tlbs_dirty to delay tlbs flush in this case. | ||
733 | */ | 768 | */ |
734 | static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, | 769 | static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) |
735 | bool clear_unsync) | ||
736 | { | 770 | { |
737 | int i, offset, nr_present; | 771 | int i, offset, nr_present; |
738 | bool reset_host_protection; | 772 | bool host_writable; |
739 | gpa_t first_pte_gpa; | 773 | gpa_t first_pte_gpa; |
740 | 774 | ||
741 | offset = nr_present = 0; | 775 | offset = nr_present = 0; |
@@ -764,31 +798,27 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, | |||
764 | return -EINVAL; | 798 | return -EINVAL; |
765 | 799 | ||
766 | gfn = gpte_to_gfn(gpte); | 800 | gfn = gpte_to_gfn(gpte); |
767 | if (is_rsvd_bits_set(&vcpu->arch.mmu, gpte, PT_PAGE_TABLE_LEVEL) | ||
768 | || gfn != sp->gfns[i] || !is_present_gpte(gpte) | ||
769 | || !(gpte & PT_ACCESSED_MASK)) { | ||
770 | u64 nonpresent; | ||
771 | 801 | ||
772 | if (is_present_gpte(gpte) || !clear_unsync) | 802 | if (FNAME(prefetch_invalid_gpte)(vcpu, sp, &sp->spt[i], gpte)) { |
773 | nonpresent = shadow_trap_nonpresent_pte; | 803 | vcpu->kvm->tlbs_dirty++; |
774 | else | 804 | continue; |
775 | nonpresent = shadow_notrap_nonpresent_pte; | 805 | } |
776 | drop_spte(vcpu->kvm, &sp->spt[i], nonpresent); | 806 | |
807 | if (gfn != sp->gfns[i]) { | ||
808 | drop_spte(vcpu->kvm, &sp->spt[i], | ||
809 | shadow_trap_nonpresent_pte); | ||
810 | vcpu->kvm->tlbs_dirty++; | ||
777 | continue; | 811 | continue; |
778 | } | 812 | } |
779 | 813 | ||
780 | nr_present++; | 814 | nr_present++; |
781 | pte_access = sp->role.access & FNAME(gpte_access)(vcpu, gpte); | 815 | pte_access = sp->role.access & FNAME(gpte_access)(vcpu, gpte); |
782 | if (!(sp->spt[i] & SPTE_HOST_WRITEABLE)) { | 816 | host_writable = sp->spt[i] & SPTE_HOST_WRITEABLE; |
783 | pte_access &= ~ACC_WRITE_MASK; | 817 | |
784 | reset_host_protection = 0; | ||
785 | } else { | ||
786 | reset_host_protection = 1; | ||
787 | } | ||
788 | set_spte(vcpu, &sp->spt[i], pte_access, 0, 0, | 818 | set_spte(vcpu, &sp->spt[i], pte_access, 0, 0, |
789 | is_dirty_gpte(gpte), PT_PAGE_TABLE_LEVEL, gfn, | 819 | is_dirty_gpte(gpte), PT_PAGE_TABLE_LEVEL, gfn, |
790 | spte_to_pfn(sp->spt[i]), true, false, | 820 | spte_to_pfn(sp->spt[i]), true, false, |
791 | reset_host_protection); | 821 | host_writable); |
792 | } | 822 | } |
793 | 823 | ||
794 | return !nr_present; | 824 | return !nr_present; |
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index b81a9b7c2ca4..25bd1bc5aad2 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -31,6 +31,7 @@ | |||
31 | 31 | ||
32 | #include <asm/tlbflush.h> | 32 | #include <asm/tlbflush.h> |
33 | #include <asm/desc.h> | 33 | #include <asm/desc.h> |
34 | #include <asm/kvm_para.h> | ||
34 | 35 | ||
35 | #include <asm/virtext.h> | 36 | #include <asm/virtext.h> |
36 | #include "trace.h" | 37 | #include "trace.h" |
@@ -50,6 +51,10 @@ MODULE_LICENSE("GPL"); | |||
50 | #define SVM_FEATURE_LBRV (1 << 1) | 51 | #define SVM_FEATURE_LBRV (1 << 1) |
51 | #define SVM_FEATURE_SVML (1 << 2) | 52 | #define SVM_FEATURE_SVML (1 << 2) |
52 | #define SVM_FEATURE_NRIP (1 << 3) | 53 | #define SVM_FEATURE_NRIP (1 << 3) |
54 | #define SVM_FEATURE_TSC_RATE (1 << 4) | ||
55 | #define SVM_FEATURE_VMCB_CLEAN (1 << 5) | ||
56 | #define SVM_FEATURE_FLUSH_ASID (1 << 6) | ||
57 | #define SVM_FEATURE_DECODE_ASSIST (1 << 7) | ||
53 | #define SVM_FEATURE_PAUSE_FILTER (1 << 10) | 58 | #define SVM_FEATURE_PAUSE_FILTER (1 << 10) |
54 | 59 | ||
55 | #define NESTED_EXIT_HOST 0 /* Exit handled on host level */ | 60 | #define NESTED_EXIT_HOST 0 /* Exit handled on host level */ |
@@ -97,10 +102,8 @@ struct nested_state { | |||
97 | unsigned long vmexit_rax; | 102 | unsigned long vmexit_rax; |
98 | 103 | ||
99 | /* cache for intercepts of the guest */ | 104 | /* cache for intercepts of the guest */ |
100 | u16 intercept_cr_read; | 105 | u32 intercept_cr; |
101 | u16 intercept_cr_write; | 106 | u32 intercept_dr; |
102 | u16 intercept_dr_read; | ||
103 | u16 intercept_dr_write; | ||
104 | u32 intercept_exceptions; | 107 | u32 intercept_exceptions; |
105 | u64 intercept; | 108 | u64 intercept; |
106 | 109 | ||
@@ -123,7 +126,12 @@ struct vcpu_svm { | |||
123 | u64 next_rip; | 126 | u64 next_rip; |
124 | 127 | ||
125 | u64 host_user_msrs[NR_HOST_SAVE_USER_MSRS]; | 128 | u64 host_user_msrs[NR_HOST_SAVE_USER_MSRS]; |
126 | u64 host_gs_base; | 129 | struct { |
130 | u16 fs; | ||
131 | u16 gs; | ||
132 | u16 ldt; | ||
133 | u64 gs_base; | ||
134 | } host; | ||
127 | 135 | ||
128 | u32 *msrpm; | 136 | u32 *msrpm; |
129 | 137 | ||
@@ -133,6 +141,7 @@ struct vcpu_svm { | |||
133 | 141 | ||
134 | unsigned int3_injected; | 142 | unsigned int3_injected; |
135 | unsigned long int3_rip; | 143 | unsigned long int3_rip; |
144 | u32 apf_reason; | ||
136 | }; | 145 | }; |
137 | 146 | ||
138 | #define MSR_INVALID 0xffffffffU | 147 | #define MSR_INVALID 0xffffffffU |
@@ -180,14 +189,151 @@ static int nested_svm_vmexit(struct vcpu_svm *svm); | |||
180 | static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr, | 189 | static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr, |
181 | bool has_error_code, u32 error_code); | 190 | bool has_error_code, u32 error_code); |
182 | 191 | ||
192 | enum { | ||
193 | VMCB_INTERCEPTS, /* Intercept vectors, TSC offset, | ||
194 | pause filter count */ | ||
195 | VMCB_PERM_MAP, /* IOPM Base and MSRPM Base */ | ||
196 | VMCB_ASID, /* ASID */ | ||
197 | VMCB_INTR, /* int_ctl, int_vector */ | ||
198 | VMCB_NPT, /* npt_en, nCR3, gPAT */ | ||
199 | VMCB_CR, /* CR0, CR3, CR4, EFER */ | ||
200 | VMCB_DR, /* DR6, DR7 */ | ||
201 | VMCB_DT, /* GDT, IDT */ | ||
202 | VMCB_SEG, /* CS, DS, SS, ES, CPL */ | ||
203 | VMCB_CR2, /* CR2 only */ | ||
204 | VMCB_LBR, /* DBGCTL, BR_FROM, BR_TO, LAST_EX_FROM, LAST_EX_TO */ | ||
205 | VMCB_DIRTY_MAX, | ||
206 | }; | ||
207 | |||
208 | /* TPR and CR2 are always written before VMRUN */ | ||
209 | #define VMCB_ALWAYS_DIRTY_MASK ((1U << VMCB_INTR) | (1U << VMCB_CR2)) | ||
210 | |||
211 | static inline void mark_all_dirty(struct vmcb *vmcb) | ||
212 | { | ||
213 | vmcb->control.clean = 0; | ||
214 | } | ||
215 | |||
216 | static inline void mark_all_clean(struct vmcb *vmcb) | ||
217 | { | ||
218 | vmcb->control.clean = ((1 << VMCB_DIRTY_MAX) - 1) | ||
219 | & ~VMCB_ALWAYS_DIRTY_MASK; | ||
220 | } | ||
221 | |||
222 | static inline void mark_dirty(struct vmcb *vmcb, int bit) | ||
223 | { | ||
224 | vmcb->control.clean &= ~(1 << bit); | ||
225 | } | ||
226 | |||
183 | static inline struct vcpu_svm *to_svm(struct kvm_vcpu *vcpu) | 227 | static inline struct vcpu_svm *to_svm(struct kvm_vcpu *vcpu) |
184 | { | 228 | { |
185 | return container_of(vcpu, struct vcpu_svm, vcpu); | 229 | return container_of(vcpu, struct vcpu_svm, vcpu); |
186 | } | 230 | } |
187 | 231 | ||
188 | static inline bool is_nested(struct vcpu_svm *svm) | 232 | static void recalc_intercepts(struct vcpu_svm *svm) |
233 | { | ||
234 | struct vmcb_control_area *c, *h; | ||
235 | struct nested_state *g; | ||
236 | |||
237 | mark_dirty(svm->vmcb, VMCB_INTERCEPTS); | ||
238 | |||
239 | if (!is_guest_mode(&svm->vcpu)) | ||
240 | return; | ||
241 | |||
242 | c = &svm->vmcb->control; | ||
243 | h = &svm->nested.hsave->control; | ||
244 | g = &svm->nested; | ||
245 | |||
246 | c->intercept_cr = h->intercept_cr | g->intercept_cr; | ||
247 | c->intercept_dr = h->intercept_dr | g->intercept_dr; | ||
248 | c->intercept_exceptions = h->intercept_exceptions | g->intercept_exceptions; | ||
249 | c->intercept = h->intercept | g->intercept; | ||
250 | } | ||
251 | |||
252 | static inline struct vmcb *get_host_vmcb(struct vcpu_svm *svm) | ||
253 | { | ||
254 | if (is_guest_mode(&svm->vcpu)) | ||
255 | return svm->nested.hsave; | ||
256 | else | ||
257 | return svm->vmcb; | ||
258 | } | ||
259 | |||
260 | static inline void set_cr_intercept(struct vcpu_svm *svm, int bit) | ||
261 | { | ||
262 | struct vmcb *vmcb = get_host_vmcb(svm); | ||
263 | |||
264 | vmcb->control.intercept_cr |= (1U << bit); | ||
265 | |||
266 | recalc_intercepts(svm); | ||
267 | } | ||
268 | |||
269 | static inline void clr_cr_intercept(struct vcpu_svm *svm, int bit) | ||
270 | { | ||
271 | struct vmcb *vmcb = get_host_vmcb(svm); | ||
272 | |||
273 | vmcb->control.intercept_cr &= ~(1U << bit); | ||
274 | |||
275 | recalc_intercepts(svm); | ||
276 | } | ||
277 | |||
278 | static inline bool is_cr_intercept(struct vcpu_svm *svm, int bit) | ||
279 | { | ||
280 | struct vmcb *vmcb = get_host_vmcb(svm); | ||
281 | |||
282 | return vmcb->control.intercept_cr & (1U << bit); | ||
283 | } | ||
284 | |||
285 | static inline void set_dr_intercept(struct vcpu_svm *svm, int bit) | ||
286 | { | ||
287 | struct vmcb *vmcb = get_host_vmcb(svm); | ||
288 | |||
289 | vmcb->control.intercept_dr |= (1U << bit); | ||
290 | |||
291 | recalc_intercepts(svm); | ||
292 | } | ||
293 | |||
294 | static inline void clr_dr_intercept(struct vcpu_svm *svm, int bit) | ||
295 | { | ||
296 | struct vmcb *vmcb = get_host_vmcb(svm); | ||
297 | |||
298 | vmcb->control.intercept_dr &= ~(1U << bit); | ||
299 | |||
300 | recalc_intercepts(svm); | ||
301 | } | ||
302 | |||
303 | static inline void set_exception_intercept(struct vcpu_svm *svm, int bit) | ||
304 | { | ||
305 | struct vmcb *vmcb = get_host_vmcb(svm); | ||
306 | |||
307 | vmcb->control.intercept_exceptions |= (1U << bit); | ||
308 | |||
309 | recalc_intercepts(svm); | ||
310 | } | ||
311 | |||
312 | static inline void clr_exception_intercept(struct vcpu_svm *svm, int bit) | ||
189 | { | 313 | { |
190 | return svm->nested.vmcb; | 314 | struct vmcb *vmcb = get_host_vmcb(svm); |
315 | |||
316 | vmcb->control.intercept_exceptions &= ~(1U << bit); | ||
317 | |||
318 | recalc_intercepts(svm); | ||
319 | } | ||
320 | |||
321 | static inline void set_intercept(struct vcpu_svm *svm, int bit) | ||
322 | { | ||
323 | struct vmcb *vmcb = get_host_vmcb(svm); | ||
324 | |||
325 | vmcb->control.intercept |= (1ULL << bit); | ||
326 | |||
327 | recalc_intercepts(svm); | ||
328 | } | ||
329 | |||
330 | static inline void clr_intercept(struct vcpu_svm *svm, int bit) | ||
331 | { | ||
332 | struct vmcb *vmcb = get_host_vmcb(svm); | ||
333 | |||
334 | vmcb->control.intercept &= ~(1ULL << bit); | ||
335 | |||
336 | recalc_intercepts(svm); | ||
191 | } | 337 | } |
192 | 338 | ||
193 | static inline void enable_gif(struct vcpu_svm *svm) | 339 | static inline void enable_gif(struct vcpu_svm *svm) |
@@ -264,11 +410,6 @@ static u32 svm_msrpm_offset(u32 msr) | |||
264 | 410 | ||
265 | #define MAX_INST_SIZE 15 | 411 | #define MAX_INST_SIZE 15 |
266 | 412 | ||
267 | static inline u32 svm_has(u32 feat) | ||
268 | { | ||
269 | return svm_features & feat; | ||
270 | } | ||
271 | |||
272 | static inline void clgi(void) | 413 | static inline void clgi(void) |
273 | { | 414 | { |
274 | asm volatile (__ex(SVM_CLGI)); | 415 | asm volatile (__ex(SVM_CLGI)); |
@@ -284,16 +425,6 @@ static inline void invlpga(unsigned long addr, u32 asid) | |||
284 | asm volatile (__ex(SVM_INVLPGA) : : "a"(addr), "c"(asid)); | 425 | asm volatile (__ex(SVM_INVLPGA) : : "a"(addr), "c"(asid)); |
285 | } | 426 | } |
286 | 427 | ||
287 | static inline void force_new_asid(struct kvm_vcpu *vcpu) | ||
288 | { | ||
289 | to_svm(vcpu)->asid_generation--; | ||
290 | } | ||
291 | |||
292 | static inline void flush_guest_tlb(struct kvm_vcpu *vcpu) | ||
293 | { | ||
294 | force_new_asid(vcpu); | ||
295 | } | ||
296 | |||
297 | static int get_npt_level(void) | 428 | static int get_npt_level(void) |
298 | { | 429 | { |
299 | #ifdef CONFIG_X86_64 | 430 | #ifdef CONFIG_X86_64 |
@@ -310,6 +441,7 @@ static void svm_set_efer(struct kvm_vcpu *vcpu, u64 efer) | |||
310 | efer &= ~EFER_LME; | 441 | efer &= ~EFER_LME; |
311 | 442 | ||
312 | to_svm(vcpu)->vmcb->save.efer = efer | EFER_SVME; | 443 | to_svm(vcpu)->vmcb->save.efer = efer | EFER_SVME; |
444 | mark_dirty(to_svm(vcpu)->vmcb, VMCB_CR); | ||
313 | } | 445 | } |
314 | 446 | ||
315 | static int is_external_interrupt(u32 info) | 447 | static int is_external_interrupt(u32 info) |
@@ -347,7 +479,7 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu) | |||
347 | svm->next_rip = svm->vmcb->control.next_rip; | 479 | svm->next_rip = svm->vmcb->control.next_rip; |
348 | 480 | ||
349 | if (!svm->next_rip) { | 481 | if (!svm->next_rip) { |
350 | if (emulate_instruction(vcpu, 0, 0, EMULTYPE_SKIP) != | 482 | if (emulate_instruction(vcpu, EMULTYPE_SKIP) != |
351 | EMULATE_DONE) | 483 | EMULATE_DONE) |
352 | printk(KERN_DEBUG "%s: NOP\n", __func__); | 484 | printk(KERN_DEBUG "%s: NOP\n", __func__); |
353 | return; | 485 | return; |
@@ -374,7 +506,7 @@ static void svm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, | |||
374 | nested_svm_check_exception(svm, nr, has_error_code, error_code)) | 506 | nested_svm_check_exception(svm, nr, has_error_code, error_code)) |
375 | return; | 507 | return; |
376 | 508 | ||
377 | if (nr == BP_VECTOR && !svm_has(SVM_FEATURE_NRIP)) { | 509 | if (nr == BP_VECTOR && !static_cpu_has(X86_FEATURE_NRIPS)) { |
378 | unsigned long rip, old_rip = kvm_rip_read(&svm->vcpu); | 510 | unsigned long rip, old_rip = kvm_rip_read(&svm->vcpu); |
379 | 511 | ||
380 | /* | 512 | /* |
@@ -670,7 +802,7 @@ static __init int svm_hardware_setup(void) | |||
670 | 802 | ||
671 | svm_features = cpuid_edx(SVM_CPUID_FUNC); | 803 | svm_features = cpuid_edx(SVM_CPUID_FUNC); |
672 | 804 | ||
673 | if (!svm_has(SVM_FEATURE_NPT)) | 805 | if (!boot_cpu_has(X86_FEATURE_NPT)) |
674 | npt_enabled = false; | 806 | npt_enabled = false; |
675 | 807 | ||
676 | if (npt_enabled && !npt) { | 808 | if (npt_enabled && !npt) { |
@@ -725,13 +857,15 @@ static void svm_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset) | |||
725 | struct vcpu_svm *svm = to_svm(vcpu); | 857 | struct vcpu_svm *svm = to_svm(vcpu); |
726 | u64 g_tsc_offset = 0; | 858 | u64 g_tsc_offset = 0; |
727 | 859 | ||
728 | if (is_nested(svm)) { | 860 | if (is_guest_mode(vcpu)) { |
729 | g_tsc_offset = svm->vmcb->control.tsc_offset - | 861 | g_tsc_offset = svm->vmcb->control.tsc_offset - |
730 | svm->nested.hsave->control.tsc_offset; | 862 | svm->nested.hsave->control.tsc_offset; |
731 | svm->nested.hsave->control.tsc_offset = offset; | 863 | svm->nested.hsave->control.tsc_offset = offset; |
732 | } | 864 | } |
733 | 865 | ||
734 | svm->vmcb->control.tsc_offset = offset + g_tsc_offset; | 866 | svm->vmcb->control.tsc_offset = offset + g_tsc_offset; |
867 | |||
868 | mark_dirty(svm->vmcb, VMCB_INTERCEPTS); | ||
735 | } | 869 | } |
736 | 870 | ||
737 | static void svm_adjust_tsc_offset(struct kvm_vcpu *vcpu, s64 adjustment) | 871 | static void svm_adjust_tsc_offset(struct kvm_vcpu *vcpu, s64 adjustment) |
@@ -739,8 +873,9 @@ static void svm_adjust_tsc_offset(struct kvm_vcpu *vcpu, s64 adjustment) | |||
739 | struct vcpu_svm *svm = to_svm(vcpu); | 873 | struct vcpu_svm *svm = to_svm(vcpu); |
740 | 874 | ||
741 | svm->vmcb->control.tsc_offset += adjustment; | 875 | svm->vmcb->control.tsc_offset += adjustment; |
742 | if (is_nested(svm)) | 876 | if (is_guest_mode(vcpu)) |
743 | svm->nested.hsave->control.tsc_offset += adjustment; | 877 | svm->nested.hsave->control.tsc_offset += adjustment; |
878 | mark_dirty(svm->vmcb, VMCB_INTERCEPTS); | ||
744 | } | 879 | } |
745 | 880 | ||
746 | static void init_vmcb(struct vcpu_svm *svm) | 881 | static void init_vmcb(struct vcpu_svm *svm) |
@@ -749,62 +884,62 @@ static void init_vmcb(struct vcpu_svm *svm) | |||
749 | struct vmcb_save_area *save = &svm->vmcb->save; | 884 | struct vmcb_save_area *save = &svm->vmcb->save; |
750 | 885 | ||
751 | svm->vcpu.fpu_active = 1; | 886 | svm->vcpu.fpu_active = 1; |
887 | svm->vcpu.arch.hflags = 0; | ||
752 | 888 | ||
753 | control->intercept_cr_read = INTERCEPT_CR0_MASK | | 889 | set_cr_intercept(svm, INTERCEPT_CR0_READ); |
754 | INTERCEPT_CR3_MASK | | 890 | set_cr_intercept(svm, INTERCEPT_CR3_READ); |
755 | INTERCEPT_CR4_MASK; | 891 | set_cr_intercept(svm, INTERCEPT_CR4_READ); |
756 | 892 | set_cr_intercept(svm, INTERCEPT_CR0_WRITE); | |
757 | control->intercept_cr_write = INTERCEPT_CR0_MASK | | 893 | set_cr_intercept(svm, INTERCEPT_CR3_WRITE); |
758 | INTERCEPT_CR3_MASK | | 894 | set_cr_intercept(svm, INTERCEPT_CR4_WRITE); |
759 | INTERCEPT_CR4_MASK | | 895 | set_cr_intercept(svm, INTERCEPT_CR8_WRITE); |
760 | INTERCEPT_CR8_MASK; | 896 | |
761 | 897 | set_dr_intercept(svm, INTERCEPT_DR0_READ); | |
762 | control->intercept_dr_read = INTERCEPT_DR0_MASK | | 898 | set_dr_intercept(svm, INTERCEPT_DR1_READ); |
763 | INTERCEPT_DR1_MASK | | 899 | set_dr_intercept(svm, INTERCEPT_DR2_READ); |
764 | INTERCEPT_DR2_MASK | | 900 | set_dr_intercept(svm, INTERCEPT_DR3_READ); |
765 | INTERCEPT_DR3_MASK | | 901 | set_dr_intercept(svm, INTERCEPT_DR4_READ); |
766 | INTERCEPT_DR4_MASK | | 902 | set_dr_intercept(svm, INTERCEPT_DR5_READ); |
767 | INTERCEPT_DR5_MASK | | 903 | set_dr_intercept(svm, INTERCEPT_DR6_READ); |
768 | INTERCEPT_DR6_MASK | | 904 | set_dr_intercept(svm, INTERCEPT_DR7_READ); |
769 | INTERCEPT_DR7_MASK; | 905 | |
770 | 906 | set_dr_intercept(svm, INTERCEPT_DR0_WRITE); | |
771 | control->intercept_dr_write = INTERCEPT_DR0_MASK | | 907 | set_dr_intercept(svm, INTERCEPT_DR1_WRITE); |
772 | INTERCEPT_DR1_MASK | | 908 | set_dr_intercept(svm, INTERCEPT_DR2_WRITE); |
773 | INTERCEPT_DR2_MASK | | 909 | set_dr_intercept(svm, INTERCEPT_DR3_WRITE); |
774 | INTERCEPT_DR3_MASK | | 910 | set_dr_intercept(svm, INTERCEPT_DR4_WRITE); |
775 | INTERCEPT_DR4_MASK | | 911 | set_dr_intercept(svm, INTERCEPT_DR5_WRITE); |
776 | INTERCEPT_DR5_MASK | | 912 | set_dr_intercept(svm, INTERCEPT_DR6_WRITE); |
777 | INTERCEPT_DR6_MASK | | 913 | set_dr_intercept(svm, INTERCEPT_DR7_WRITE); |
778 | INTERCEPT_DR7_MASK; | 914 | |
779 | 915 | set_exception_intercept(svm, PF_VECTOR); | |
780 | control->intercept_exceptions = (1 << PF_VECTOR) | | 916 | set_exception_intercept(svm, UD_VECTOR); |
781 | (1 << UD_VECTOR) | | 917 | set_exception_intercept(svm, MC_VECTOR); |
782 | (1 << MC_VECTOR); | 918 | |
783 | 919 | set_intercept(svm, INTERCEPT_INTR); | |
784 | 920 | set_intercept(svm, INTERCEPT_NMI); | |
785 | control->intercept = (1ULL << INTERCEPT_INTR) | | 921 | set_intercept(svm, INTERCEPT_SMI); |
786 | (1ULL << INTERCEPT_NMI) | | 922 | set_intercept(svm, INTERCEPT_SELECTIVE_CR0); |
787 | (1ULL << INTERCEPT_SMI) | | 923 | set_intercept(svm, INTERCEPT_CPUID); |
788 | (1ULL << INTERCEPT_SELECTIVE_CR0) | | 924 | set_intercept(svm, INTERCEPT_INVD); |
789 | (1ULL << INTERCEPT_CPUID) | | 925 | set_intercept(svm, INTERCEPT_HLT); |
790 | (1ULL << INTERCEPT_INVD) | | 926 | set_intercept(svm, INTERCEPT_INVLPG); |
791 | (1ULL << INTERCEPT_HLT) | | 927 | set_intercept(svm, INTERCEPT_INVLPGA); |
792 | (1ULL << INTERCEPT_INVLPG) | | 928 | set_intercept(svm, INTERCEPT_IOIO_PROT); |
793 | (1ULL << INTERCEPT_INVLPGA) | | 929 | set_intercept(svm, INTERCEPT_MSR_PROT); |
794 | (1ULL << INTERCEPT_IOIO_PROT) | | 930 | set_intercept(svm, INTERCEPT_TASK_SWITCH); |
795 | (1ULL << INTERCEPT_MSR_PROT) | | 931 | set_intercept(svm, INTERCEPT_SHUTDOWN); |
796 | (1ULL << INTERCEPT_TASK_SWITCH) | | 932 | set_intercept(svm, INTERCEPT_VMRUN); |
797 | (1ULL << INTERCEPT_SHUTDOWN) | | 933 | set_intercept(svm, INTERCEPT_VMMCALL); |
798 | (1ULL << INTERCEPT_VMRUN) | | 934 | set_intercept(svm, INTERCEPT_VMLOAD); |
799 | (1ULL << INTERCEPT_VMMCALL) | | 935 | set_intercept(svm, INTERCEPT_VMSAVE); |
800 | (1ULL << INTERCEPT_VMLOAD) | | 936 | set_intercept(svm, INTERCEPT_STGI); |
801 | (1ULL << INTERCEPT_VMSAVE) | | 937 | set_intercept(svm, INTERCEPT_CLGI); |
802 | (1ULL << INTERCEPT_STGI) | | 938 | set_intercept(svm, INTERCEPT_SKINIT); |
803 | (1ULL << INTERCEPT_CLGI) | | 939 | set_intercept(svm, INTERCEPT_WBINVD); |
804 | (1ULL << INTERCEPT_SKINIT) | | 940 | set_intercept(svm, INTERCEPT_MONITOR); |
805 | (1ULL << INTERCEPT_WBINVD) | | 941 | set_intercept(svm, INTERCEPT_MWAIT); |
806 | (1ULL << INTERCEPT_MONITOR) | | 942 | set_intercept(svm, INTERCEPT_XSETBV); |
807 | (1ULL << INTERCEPT_MWAIT); | ||
808 | 943 | ||
809 | control->iopm_base_pa = iopm_base; | 944 | control->iopm_base_pa = iopm_base; |
810 | control->msrpm_base_pa = __pa(svm->msrpm); | 945 | control->msrpm_base_pa = __pa(svm->msrpm); |
@@ -855,25 +990,27 @@ static void init_vmcb(struct vcpu_svm *svm) | |||
855 | if (npt_enabled) { | 990 | if (npt_enabled) { |
856 | /* Setup VMCB for Nested Paging */ | 991 | /* Setup VMCB for Nested Paging */ |
857 | control->nested_ctl = 1; | 992 | control->nested_ctl = 1; |
858 | control->intercept &= ~((1ULL << INTERCEPT_TASK_SWITCH) | | 993 | clr_intercept(svm, INTERCEPT_TASK_SWITCH); |
859 | (1ULL << INTERCEPT_INVLPG)); | 994 | clr_intercept(svm, INTERCEPT_INVLPG); |
860 | control->intercept_exceptions &= ~(1 << PF_VECTOR); | 995 | clr_exception_intercept(svm, PF_VECTOR); |
861 | control->intercept_cr_read &= ~INTERCEPT_CR3_MASK; | 996 | clr_cr_intercept(svm, INTERCEPT_CR3_READ); |
862 | control->intercept_cr_write &= ~INTERCEPT_CR3_MASK; | 997 | clr_cr_intercept(svm, INTERCEPT_CR3_WRITE); |
863 | save->g_pat = 0x0007040600070406ULL; | 998 | save->g_pat = 0x0007040600070406ULL; |
864 | save->cr3 = 0; | 999 | save->cr3 = 0; |
865 | save->cr4 = 0; | 1000 | save->cr4 = 0; |
866 | } | 1001 | } |
867 | force_new_asid(&svm->vcpu); | 1002 | svm->asid_generation = 0; |
868 | 1003 | ||
869 | svm->nested.vmcb = 0; | 1004 | svm->nested.vmcb = 0; |
870 | svm->vcpu.arch.hflags = 0; | 1005 | svm->vcpu.arch.hflags = 0; |
871 | 1006 | ||
872 | if (svm_has(SVM_FEATURE_PAUSE_FILTER)) { | 1007 | if (boot_cpu_has(X86_FEATURE_PAUSEFILTER)) { |
873 | control->pause_filter_count = 3000; | 1008 | control->pause_filter_count = 3000; |
874 | control->intercept |= (1ULL << INTERCEPT_PAUSE); | 1009 | set_intercept(svm, INTERCEPT_PAUSE); |
875 | } | 1010 | } |
876 | 1011 | ||
1012 | mark_all_dirty(svm->vmcb); | ||
1013 | |||
877 | enable_gif(svm); | 1014 | enable_gif(svm); |
878 | } | 1015 | } |
879 | 1016 | ||
@@ -990,8 +1127,16 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | |||
990 | 1127 | ||
991 | if (unlikely(cpu != vcpu->cpu)) { | 1128 | if (unlikely(cpu != vcpu->cpu)) { |
992 | svm->asid_generation = 0; | 1129 | svm->asid_generation = 0; |
1130 | mark_all_dirty(svm->vmcb); | ||
993 | } | 1131 | } |
994 | 1132 | ||
1133 | #ifdef CONFIG_X86_64 | ||
1134 | rdmsrl(MSR_GS_BASE, to_svm(vcpu)->host.gs_base); | ||
1135 | #endif | ||
1136 | savesegment(fs, svm->host.fs); | ||
1137 | savesegment(gs, svm->host.gs); | ||
1138 | svm->host.ldt = kvm_read_ldt(); | ||
1139 | |||
995 | for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++) | 1140 | for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++) |
996 | rdmsrl(host_save_user_msrs[i], svm->host_user_msrs[i]); | 1141 | rdmsrl(host_save_user_msrs[i], svm->host_user_msrs[i]); |
997 | } | 1142 | } |
@@ -1002,6 +1147,14 @@ static void svm_vcpu_put(struct kvm_vcpu *vcpu) | |||
1002 | int i; | 1147 | int i; |
1003 | 1148 | ||
1004 | ++vcpu->stat.host_state_reload; | 1149 | ++vcpu->stat.host_state_reload; |
1150 | kvm_load_ldt(svm->host.ldt); | ||
1151 | #ifdef CONFIG_X86_64 | ||
1152 | loadsegment(fs, svm->host.fs); | ||
1153 | load_gs_index(svm->host.gs); | ||
1154 | wrmsrl(MSR_KERNEL_GS_BASE, current->thread.gs); | ||
1155 | #else | ||
1156 | loadsegment(gs, svm->host.gs); | ||
1157 | #endif | ||
1005 | for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++) | 1158 | for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++) |
1006 | wrmsrl(host_save_user_msrs[i], svm->host_user_msrs[i]); | 1159 | wrmsrl(host_save_user_msrs[i], svm->host_user_msrs[i]); |
1007 | } | 1160 | } |
@@ -1021,7 +1174,7 @@ static void svm_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg) | |||
1021 | switch (reg) { | 1174 | switch (reg) { |
1022 | case VCPU_EXREG_PDPTR: | 1175 | case VCPU_EXREG_PDPTR: |
1023 | BUG_ON(!npt_enabled); | 1176 | BUG_ON(!npt_enabled); |
1024 | load_pdptrs(vcpu, vcpu->arch.walk_mmu, vcpu->arch.cr3); | 1177 | load_pdptrs(vcpu, vcpu->arch.walk_mmu, kvm_read_cr3(vcpu)); |
1025 | break; | 1178 | break; |
1026 | default: | 1179 | default: |
1027 | BUG(); | 1180 | BUG(); |
@@ -1030,12 +1183,12 @@ static void svm_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg) | |||
1030 | 1183 | ||
1031 | static void svm_set_vintr(struct vcpu_svm *svm) | 1184 | static void svm_set_vintr(struct vcpu_svm *svm) |
1032 | { | 1185 | { |
1033 | svm->vmcb->control.intercept |= 1ULL << INTERCEPT_VINTR; | 1186 | set_intercept(svm, INTERCEPT_VINTR); |
1034 | } | 1187 | } |
1035 | 1188 | ||
1036 | static void svm_clear_vintr(struct vcpu_svm *svm) | 1189 | static void svm_clear_vintr(struct vcpu_svm *svm) |
1037 | { | 1190 | { |
1038 | svm->vmcb->control.intercept &= ~(1ULL << INTERCEPT_VINTR); | 1191 | clr_intercept(svm, INTERCEPT_VINTR); |
1039 | } | 1192 | } |
1040 | 1193 | ||
1041 | static struct vmcb_seg *svm_seg(struct kvm_vcpu *vcpu, int seg) | 1194 | static struct vmcb_seg *svm_seg(struct kvm_vcpu *vcpu, int seg) |
@@ -1150,6 +1303,7 @@ static void svm_set_idt(struct kvm_vcpu *vcpu, struct desc_ptr *dt) | |||
1150 | 1303 | ||
1151 | svm->vmcb->save.idtr.limit = dt->size; | 1304 | svm->vmcb->save.idtr.limit = dt->size; |
1152 | svm->vmcb->save.idtr.base = dt->address ; | 1305 | svm->vmcb->save.idtr.base = dt->address ; |
1306 | mark_dirty(svm->vmcb, VMCB_DT); | ||
1153 | } | 1307 | } |
1154 | 1308 | ||
1155 | static void svm_get_gdt(struct kvm_vcpu *vcpu, struct desc_ptr *dt) | 1309 | static void svm_get_gdt(struct kvm_vcpu *vcpu, struct desc_ptr *dt) |
@@ -1166,19 +1320,23 @@ static void svm_set_gdt(struct kvm_vcpu *vcpu, struct desc_ptr *dt) | |||
1166 | 1320 | ||
1167 | svm->vmcb->save.gdtr.limit = dt->size; | 1321 | svm->vmcb->save.gdtr.limit = dt->size; |
1168 | svm->vmcb->save.gdtr.base = dt->address ; | 1322 | svm->vmcb->save.gdtr.base = dt->address ; |
1323 | mark_dirty(svm->vmcb, VMCB_DT); | ||
1169 | } | 1324 | } |
1170 | 1325 | ||
1171 | static void svm_decache_cr0_guest_bits(struct kvm_vcpu *vcpu) | 1326 | static void svm_decache_cr0_guest_bits(struct kvm_vcpu *vcpu) |
1172 | { | 1327 | { |
1173 | } | 1328 | } |
1174 | 1329 | ||
1330 | static void svm_decache_cr3(struct kvm_vcpu *vcpu) | ||
1331 | { | ||
1332 | } | ||
1333 | |||
1175 | static void svm_decache_cr4_guest_bits(struct kvm_vcpu *vcpu) | 1334 | static void svm_decache_cr4_guest_bits(struct kvm_vcpu *vcpu) |
1176 | { | 1335 | { |
1177 | } | 1336 | } |
1178 | 1337 | ||
1179 | static void update_cr0_intercept(struct vcpu_svm *svm) | 1338 | static void update_cr0_intercept(struct vcpu_svm *svm) |
1180 | { | 1339 | { |
1181 | struct vmcb *vmcb = svm->vmcb; | ||
1182 | ulong gcr0 = svm->vcpu.arch.cr0; | 1340 | ulong gcr0 = svm->vcpu.arch.cr0; |
1183 | u64 *hcr0 = &svm->vmcb->save.cr0; | 1341 | u64 *hcr0 = &svm->vmcb->save.cr0; |
1184 | 1342 | ||
@@ -1188,27 +1346,14 @@ static void update_cr0_intercept(struct vcpu_svm *svm) | |||
1188 | *hcr0 = (*hcr0 & ~SVM_CR0_SELECTIVE_MASK) | 1346 | *hcr0 = (*hcr0 & ~SVM_CR0_SELECTIVE_MASK) |
1189 | | (gcr0 & SVM_CR0_SELECTIVE_MASK); | 1347 | | (gcr0 & SVM_CR0_SELECTIVE_MASK); |
1190 | 1348 | ||
1349 | mark_dirty(svm->vmcb, VMCB_CR); | ||
1191 | 1350 | ||
1192 | if (gcr0 == *hcr0 && svm->vcpu.fpu_active) { | 1351 | if (gcr0 == *hcr0 && svm->vcpu.fpu_active) { |
1193 | vmcb->control.intercept_cr_read &= ~INTERCEPT_CR0_MASK; | 1352 | clr_cr_intercept(svm, INTERCEPT_CR0_READ); |
1194 | vmcb->control.intercept_cr_write &= ~INTERCEPT_CR0_MASK; | 1353 | clr_cr_intercept(svm, INTERCEPT_CR0_WRITE); |
1195 | if (is_nested(svm)) { | ||
1196 | struct vmcb *hsave = svm->nested.hsave; | ||
1197 | |||
1198 | hsave->control.intercept_cr_read &= ~INTERCEPT_CR0_MASK; | ||
1199 | hsave->control.intercept_cr_write &= ~INTERCEPT_CR0_MASK; | ||
1200 | vmcb->control.intercept_cr_read |= svm->nested.intercept_cr_read; | ||
1201 | vmcb->control.intercept_cr_write |= svm->nested.intercept_cr_write; | ||
1202 | } | ||
1203 | } else { | 1354 | } else { |
1204 | svm->vmcb->control.intercept_cr_read |= INTERCEPT_CR0_MASK; | 1355 | set_cr_intercept(svm, INTERCEPT_CR0_READ); |
1205 | svm->vmcb->control.intercept_cr_write |= INTERCEPT_CR0_MASK; | 1356 | set_cr_intercept(svm, INTERCEPT_CR0_WRITE); |
1206 | if (is_nested(svm)) { | ||
1207 | struct vmcb *hsave = svm->nested.hsave; | ||
1208 | |||
1209 | hsave->control.intercept_cr_read |= INTERCEPT_CR0_MASK; | ||
1210 | hsave->control.intercept_cr_write |= INTERCEPT_CR0_MASK; | ||
1211 | } | ||
1212 | } | 1357 | } |
1213 | } | 1358 | } |
1214 | 1359 | ||
@@ -1216,7 +1361,7 @@ static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) | |||
1216 | { | 1361 | { |
1217 | struct vcpu_svm *svm = to_svm(vcpu); | 1362 | struct vcpu_svm *svm = to_svm(vcpu); |
1218 | 1363 | ||
1219 | if (is_nested(svm)) { | 1364 | if (is_guest_mode(vcpu)) { |
1220 | /* | 1365 | /* |
1221 | * We are here because we run in nested mode, the host kvm | 1366 | * We are here because we run in nested mode, the host kvm |
1222 | * intercepts cr0 writes but the l1 hypervisor does not. | 1367 | * intercepts cr0 writes but the l1 hypervisor does not. |
@@ -1268,6 +1413,7 @@ static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) | |||
1268 | */ | 1413 | */ |
1269 | cr0 &= ~(X86_CR0_CD | X86_CR0_NW); | 1414 | cr0 &= ~(X86_CR0_CD | X86_CR0_NW); |
1270 | svm->vmcb->save.cr0 = cr0; | 1415 | svm->vmcb->save.cr0 = cr0; |
1416 | mark_dirty(svm->vmcb, VMCB_CR); | ||
1271 | update_cr0_intercept(svm); | 1417 | update_cr0_intercept(svm); |
1272 | } | 1418 | } |
1273 | 1419 | ||
@@ -1277,13 +1423,14 @@ static void svm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) | |||
1277 | unsigned long old_cr4 = to_svm(vcpu)->vmcb->save.cr4; | 1423 | unsigned long old_cr4 = to_svm(vcpu)->vmcb->save.cr4; |
1278 | 1424 | ||
1279 | if (npt_enabled && ((old_cr4 ^ cr4) & X86_CR4_PGE)) | 1425 | if (npt_enabled && ((old_cr4 ^ cr4) & X86_CR4_PGE)) |
1280 | force_new_asid(vcpu); | 1426 | svm_flush_tlb(vcpu); |
1281 | 1427 | ||
1282 | vcpu->arch.cr4 = cr4; | 1428 | vcpu->arch.cr4 = cr4; |
1283 | if (!npt_enabled) | 1429 | if (!npt_enabled) |
1284 | cr4 |= X86_CR4_PAE; | 1430 | cr4 |= X86_CR4_PAE; |
1285 | cr4 |= host_cr4_mce; | 1431 | cr4 |= host_cr4_mce; |
1286 | to_svm(vcpu)->vmcb->save.cr4 = cr4; | 1432 | to_svm(vcpu)->vmcb->save.cr4 = cr4; |
1433 | mark_dirty(to_svm(vcpu)->vmcb, VMCB_CR); | ||
1287 | } | 1434 | } |
1288 | 1435 | ||
1289 | static void svm_set_segment(struct kvm_vcpu *vcpu, | 1436 | static void svm_set_segment(struct kvm_vcpu *vcpu, |
@@ -1312,26 +1459,25 @@ static void svm_set_segment(struct kvm_vcpu *vcpu, | |||
1312 | = (svm->vmcb->save.cs.attrib | 1459 | = (svm->vmcb->save.cs.attrib |
1313 | >> SVM_SELECTOR_DPL_SHIFT) & 3; | 1460 | >> SVM_SELECTOR_DPL_SHIFT) & 3; |
1314 | 1461 | ||
1462 | mark_dirty(svm->vmcb, VMCB_SEG); | ||
1315 | } | 1463 | } |
1316 | 1464 | ||
1317 | static void update_db_intercept(struct kvm_vcpu *vcpu) | 1465 | static void update_db_intercept(struct kvm_vcpu *vcpu) |
1318 | { | 1466 | { |
1319 | struct vcpu_svm *svm = to_svm(vcpu); | 1467 | struct vcpu_svm *svm = to_svm(vcpu); |
1320 | 1468 | ||
1321 | svm->vmcb->control.intercept_exceptions &= | 1469 | clr_exception_intercept(svm, DB_VECTOR); |
1322 | ~((1 << DB_VECTOR) | (1 << BP_VECTOR)); | 1470 | clr_exception_intercept(svm, BP_VECTOR); |
1323 | 1471 | ||
1324 | if (svm->nmi_singlestep) | 1472 | if (svm->nmi_singlestep) |
1325 | svm->vmcb->control.intercept_exceptions |= (1 << DB_VECTOR); | 1473 | set_exception_intercept(svm, DB_VECTOR); |
1326 | 1474 | ||
1327 | if (vcpu->guest_debug & KVM_GUESTDBG_ENABLE) { | 1475 | if (vcpu->guest_debug & KVM_GUESTDBG_ENABLE) { |
1328 | if (vcpu->guest_debug & | 1476 | if (vcpu->guest_debug & |
1329 | (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP)) | 1477 | (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP)) |
1330 | svm->vmcb->control.intercept_exceptions |= | 1478 | set_exception_intercept(svm, DB_VECTOR); |
1331 | 1 << DB_VECTOR; | ||
1332 | if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP) | 1479 | if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP) |
1333 | svm->vmcb->control.intercept_exceptions |= | 1480 | set_exception_intercept(svm, BP_VECTOR); |
1334 | 1 << BP_VECTOR; | ||
1335 | } else | 1481 | } else |
1336 | vcpu->guest_debug = 0; | 1482 | vcpu->guest_debug = 0; |
1337 | } | 1483 | } |
@@ -1345,21 +1491,9 @@ static void svm_guest_debug(struct kvm_vcpu *vcpu, struct kvm_guest_debug *dbg) | |||
1345 | else | 1491 | else |
1346 | svm->vmcb->save.dr7 = vcpu->arch.dr7; | 1492 | svm->vmcb->save.dr7 = vcpu->arch.dr7; |
1347 | 1493 | ||
1348 | update_db_intercept(vcpu); | 1494 | mark_dirty(svm->vmcb, VMCB_DR); |
1349 | } | ||
1350 | |||
1351 | static void load_host_msrs(struct kvm_vcpu *vcpu) | ||
1352 | { | ||
1353 | #ifdef CONFIG_X86_64 | ||
1354 | wrmsrl(MSR_GS_BASE, to_svm(vcpu)->host_gs_base); | ||
1355 | #endif | ||
1356 | } | ||
1357 | 1495 | ||
1358 | static void save_host_msrs(struct kvm_vcpu *vcpu) | 1496 | update_db_intercept(vcpu); |
1359 | { | ||
1360 | #ifdef CONFIG_X86_64 | ||
1361 | rdmsrl(MSR_GS_BASE, to_svm(vcpu)->host_gs_base); | ||
1362 | #endif | ||
1363 | } | 1497 | } |
1364 | 1498 | ||
1365 | static void new_asid(struct vcpu_svm *svm, struct svm_cpu_data *sd) | 1499 | static void new_asid(struct vcpu_svm *svm, struct svm_cpu_data *sd) |
@@ -1372,6 +1506,8 @@ static void new_asid(struct vcpu_svm *svm, struct svm_cpu_data *sd) | |||
1372 | 1506 | ||
1373 | svm->asid_generation = sd->asid_generation; | 1507 | svm->asid_generation = sd->asid_generation; |
1374 | svm->vmcb->control.asid = sd->next_asid++; | 1508 | svm->vmcb->control.asid = sd->next_asid++; |
1509 | |||
1510 | mark_dirty(svm->vmcb, VMCB_ASID); | ||
1375 | } | 1511 | } |
1376 | 1512 | ||
1377 | static void svm_set_dr7(struct kvm_vcpu *vcpu, unsigned long value) | 1513 | static void svm_set_dr7(struct kvm_vcpu *vcpu, unsigned long value) |
@@ -1379,20 +1515,40 @@ static void svm_set_dr7(struct kvm_vcpu *vcpu, unsigned long value) | |||
1379 | struct vcpu_svm *svm = to_svm(vcpu); | 1515 | struct vcpu_svm *svm = to_svm(vcpu); |
1380 | 1516 | ||
1381 | svm->vmcb->save.dr7 = value; | 1517 | svm->vmcb->save.dr7 = value; |
1518 | mark_dirty(svm->vmcb, VMCB_DR); | ||
1382 | } | 1519 | } |
1383 | 1520 | ||
1384 | static int pf_interception(struct vcpu_svm *svm) | 1521 | static int pf_interception(struct vcpu_svm *svm) |
1385 | { | 1522 | { |
1386 | u64 fault_address; | 1523 | u64 fault_address = svm->vmcb->control.exit_info_2; |
1387 | u32 error_code; | 1524 | u32 error_code; |
1525 | int r = 1; | ||
1388 | 1526 | ||
1389 | fault_address = svm->vmcb->control.exit_info_2; | 1527 | switch (svm->apf_reason) { |
1390 | error_code = svm->vmcb->control.exit_info_1; | 1528 | default: |
1391 | 1529 | error_code = svm->vmcb->control.exit_info_1; | |
1392 | trace_kvm_page_fault(fault_address, error_code); | 1530 | |
1393 | if (!npt_enabled && kvm_event_needs_reinjection(&svm->vcpu)) | 1531 | trace_kvm_page_fault(fault_address, error_code); |
1394 | kvm_mmu_unprotect_page_virt(&svm->vcpu, fault_address); | 1532 | if (!npt_enabled && kvm_event_needs_reinjection(&svm->vcpu)) |
1395 | return kvm_mmu_page_fault(&svm->vcpu, fault_address, error_code); | 1533 | kvm_mmu_unprotect_page_virt(&svm->vcpu, fault_address); |
1534 | r = kvm_mmu_page_fault(&svm->vcpu, fault_address, error_code, | ||
1535 | svm->vmcb->control.insn_bytes, | ||
1536 | svm->vmcb->control.insn_len); | ||
1537 | break; | ||
1538 | case KVM_PV_REASON_PAGE_NOT_PRESENT: | ||
1539 | svm->apf_reason = 0; | ||
1540 | local_irq_disable(); | ||
1541 | kvm_async_pf_task_wait(fault_address); | ||
1542 | local_irq_enable(); | ||
1543 | break; | ||
1544 | case KVM_PV_REASON_PAGE_READY: | ||
1545 | svm->apf_reason = 0; | ||
1546 | local_irq_disable(); | ||
1547 | kvm_async_pf_task_wake(fault_address); | ||
1548 | local_irq_enable(); | ||
1549 | break; | ||
1550 | } | ||
1551 | return r; | ||
1396 | } | 1552 | } |
1397 | 1553 | ||
1398 | static int db_interception(struct vcpu_svm *svm) | 1554 | static int db_interception(struct vcpu_svm *svm) |
@@ -1440,7 +1596,7 @@ static int ud_interception(struct vcpu_svm *svm) | |||
1440 | { | 1596 | { |
1441 | int er; | 1597 | int er; |
1442 | 1598 | ||
1443 | er = emulate_instruction(&svm->vcpu, 0, 0, EMULTYPE_TRAP_UD); | 1599 | er = emulate_instruction(&svm->vcpu, EMULTYPE_TRAP_UD); |
1444 | if (er != EMULATE_DONE) | 1600 | if (er != EMULATE_DONE) |
1445 | kvm_queue_exception(&svm->vcpu, UD_VECTOR); | 1601 | kvm_queue_exception(&svm->vcpu, UD_VECTOR); |
1446 | return 1; | 1602 | return 1; |
@@ -1449,21 +1605,8 @@ static int ud_interception(struct vcpu_svm *svm) | |||
1449 | static void svm_fpu_activate(struct kvm_vcpu *vcpu) | 1605 | static void svm_fpu_activate(struct kvm_vcpu *vcpu) |
1450 | { | 1606 | { |
1451 | struct vcpu_svm *svm = to_svm(vcpu); | 1607 | struct vcpu_svm *svm = to_svm(vcpu); |
1452 | u32 excp; | ||
1453 | |||
1454 | if (is_nested(svm)) { | ||
1455 | u32 h_excp, n_excp; | ||
1456 | |||
1457 | h_excp = svm->nested.hsave->control.intercept_exceptions; | ||
1458 | n_excp = svm->nested.intercept_exceptions; | ||
1459 | h_excp &= ~(1 << NM_VECTOR); | ||
1460 | excp = h_excp | n_excp; | ||
1461 | } else { | ||
1462 | excp = svm->vmcb->control.intercept_exceptions; | ||
1463 | excp &= ~(1 << NM_VECTOR); | ||
1464 | } | ||
1465 | 1608 | ||
1466 | svm->vmcb->control.intercept_exceptions = excp; | 1609 | clr_exception_intercept(svm, NM_VECTOR); |
1467 | 1610 | ||
1468 | svm->vcpu.fpu_active = 1; | 1611 | svm->vcpu.fpu_active = 1; |
1469 | update_cr0_intercept(svm); | 1612 | update_cr0_intercept(svm); |
@@ -1570,7 +1713,7 @@ static int io_interception(struct vcpu_svm *svm) | |||
1570 | string = (io_info & SVM_IOIO_STR_MASK) != 0; | 1713 | string = (io_info & SVM_IOIO_STR_MASK) != 0; |
1571 | in = (io_info & SVM_IOIO_TYPE_MASK) != 0; | 1714 | in = (io_info & SVM_IOIO_TYPE_MASK) != 0; |
1572 | if (string || in) | 1715 | if (string || in) |
1573 | return emulate_instruction(vcpu, 0, 0, 0) == EMULATE_DONE; | 1716 | return emulate_instruction(vcpu, 0) == EMULATE_DONE; |
1574 | 1717 | ||
1575 | port = io_info >> 16; | 1718 | port = io_info >> 16; |
1576 | size = (io_info & SVM_IOIO_SIZE_MASK) >> SVM_IOIO_SIZE_SHIFT; | 1719 | size = (io_info & SVM_IOIO_SIZE_MASK) >> SVM_IOIO_SIZE_SHIFT; |
@@ -1624,17 +1767,19 @@ static void nested_svm_set_tdp_cr3(struct kvm_vcpu *vcpu, | |||
1624 | struct vcpu_svm *svm = to_svm(vcpu); | 1767 | struct vcpu_svm *svm = to_svm(vcpu); |
1625 | 1768 | ||
1626 | svm->vmcb->control.nested_cr3 = root; | 1769 | svm->vmcb->control.nested_cr3 = root; |
1627 | force_new_asid(vcpu); | 1770 | mark_dirty(svm->vmcb, VMCB_NPT); |
1771 | svm_flush_tlb(vcpu); | ||
1628 | } | 1772 | } |
1629 | 1773 | ||
1630 | static void nested_svm_inject_npf_exit(struct kvm_vcpu *vcpu) | 1774 | static void nested_svm_inject_npf_exit(struct kvm_vcpu *vcpu, |
1775 | struct x86_exception *fault) | ||
1631 | { | 1776 | { |
1632 | struct vcpu_svm *svm = to_svm(vcpu); | 1777 | struct vcpu_svm *svm = to_svm(vcpu); |
1633 | 1778 | ||
1634 | svm->vmcb->control.exit_code = SVM_EXIT_NPF; | 1779 | svm->vmcb->control.exit_code = SVM_EXIT_NPF; |
1635 | svm->vmcb->control.exit_code_hi = 0; | 1780 | svm->vmcb->control.exit_code_hi = 0; |
1636 | svm->vmcb->control.exit_info_1 = vcpu->arch.fault.error_code; | 1781 | svm->vmcb->control.exit_info_1 = fault->error_code; |
1637 | svm->vmcb->control.exit_info_2 = vcpu->arch.fault.address; | 1782 | svm->vmcb->control.exit_info_2 = fault->address; |
1638 | 1783 | ||
1639 | nested_svm_vmexit(svm); | 1784 | nested_svm_vmexit(svm); |
1640 | } | 1785 | } |
@@ -1680,7 +1825,7 @@ static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr, | |||
1680 | { | 1825 | { |
1681 | int vmexit; | 1826 | int vmexit; |
1682 | 1827 | ||
1683 | if (!is_nested(svm)) | 1828 | if (!is_guest_mode(&svm->vcpu)) |
1684 | return 0; | 1829 | return 0; |
1685 | 1830 | ||
1686 | svm->vmcb->control.exit_code = SVM_EXIT_EXCP_BASE + nr; | 1831 | svm->vmcb->control.exit_code = SVM_EXIT_EXCP_BASE + nr; |
@@ -1698,7 +1843,7 @@ static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr, | |||
1698 | /* This function returns true if it is save to enable the irq window */ | 1843 | /* This function returns true if it is save to enable the irq window */ |
1699 | static inline bool nested_svm_intr(struct vcpu_svm *svm) | 1844 | static inline bool nested_svm_intr(struct vcpu_svm *svm) |
1700 | { | 1845 | { |
1701 | if (!is_nested(svm)) | 1846 | if (!is_guest_mode(&svm->vcpu)) |
1702 | return true; | 1847 | return true; |
1703 | 1848 | ||
1704 | if (!(svm->vcpu.arch.hflags & HF_VINTR_MASK)) | 1849 | if (!(svm->vcpu.arch.hflags & HF_VINTR_MASK)) |
@@ -1737,7 +1882,7 @@ static inline bool nested_svm_intr(struct vcpu_svm *svm) | |||
1737 | /* This function returns true if it is save to enable the nmi window */ | 1882 | /* This function returns true if it is save to enable the nmi window */ |
1738 | static inline bool nested_svm_nmi(struct vcpu_svm *svm) | 1883 | static inline bool nested_svm_nmi(struct vcpu_svm *svm) |
1739 | { | 1884 | { |
1740 | if (!is_nested(svm)) | 1885 | if (!is_guest_mode(&svm->vcpu)) |
1741 | return true; | 1886 | return true; |
1742 | 1887 | ||
1743 | if (!(svm->nested.intercept & (1ULL << INTERCEPT_NMI))) | 1888 | if (!(svm->nested.intercept & (1ULL << INTERCEPT_NMI))) |
@@ -1836,8 +1981,8 @@ static int nested_svm_exit_special(struct vcpu_svm *svm) | |||
1836 | return NESTED_EXIT_HOST; | 1981 | return NESTED_EXIT_HOST; |
1837 | break; | 1982 | break; |
1838 | case SVM_EXIT_EXCP_BASE + PF_VECTOR: | 1983 | case SVM_EXIT_EXCP_BASE + PF_VECTOR: |
1839 | /* When we're shadowing, trap PFs */ | 1984 | /* When we're shadowing, trap PFs, but not async PF */ |
1840 | if (!npt_enabled) | 1985 | if (!npt_enabled && svm->apf_reason == 0) |
1841 | return NESTED_EXIT_HOST; | 1986 | return NESTED_EXIT_HOST; |
1842 | break; | 1987 | break; |
1843 | case SVM_EXIT_EXCP_BASE + NM_VECTOR: | 1988 | case SVM_EXIT_EXCP_BASE + NM_VECTOR: |
@@ -1865,27 +2010,15 @@ static int nested_svm_intercept(struct vcpu_svm *svm) | |||
1865 | case SVM_EXIT_IOIO: | 2010 | case SVM_EXIT_IOIO: |
1866 | vmexit = nested_svm_intercept_ioio(svm); | 2011 | vmexit = nested_svm_intercept_ioio(svm); |
1867 | break; | 2012 | break; |
1868 | case SVM_EXIT_READ_CR0 ... SVM_EXIT_READ_CR8: { | 2013 | case SVM_EXIT_READ_CR0 ... SVM_EXIT_WRITE_CR8: { |
1869 | u32 cr_bits = 1 << (exit_code - SVM_EXIT_READ_CR0); | 2014 | u32 bit = 1U << (exit_code - SVM_EXIT_READ_CR0); |
1870 | if (svm->nested.intercept_cr_read & cr_bits) | 2015 | if (svm->nested.intercept_cr & bit) |
1871 | vmexit = NESTED_EXIT_DONE; | 2016 | vmexit = NESTED_EXIT_DONE; |
1872 | break; | 2017 | break; |
1873 | } | 2018 | } |
1874 | case SVM_EXIT_WRITE_CR0 ... SVM_EXIT_WRITE_CR8: { | 2019 | case SVM_EXIT_READ_DR0 ... SVM_EXIT_WRITE_DR7: { |
1875 | u32 cr_bits = 1 << (exit_code - SVM_EXIT_WRITE_CR0); | 2020 | u32 bit = 1U << (exit_code - SVM_EXIT_READ_DR0); |
1876 | if (svm->nested.intercept_cr_write & cr_bits) | 2021 | if (svm->nested.intercept_dr & bit) |
1877 | vmexit = NESTED_EXIT_DONE; | ||
1878 | break; | ||
1879 | } | ||
1880 | case SVM_EXIT_READ_DR0 ... SVM_EXIT_READ_DR7: { | ||
1881 | u32 dr_bits = 1 << (exit_code - SVM_EXIT_READ_DR0); | ||
1882 | if (svm->nested.intercept_dr_read & dr_bits) | ||
1883 | vmexit = NESTED_EXIT_DONE; | ||
1884 | break; | ||
1885 | } | ||
1886 | case SVM_EXIT_WRITE_DR0 ... SVM_EXIT_WRITE_DR7: { | ||
1887 | u32 dr_bits = 1 << (exit_code - SVM_EXIT_WRITE_DR0); | ||
1888 | if (svm->nested.intercept_dr_write & dr_bits) | ||
1889 | vmexit = NESTED_EXIT_DONE; | 2022 | vmexit = NESTED_EXIT_DONE; |
1890 | break; | 2023 | break; |
1891 | } | 2024 | } |
@@ -1893,6 +2026,10 @@ static int nested_svm_intercept(struct vcpu_svm *svm) | |||
1893 | u32 excp_bits = 1 << (exit_code - SVM_EXIT_EXCP_BASE); | 2026 | u32 excp_bits = 1 << (exit_code - SVM_EXIT_EXCP_BASE); |
1894 | if (svm->nested.intercept_exceptions & excp_bits) | 2027 | if (svm->nested.intercept_exceptions & excp_bits) |
1895 | vmexit = NESTED_EXIT_DONE; | 2028 | vmexit = NESTED_EXIT_DONE; |
2029 | /* async page fault always cause vmexit */ | ||
2030 | else if ((exit_code == SVM_EXIT_EXCP_BASE + PF_VECTOR) && | ||
2031 | svm->apf_reason != 0) | ||
2032 | vmexit = NESTED_EXIT_DONE; | ||
1896 | break; | 2033 | break; |
1897 | } | 2034 | } |
1898 | case SVM_EXIT_ERR: { | 2035 | case SVM_EXIT_ERR: { |
@@ -1926,10 +2063,8 @@ static inline void copy_vmcb_control_area(struct vmcb *dst_vmcb, struct vmcb *fr | |||
1926 | struct vmcb_control_area *dst = &dst_vmcb->control; | 2063 | struct vmcb_control_area *dst = &dst_vmcb->control; |
1927 | struct vmcb_control_area *from = &from_vmcb->control; | 2064 | struct vmcb_control_area *from = &from_vmcb->control; |
1928 | 2065 | ||
1929 | dst->intercept_cr_read = from->intercept_cr_read; | 2066 | dst->intercept_cr = from->intercept_cr; |
1930 | dst->intercept_cr_write = from->intercept_cr_write; | 2067 | dst->intercept_dr = from->intercept_dr; |
1931 | dst->intercept_dr_read = from->intercept_dr_read; | ||
1932 | dst->intercept_dr_write = from->intercept_dr_write; | ||
1933 | dst->intercept_exceptions = from->intercept_exceptions; | 2068 | dst->intercept_exceptions = from->intercept_exceptions; |
1934 | dst->intercept = from->intercept; | 2069 | dst->intercept = from->intercept; |
1935 | dst->iopm_base_pa = from->iopm_base_pa; | 2070 | dst->iopm_base_pa = from->iopm_base_pa; |
@@ -1970,7 +2105,8 @@ static int nested_svm_vmexit(struct vcpu_svm *svm) | |||
1970 | if (!nested_vmcb) | 2105 | if (!nested_vmcb) |
1971 | return 1; | 2106 | return 1; |
1972 | 2107 | ||
1973 | /* Exit nested SVM mode */ | 2108 | /* Exit Guest-Mode */ |
2109 | leave_guest_mode(&svm->vcpu); | ||
1974 | svm->nested.vmcb = 0; | 2110 | svm->nested.vmcb = 0; |
1975 | 2111 | ||
1976 | /* Give the current vmcb to the guest */ | 2112 | /* Give the current vmcb to the guest */ |
@@ -1984,7 +2120,7 @@ static int nested_svm_vmexit(struct vcpu_svm *svm) | |||
1984 | nested_vmcb->save.idtr = vmcb->save.idtr; | 2120 | nested_vmcb->save.idtr = vmcb->save.idtr; |
1985 | nested_vmcb->save.efer = svm->vcpu.arch.efer; | 2121 | nested_vmcb->save.efer = svm->vcpu.arch.efer; |
1986 | nested_vmcb->save.cr0 = kvm_read_cr0(&svm->vcpu); | 2122 | nested_vmcb->save.cr0 = kvm_read_cr0(&svm->vcpu); |
1987 | nested_vmcb->save.cr3 = svm->vcpu.arch.cr3; | 2123 | nested_vmcb->save.cr3 = kvm_read_cr3(&svm->vcpu); |
1988 | nested_vmcb->save.cr2 = vmcb->save.cr2; | 2124 | nested_vmcb->save.cr2 = vmcb->save.cr2; |
1989 | nested_vmcb->save.cr4 = svm->vcpu.arch.cr4; | 2125 | nested_vmcb->save.cr4 = svm->vcpu.arch.cr4; |
1990 | nested_vmcb->save.rflags = vmcb->save.rflags; | 2126 | nested_vmcb->save.rflags = vmcb->save.rflags; |
@@ -2061,6 +2197,8 @@ static int nested_svm_vmexit(struct vcpu_svm *svm) | |||
2061 | svm->vmcb->save.cpl = 0; | 2197 | svm->vmcb->save.cpl = 0; |
2062 | svm->vmcb->control.exit_int_info = 0; | 2198 | svm->vmcb->control.exit_int_info = 0; |
2063 | 2199 | ||
2200 | mark_all_dirty(svm->vmcb); | ||
2201 | |||
2064 | nested_svm_unmap(page); | 2202 | nested_svm_unmap(page); |
2065 | 2203 | ||
2066 | nested_svm_uninit_mmu_context(&svm->vcpu); | 2204 | nested_svm_uninit_mmu_context(&svm->vcpu); |
@@ -2148,8 +2286,8 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm) | |||
2148 | nested_vmcb->control.event_inj, | 2286 | nested_vmcb->control.event_inj, |
2149 | nested_vmcb->control.nested_ctl); | 2287 | nested_vmcb->control.nested_ctl); |
2150 | 2288 | ||
2151 | trace_kvm_nested_intercepts(nested_vmcb->control.intercept_cr_read, | 2289 | trace_kvm_nested_intercepts(nested_vmcb->control.intercept_cr & 0xffff, |
2152 | nested_vmcb->control.intercept_cr_write, | 2290 | nested_vmcb->control.intercept_cr >> 16, |
2153 | nested_vmcb->control.intercept_exceptions, | 2291 | nested_vmcb->control.intercept_exceptions, |
2154 | nested_vmcb->control.intercept); | 2292 | nested_vmcb->control.intercept); |
2155 | 2293 | ||
@@ -2177,7 +2315,7 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm) | |||
2177 | if (npt_enabled) | 2315 | if (npt_enabled) |
2178 | hsave->save.cr3 = vmcb->save.cr3; | 2316 | hsave->save.cr3 = vmcb->save.cr3; |
2179 | else | 2317 | else |
2180 | hsave->save.cr3 = svm->vcpu.arch.cr3; | 2318 | hsave->save.cr3 = kvm_read_cr3(&svm->vcpu); |
2181 | 2319 | ||
2182 | copy_vmcb_control_area(hsave, vmcb); | 2320 | copy_vmcb_control_area(hsave, vmcb); |
2183 | 2321 | ||
@@ -2229,14 +2367,12 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm) | |||
2229 | svm->nested.vmcb_iopm = nested_vmcb->control.iopm_base_pa & ~0x0fffULL; | 2367 | svm->nested.vmcb_iopm = nested_vmcb->control.iopm_base_pa & ~0x0fffULL; |
2230 | 2368 | ||
2231 | /* cache intercepts */ | 2369 | /* cache intercepts */ |
2232 | svm->nested.intercept_cr_read = nested_vmcb->control.intercept_cr_read; | 2370 | svm->nested.intercept_cr = nested_vmcb->control.intercept_cr; |
2233 | svm->nested.intercept_cr_write = nested_vmcb->control.intercept_cr_write; | 2371 | svm->nested.intercept_dr = nested_vmcb->control.intercept_dr; |
2234 | svm->nested.intercept_dr_read = nested_vmcb->control.intercept_dr_read; | ||
2235 | svm->nested.intercept_dr_write = nested_vmcb->control.intercept_dr_write; | ||
2236 | svm->nested.intercept_exceptions = nested_vmcb->control.intercept_exceptions; | 2372 | svm->nested.intercept_exceptions = nested_vmcb->control.intercept_exceptions; |
2237 | svm->nested.intercept = nested_vmcb->control.intercept; | 2373 | svm->nested.intercept = nested_vmcb->control.intercept; |
2238 | 2374 | ||
2239 | force_new_asid(&svm->vcpu); | 2375 | svm_flush_tlb(&svm->vcpu); |
2240 | svm->vmcb->control.int_ctl = nested_vmcb->control.int_ctl | V_INTR_MASKING_MASK; | 2376 | svm->vmcb->control.int_ctl = nested_vmcb->control.int_ctl | V_INTR_MASKING_MASK; |
2241 | if (nested_vmcb->control.int_ctl & V_INTR_MASKING_MASK) | 2377 | if (nested_vmcb->control.int_ctl & V_INTR_MASKING_MASK) |
2242 | svm->vcpu.arch.hflags |= HF_VINTR_MASK; | 2378 | svm->vcpu.arch.hflags |= HF_VINTR_MASK; |
@@ -2245,29 +2381,12 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm) | |||
2245 | 2381 | ||
2246 | if (svm->vcpu.arch.hflags & HF_VINTR_MASK) { | 2382 | if (svm->vcpu.arch.hflags & HF_VINTR_MASK) { |
2247 | /* We only want the cr8 intercept bits of the guest */ | 2383 | /* We only want the cr8 intercept bits of the guest */ |
2248 | svm->vmcb->control.intercept_cr_read &= ~INTERCEPT_CR8_MASK; | 2384 | clr_cr_intercept(svm, INTERCEPT_CR8_READ); |
2249 | svm->vmcb->control.intercept_cr_write &= ~INTERCEPT_CR8_MASK; | 2385 | clr_cr_intercept(svm, INTERCEPT_CR8_WRITE); |
2250 | } | 2386 | } |
2251 | 2387 | ||
2252 | /* We don't want to see VMMCALLs from a nested guest */ | 2388 | /* We don't want to see VMMCALLs from a nested guest */ |
2253 | svm->vmcb->control.intercept &= ~(1ULL << INTERCEPT_VMMCALL); | 2389 | clr_intercept(svm, INTERCEPT_VMMCALL); |
2254 | |||
2255 | /* | ||
2256 | * We don't want a nested guest to be more powerful than the guest, so | ||
2257 | * all intercepts are ORed | ||
2258 | */ | ||
2259 | svm->vmcb->control.intercept_cr_read |= | ||
2260 | nested_vmcb->control.intercept_cr_read; | ||
2261 | svm->vmcb->control.intercept_cr_write |= | ||
2262 | nested_vmcb->control.intercept_cr_write; | ||
2263 | svm->vmcb->control.intercept_dr_read |= | ||
2264 | nested_vmcb->control.intercept_dr_read; | ||
2265 | svm->vmcb->control.intercept_dr_write |= | ||
2266 | nested_vmcb->control.intercept_dr_write; | ||
2267 | svm->vmcb->control.intercept_exceptions |= | ||
2268 | nested_vmcb->control.intercept_exceptions; | ||
2269 | |||
2270 | svm->vmcb->control.intercept |= nested_vmcb->control.intercept; | ||
2271 | 2390 | ||
2272 | svm->vmcb->control.lbr_ctl = nested_vmcb->control.lbr_ctl; | 2391 | svm->vmcb->control.lbr_ctl = nested_vmcb->control.lbr_ctl; |
2273 | svm->vmcb->control.int_vector = nested_vmcb->control.int_vector; | 2392 | svm->vmcb->control.int_vector = nested_vmcb->control.int_vector; |
@@ -2278,11 +2397,21 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm) | |||
2278 | 2397 | ||
2279 | nested_svm_unmap(page); | 2398 | nested_svm_unmap(page); |
2280 | 2399 | ||
2281 | /* nested_vmcb is our indicator if nested SVM is activated */ | 2400 | /* Enter Guest-Mode */ |
2401 | enter_guest_mode(&svm->vcpu); | ||
2402 | |||
2403 | /* | ||
2404 | * Merge guest and host intercepts - must be called with vcpu in | ||
2405 | * guest-mode to take affect here | ||
2406 | */ | ||
2407 | recalc_intercepts(svm); | ||
2408 | |||
2282 | svm->nested.vmcb = vmcb_gpa; | 2409 | svm->nested.vmcb = vmcb_gpa; |
2283 | 2410 | ||
2284 | enable_gif(svm); | 2411 | enable_gif(svm); |
2285 | 2412 | ||
2413 | mark_all_dirty(svm->vmcb); | ||
2414 | |||
2286 | return true; | 2415 | return true; |
2287 | } | 2416 | } |
2288 | 2417 | ||
@@ -2400,6 +2529,8 @@ static int clgi_interception(struct vcpu_svm *svm) | |||
2400 | svm_clear_vintr(svm); | 2529 | svm_clear_vintr(svm); |
2401 | svm->vmcb->control.int_ctl &= ~V_IRQ_MASK; | 2530 | svm->vmcb->control.int_ctl &= ~V_IRQ_MASK; |
2402 | 2531 | ||
2532 | mark_dirty(svm->vmcb, VMCB_INTR); | ||
2533 | |||
2403 | return 1; | 2534 | return 1; |
2404 | } | 2535 | } |
2405 | 2536 | ||
@@ -2426,6 +2557,19 @@ static int skinit_interception(struct vcpu_svm *svm) | |||
2426 | return 1; | 2557 | return 1; |
2427 | } | 2558 | } |
2428 | 2559 | ||
2560 | static int xsetbv_interception(struct vcpu_svm *svm) | ||
2561 | { | ||
2562 | u64 new_bv = kvm_read_edx_eax(&svm->vcpu); | ||
2563 | u32 index = kvm_register_read(&svm->vcpu, VCPU_REGS_RCX); | ||
2564 | |||
2565 | if (kvm_set_xcr(&svm->vcpu, index, new_bv) == 0) { | ||
2566 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; | ||
2567 | skip_emulated_instruction(&svm->vcpu); | ||
2568 | } | ||
2569 | |||
2570 | return 1; | ||
2571 | } | ||
2572 | |||
2429 | static int invalid_op_interception(struct vcpu_svm *svm) | 2573 | static int invalid_op_interception(struct vcpu_svm *svm) |
2430 | { | 2574 | { |
2431 | kvm_queue_exception(&svm->vcpu, UD_VECTOR); | 2575 | kvm_queue_exception(&svm->vcpu, UD_VECTOR); |
@@ -2507,19 +2651,92 @@ static int cpuid_interception(struct vcpu_svm *svm) | |||
2507 | static int iret_interception(struct vcpu_svm *svm) | 2651 | static int iret_interception(struct vcpu_svm *svm) |
2508 | { | 2652 | { |
2509 | ++svm->vcpu.stat.nmi_window_exits; | 2653 | ++svm->vcpu.stat.nmi_window_exits; |
2510 | svm->vmcb->control.intercept &= ~(1ULL << INTERCEPT_IRET); | 2654 | clr_intercept(svm, INTERCEPT_IRET); |
2511 | svm->vcpu.arch.hflags |= HF_IRET_MASK; | 2655 | svm->vcpu.arch.hflags |= HF_IRET_MASK; |
2512 | return 1; | 2656 | return 1; |
2513 | } | 2657 | } |
2514 | 2658 | ||
2515 | static int invlpg_interception(struct vcpu_svm *svm) | 2659 | static int invlpg_interception(struct vcpu_svm *svm) |
2516 | { | 2660 | { |
2517 | return emulate_instruction(&svm->vcpu, 0, 0, 0) == EMULATE_DONE; | 2661 | if (!static_cpu_has(X86_FEATURE_DECODEASSISTS)) |
2662 | return emulate_instruction(&svm->vcpu, 0) == EMULATE_DONE; | ||
2663 | |||
2664 | kvm_mmu_invlpg(&svm->vcpu, svm->vmcb->control.exit_info_1); | ||
2665 | skip_emulated_instruction(&svm->vcpu); | ||
2666 | return 1; | ||
2518 | } | 2667 | } |
2519 | 2668 | ||
2520 | static int emulate_on_interception(struct vcpu_svm *svm) | 2669 | static int emulate_on_interception(struct vcpu_svm *svm) |
2521 | { | 2670 | { |
2522 | return emulate_instruction(&svm->vcpu, 0, 0, 0) == EMULATE_DONE; | 2671 | return emulate_instruction(&svm->vcpu, 0) == EMULATE_DONE; |
2672 | } | ||
2673 | |||
2674 | #define CR_VALID (1ULL << 63) | ||
2675 | |||
2676 | static int cr_interception(struct vcpu_svm *svm) | ||
2677 | { | ||
2678 | int reg, cr; | ||
2679 | unsigned long val; | ||
2680 | int err; | ||
2681 | |||
2682 | if (!static_cpu_has(X86_FEATURE_DECODEASSISTS)) | ||
2683 | return emulate_on_interception(svm); | ||
2684 | |||
2685 | if (unlikely((svm->vmcb->control.exit_info_1 & CR_VALID) == 0)) | ||
2686 | return emulate_on_interception(svm); | ||
2687 | |||
2688 | reg = svm->vmcb->control.exit_info_1 & SVM_EXITINFO_REG_MASK; | ||
2689 | cr = svm->vmcb->control.exit_code - SVM_EXIT_READ_CR0; | ||
2690 | |||
2691 | err = 0; | ||
2692 | if (cr >= 16) { /* mov to cr */ | ||
2693 | cr -= 16; | ||
2694 | val = kvm_register_read(&svm->vcpu, reg); | ||
2695 | switch (cr) { | ||
2696 | case 0: | ||
2697 | err = kvm_set_cr0(&svm->vcpu, val); | ||
2698 | break; | ||
2699 | case 3: | ||
2700 | err = kvm_set_cr3(&svm->vcpu, val); | ||
2701 | break; | ||
2702 | case 4: | ||
2703 | err = kvm_set_cr4(&svm->vcpu, val); | ||
2704 | break; | ||
2705 | case 8: | ||
2706 | err = kvm_set_cr8(&svm->vcpu, val); | ||
2707 | break; | ||
2708 | default: | ||
2709 | WARN(1, "unhandled write to CR%d", cr); | ||
2710 | kvm_queue_exception(&svm->vcpu, UD_VECTOR); | ||
2711 | return 1; | ||
2712 | } | ||
2713 | } else { /* mov from cr */ | ||
2714 | switch (cr) { | ||
2715 | case 0: | ||
2716 | val = kvm_read_cr0(&svm->vcpu); | ||
2717 | break; | ||
2718 | case 2: | ||
2719 | val = svm->vcpu.arch.cr2; | ||
2720 | break; | ||
2721 | case 3: | ||
2722 | val = kvm_read_cr3(&svm->vcpu); | ||
2723 | break; | ||
2724 | case 4: | ||
2725 | val = kvm_read_cr4(&svm->vcpu); | ||
2726 | break; | ||
2727 | case 8: | ||
2728 | val = kvm_get_cr8(&svm->vcpu); | ||
2729 | break; | ||
2730 | default: | ||
2731 | WARN(1, "unhandled read from CR%d", cr); | ||
2732 | kvm_queue_exception(&svm->vcpu, UD_VECTOR); | ||
2733 | return 1; | ||
2734 | } | ||
2735 | kvm_register_write(&svm->vcpu, reg, val); | ||
2736 | } | ||
2737 | kvm_complete_insn_gp(&svm->vcpu, err); | ||
2738 | |||
2739 | return 1; | ||
2523 | } | 2740 | } |
2524 | 2741 | ||
2525 | static int cr0_write_interception(struct vcpu_svm *svm) | 2742 | static int cr0_write_interception(struct vcpu_svm *svm) |
@@ -2527,7 +2744,7 @@ static int cr0_write_interception(struct vcpu_svm *svm) | |||
2527 | struct kvm_vcpu *vcpu = &svm->vcpu; | 2744 | struct kvm_vcpu *vcpu = &svm->vcpu; |
2528 | int r; | 2745 | int r; |
2529 | 2746 | ||
2530 | r = emulate_instruction(&svm->vcpu, 0, 0, 0); | 2747 | r = cr_interception(svm); |
2531 | 2748 | ||
2532 | if (svm->nested.vmexit_rip) { | 2749 | if (svm->nested.vmexit_rip) { |
2533 | kvm_register_write(vcpu, VCPU_REGS_RIP, svm->nested.vmexit_rip); | 2750 | kvm_register_write(vcpu, VCPU_REGS_RIP, svm->nested.vmexit_rip); |
@@ -2536,22 +2753,47 @@ static int cr0_write_interception(struct vcpu_svm *svm) | |||
2536 | svm->nested.vmexit_rip = 0; | 2753 | svm->nested.vmexit_rip = 0; |
2537 | } | 2754 | } |
2538 | 2755 | ||
2539 | return r == EMULATE_DONE; | 2756 | return r; |
2757 | } | ||
2758 | |||
2759 | static int dr_interception(struct vcpu_svm *svm) | ||
2760 | { | ||
2761 | int reg, dr; | ||
2762 | unsigned long val; | ||
2763 | int err; | ||
2764 | |||
2765 | if (!boot_cpu_has(X86_FEATURE_DECODEASSISTS)) | ||
2766 | return emulate_on_interception(svm); | ||
2767 | |||
2768 | reg = svm->vmcb->control.exit_info_1 & SVM_EXITINFO_REG_MASK; | ||
2769 | dr = svm->vmcb->control.exit_code - SVM_EXIT_READ_DR0; | ||
2770 | |||
2771 | if (dr >= 16) { /* mov to DRn */ | ||
2772 | val = kvm_register_read(&svm->vcpu, reg); | ||
2773 | kvm_set_dr(&svm->vcpu, dr - 16, val); | ||
2774 | } else { | ||
2775 | err = kvm_get_dr(&svm->vcpu, dr, &val); | ||
2776 | if (!err) | ||
2777 | kvm_register_write(&svm->vcpu, reg, val); | ||
2778 | } | ||
2779 | |||
2780 | return 1; | ||
2540 | } | 2781 | } |
2541 | 2782 | ||
2542 | static int cr8_write_interception(struct vcpu_svm *svm) | 2783 | static int cr8_write_interception(struct vcpu_svm *svm) |
2543 | { | 2784 | { |
2544 | struct kvm_run *kvm_run = svm->vcpu.run; | 2785 | struct kvm_run *kvm_run = svm->vcpu.run; |
2786 | int r; | ||
2545 | 2787 | ||
2546 | u8 cr8_prev = kvm_get_cr8(&svm->vcpu); | 2788 | u8 cr8_prev = kvm_get_cr8(&svm->vcpu); |
2547 | /* instruction emulation calls kvm_set_cr8() */ | 2789 | /* instruction emulation calls kvm_set_cr8() */ |
2548 | emulate_instruction(&svm->vcpu, 0, 0, 0); | 2790 | r = cr_interception(svm); |
2549 | if (irqchip_in_kernel(svm->vcpu.kvm)) { | 2791 | if (irqchip_in_kernel(svm->vcpu.kvm)) { |
2550 | svm->vmcb->control.intercept_cr_write &= ~INTERCEPT_CR8_MASK; | 2792 | clr_cr_intercept(svm, INTERCEPT_CR8_WRITE); |
2551 | return 1; | 2793 | return r; |
2552 | } | 2794 | } |
2553 | if (cr8_prev <= kvm_get_cr8(&svm->vcpu)) | 2795 | if (cr8_prev <= kvm_get_cr8(&svm->vcpu)) |
2554 | return 1; | 2796 | return r; |
2555 | kvm_run->exit_reason = KVM_EXIT_SET_TPR; | 2797 | kvm_run->exit_reason = KVM_EXIT_SET_TPR; |
2556 | return 0; | 2798 | return 0; |
2557 | } | 2799 | } |
@@ -2562,14 +2804,9 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data) | |||
2562 | 2804 | ||
2563 | switch (ecx) { | 2805 | switch (ecx) { |
2564 | case MSR_IA32_TSC: { | 2806 | case MSR_IA32_TSC: { |
2565 | u64 tsc_offset; | 2807 | struct vmcb *vmcb = get_host_vmcb(svm); |
2566 | 2808 | ||
2567 | if (is_nested(svm)) | 2809 | *data = vmcb->control.tsc_offset + native_read_tsc(); |
2568 | tsc_offset = svm->nested.hsave->control.tsc_offset; | ||
2569 | else | ||
2570 | tsc_offset = svm->vmcb->control.tsc_offset; | ||
2571 | |||
2572 | *data = tsc_offset + native_read_tsc(); | ||
2573 | break; | 2810 | break; |
2574 | } | 2811 | } |
2575 | case MSR_STAR: | 2812 | case MSR_STAR: |
@@ -2714,7 +2951,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data) | |||
2714 | svm->vmcb->save.sysenter_esp = data; | 2951 | svm->vmcb->save.sysenter_esp = data; |
2715 | break; | 2952 | break; |
2716 | case MSR_IA32_DEBUGCTLMSR: | 2953 | case MSR_IA32_DEBUGCTLMSR: |
2717 | if (!svm_has(SVM_FEATURE_LBRV)) { | 2954 | if (!boot_cpu_has(X86_FEATURE_LBRV)) { |
2718 | pr_unimpl(vcpu, "%s: MSR_IA32_DEBUGCTL 0x%llx, nop\n", | 2955 | pr_unimpl(vcpu, "%s: MSR_IA32_DEBUGCTL 0x%llx, nop\n", |
2719 | __func__, data); | 2956 | __func__, data); |
2720 | break; | 2957 | break; |
@@ -2723,6 +2960,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data) | |||
2723 | return 1; | 2960 | return 1; |
2724 | 2961 | ||
2725 | svm->vmcb->save.dbgctl = data; | 2962 | svm->vmcb->save.dbgctl = data; |
2963 | mark_dirty(svm->vmcb, VMCB_LBR); | ||
2726 | if (data & (1ULL<<0)) | 2964 | if (data & (1ULL<<0)) |
2727 | svm_enable_lbrv(svm); | 2965 | svm_enable_lbrv(svm); |
2728 | else | 2966 | else |
@@ -2775,6 +3013,7 @@ static int interrupt_window_interception(struct vcpu_svm *svm) | |||
2775 | kvm_make_request(KVM_REQ_EVENT, &svm->vcpu); | 3013 | kvm_make_request(KVM_REQ_EVENT, &svm->vcpu); |
2776 | svm_clear_vintr(svm); | 3014 | svm_clear_vintr(svm); |
2777 | svm->vmcb->control.int_ctl &= ~V_IRQ_MASK; | 3015 | svm->vmcb->control.int_ctl &= ~V_IRQ_MASK; |
3016 | mark_dirty(svm->vmcb, VMCB_INTR); | ||
2778 | /* | 3017 | /* |
2779 | * If the user space waits to inject interrupts, exit as soon as | 3018 | * If the user space waits to inject interrupts, exit as soon as |
2780 | * possible | 3019 | * possible |
@@ -2797,31 +3036,31 @@ static int pause_interception(struct vcpu_svm *svm) | |||
2797 | } | 3036 | } |
2798 | 3037 | ||
2799 | static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = { | 3038 | static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = { |
2800 | [SVM_EXIT_READ_CR0] = emulate_on_interception, | 3039 | [SVM_EXIT_READ_CR0] = cr_interception, |
2801 | [SVM_EXIT_READ_CR3] = emulate_on_interception, | 3040 | [SVM_EXIT_READ_CR3] = cr_interception, |
2802 | [SVM_EXIT_READ_CR4] = emulate_on_interception, | 3041 | [SVM_EXIT_READ_CR4] = cr_interception, |
2803 | [SVM_EXIT_READ_CR8] = emulate_on_interception, | 3042 | [SVM_EXIT_READ_CR8] = cr_interception, |
2804 | [SVM_EXIT_CR0_SEL_WRITE] = emulate_on_interception, | 3043 | [SVM_EXIT_CR0_SEL_WRITE] = emulate_on_interception, |
2805 | [SVM_EXIT_WRITE_CR0] = cr0_write_interception, | 3044 | [SVM_EXIT_WRITE_CR0] = cr0_write_interception, |
2806 | [SVM_EXIT_WRITE_CR3] = emulate_on_interception, | 3045 | [SVM_EXIT_WRITE_CR3] = cr_interception, |
2807 | [SVM_EXIT_WRITE_CR4] = emulate_on_interception, | 3046 | [SVM_EXIT_WRITE_CR4] = cr_interception, |
2808 | [SVM_EXIT_WRITE_CR8] = cr8_write_interception, | 3047 | [SVM_EXIT_WRITE_CR8] = cr8_write_interception, |
2809 | [SVM_EXIT_READ_DR0] = emulate_on_interception, | 3048 | [SVM_EXIT_READ_DR0] = dr_interception, |
2810 | [SVM_EXIT_READ_DR1] = emulate_on_interception, | 3049 | [SVM_EXIT_READ_DR1] = dr_interception, |
2811 | [SVM_EXIT_READ_DR2] = emulate_on_interception, | 3050 | [SVM_EXIT_READ_DR2] = dr_interception, |
2812 | [SVM_EXIT_READ_DR3] = emulate_on_interception, | 3051 | [SVM_EXIT_READ_DR3] = dr_interception, |
2813 | [SVM_EXIT_READ_DR4] = emulate_on_interception, | 3052 | [SVM_EXIT_READ_DR4] = dr_interception, |
2814 | [SVM_EXIT_READ_DR5] = emulate_on_interception, | 3053 | [SVM_EXIT_READ_DR5] = dr_interception, |
2815 | [SVM_EXIT_READ_DR6] = emulate_on_interception, | 3054 | [SVM_EXIT_READ_DR6] = dr_interception, |
2816 | [SVM_EXIT_READ_DR7] = emulate_on_interception, | 3055 | [SVM_EXIT_READ_DR7] = dr_interception, |
2817 | [SVM_EXIT_WRITE_DR0] = emulate_on_interception, | 3056 | [SVM_EXIT_WRITE_DR0] = dr_interception, |
2818 | [SVM_EXIT_WRITE_DR1] = emulate_on_interception, | 3057 | [SVM_EXIT_WRITE_DR1] = dr_interception, |
2819 | [SVM_EXIT_WRITE_DR2] = emulate_on_interception, | 3058 | [SVM_EXIT_WRITE_DR2] = dr_interception, |
2820 | [SVM_EXIT_WRITE_DR3] = emulate_on_interception, | 3059 | [SVM_EXIT_WRITE_DR3] = dr_interception, |
2821 | [SVM_EXIT_WRITE_DR4] = emulate_on_interception, | 3060 | [SVM_EXIT_WRITE_DR4] = dr_interception, |
2822 | [SVM_EXIT_WRITE_DR5] = emulate_on_interception, | 3061 | [SVM_EXIT_WRITE_DR5] = dr_interception, |
2823 | [SVM_EXIT_WRITE_DR6] = emulate_on_interception, | 3062 | [SVM_EXIT_WRITE_DR6] = dr_interception, |
2824 | [SVM_EXIT_WRITE_DR7] = emulate_on_interception, | 3063 | [SVM_EXIT_WRITE_DR7] = dr_interception, |
2825 | [SVM_EXIT_EXCP_BASE + DB_VECTOR] = db_interception, | 3064 | [SVM_EXIT_EXCP_BASE + DB_VECTOR] = db_interception, |
2826 | [SVM_EXIT_EXCP_BASE + BP_VECTOR] = bp_interception, | 3065 | [SVM_EXIT_EXCP_BASE + BP_VECTOR] = bp_interception, |
2827 | [SVM_EXIT_EXCP_BASE + UD_VECTOR] = ud_interception, | 3066 | [SVM_EXIT_EXCP_BASE + UD_VECTOR] = ud_interception, |
@@ -2854,6 +3093,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = { | |||
2854 | [SVM_EXIT_WBINVD] = emulate_on_interception, | 3093 | [SVM_EXIT_WBINVD] = emulate_on_interception, |
2855 | [SVM_EXIT_MONITOR] = invalid_op_interception, | 3094 | [SVM_EXIT_MONITOR] = invalid_op_interception, |
2856 | [SVM_EXIT_MWAIT] = invalid_op_interception, | 3095 | [SVM_EXIT_MWAIT] = invalid_op_interception, |
3096 | [SVM_EXIT_XSETBV] = xsetbv_interception, | ||
2857 | [SVM_EXIT_NPF] = pf_interception, | 3097 | [SVM_EXIT_NPF] = pf_interception, |
2858 | }; | 3098 | }; |
2859 | 3099 | ||
@@ -2864,10 +3104,10 @@ void dump_vmcb(struct kvm_vcpu *vcpu) | |||
2864 | struct vmcb_save_area *save = &svm->vmcb->save; | 3104 | struct vmcb_save_area *save = &svm->vmcb->save; |
2865 | 3105 | ||
2866 | pr_err("VMCB Control Area:\n"); | 3106 | pr_err("VMCB Control Area:\n"); |
2867 | pr_err("cr_read: %04x\n", control->intercept_cr_read); | 3107 | pr_err("cr_read: %04x\n", control->intercept_cr & 0xffff); |
2868 | pr_err("cr_write: %04x\n", control->intercept_cr_write); | 3108 | pr_err("cr_write: %04x\n", control->intercept_cr >> 16); |
2869 | pr_err("dr_read: %04x\n", control->intercept_dr_read); | 3109 | pr_err("dr_read: %04x\n", control->intercept_dr & 0xffff); |
2870 | pr_err("dr_write: %04x\n", control->intercept_dr_write); | 3110 | pr_err("dr_write: %04x\n", control->intercept_dr >> 16); |
2871 | pr_err("exceptions: %08x\n", control->intercept_exceptions); | 3111 | pr_err("exceptions: %08x\n", control->intercept_exceptions); |
2872 | pr_err("intercepts: %016llx\n", control->intercept); | 3112 | pr_err("intercepts: %016llx\n", control->intercept); |
2873 | pr_err("pause filter count: %d\n", control->pause_filter_count); | 3113 | pr_err("pause filter count: %d\n", control->pause_filter_count); |
@@ -2950,15 +3190,23 @@ void dump_vmcb(struct kvm_vcpu *vcpu) | |||
2950 | 3190 | ||
2951 | } | 3191 | } |
2952 | 3192 | ||
3193 | static void svm_get_exit_info(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2) | ||
3194 | { | ||
3195 | struct vmcb_control_area *control = &to_svm(vcpu)->vmcb->control; | ||
3196 | |||
3197 | *info1 = control->exit_info_1; | ||
3198 | *info2 = control->exit_info_2; | ||
3199 | } | ||
3200 | |||
2953 | static int handle_exit(struct kvm_vcpu *vcpu) | 3201 | static int handle_exit(struct kvm_vcpu *vcpu) |
2954 | { | 3202 | { |
2955 | struct vcpu_svm *svm = to_svm(vcpu); | 3203 | struct vcpu_svm *svm = to_svm(vcpu); |
2956 | struct kvm_run *kvm_run = vcpu->run; | 3204 | struct kvm_run *kvm_run = vcpu->run; |
2957 | u32 exit_code = svm->vmcb->control.exit_code; | 3205 | u32 exit_code = svm->vmcb->control.exit_code; |
2958 | 3206 | ||
2959 | trace_kvm_exit(exit_code, vcpu); | 3207 | trace_kvm_exit(exit_code, vcpu, KVM_ISA_SVM); |
2960 | 3208 | ||
2961 | if (!(svm->vmcb->control.intercept_cr_write & INTERCEPT_CR0_MASK)) | 3209 | if (!is_cr_intercept(svm, INTERCEPT_CR0_WRITE)) |
2962 | vcpu->arch.cr0 = svm->vmcb->save.cr0; | 3210 | vcpu->arch.cr0 = svm->vmcb->save.cr0; |
2963 | if (npt_enabled) | 3211 | if (npt_enabled) |
2964 | vcpu->arch.cr3 = svm->vmcb->save.cr3; | 3212 | vcpu->arch.cr3 = svm->vmcb->save.cr3; |
@@ -2970,7 +3218,7 @@ static int handle_exit(struct kvm_vcpu *vcpu) | |||
2970 | return 1; | 3218 | return 1; |
2971 | } | 3219 | } |
2972 | 3220 | ||
2973 | if (is_nested(svm)) { | 3221 | if (is_guest_mode(vcpu)) { |
2974 | int vmexit; | 3222 | int vmexit; |
2975 | 3223 | ||
2976 | trace_kvm_nested_vmexit(svm->vmcb->save.rip, exit_code, | 3224 | trace_kvm_nested_vmexit(svm->vmcb->save.rip, exit_code, |
@@ -3033,7 +3281,6 @@ static void pre_svm_run(struct vcpu_svm *svm) | |||
3033 | 3281 | ||
3034 | struct svm_cpu_data *sd = per_cpu(svm_data, cpu); | 3282 | struct svm_cpu_data *sd = per_cpu(svm_data, cpu); |
3035 | 3283 | ||
3036 | svm->vmcb->control.tlb_ctl = TLB_CONTROL_DO_NOTHING; | ||
3037 | /* FIXME: handle wraparound of asid_generation */ | 3284 | /* FIXME: handle wraparound of asid_generation */ |
3038 | if (svm->asid_generation != sd->asid_generation) | 3285 | if (svm->asid_generation != sd->asid_generation) |
3039 | new_asid(svm, sd); | 3286 | new_asid(svm, sd); |
@@ -3045,7 +3292,7 @@ static void svm_inject_nmi(struct kvm_vcpu *vcpu) | |||
3045 | 3292 | ||
3046 | svm->vmcb->control.event_inj = SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_NMI; | 3293 | svm->vmcb->control.event_inj = SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_NMI; |
3047 | vcpu->arch.hflags |= HF_NMI_MASK; | 3294 | vcpu->arch.hflags |= HF_NMI_MASK; |
3048 | svm->vmcb->control.intercept |= (1ULL << INTERCEPT_IRET); | 3295 | set_intercept(svm, INTERCEPT_IRET); |
3049 | ++vcpu->stat.nmi_injections; | 3296 | ++vcpu->stat.nmi_injections; |
3050 | } | 3297 | } |
3051 | 3298 | ||
@@ -3058,6 +3305,7 @@ static inline void svm_inject_irq(struct vcpu_svm *svm, int irq) | |||
3058 | control->int_ctl &= ~V_INTR_PRIO_MASK; | 3305 | control->int_ctl &= ~V_INTR_PRIO_MASK; |
3059 | control->int_ctl |= V_IRQ_MASK | | 3306 | control->int_ctl |= V_IRQ_MASK | |
3060 | ((/*control->int_vector >> 4*/ 0xf) << V_INTR_PRIO_SHIFT); | 3307 | ((/*control->int_vector >> 4*/ 0xf) << V_INTR_PRIO_SHIFT); |
3308 | mark_dirty(svm->vmcb, VMCB_INTR); | ||
3061 | } | 3309 | } |
3062 | 3310 | ||
3063 | static void svm_set_irq(struct kvm_vcpu *vcpu) | 3311 | static void svm_set_irq(struct kvm_vcpu *vcpu) |
@@ -3077,14 +3325,14 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr) | |||
3077 | { | 3325 | { |
3078 | struct vcpu_svm *svm = to_svm(vcpu); | 3326 | struct vcpu_svm *svm = to_svm(vcpu); |
3079 | 3327 | ||
3080 | if (is_nested(svm) && (vcpu->arch.hflags & HF_VINTR_MASK)) | 3328 | if (is_guest_mode(vcpu) && (vcpu->arch.hflags & HF_VINTR_MASK)) |
3081 | return; | 3329 | return; |
3082 | 3330 | ||
3083 | if (irr == -1) | 3331 | if (irr == -1) |
3084 | return; | 3332 | return; |
3085 | 3333 | ||
3086 | if (tpr >= irr) | 3334 | if (tpr >= irr) |
3087 | svm->vmcb->control.intercept_cr_write |= INTERCEPT_CR8_MASK; | 3335 | set_cr_intercept(svm, INTERCEPT_CR8_WRITE); |
3088 | } | 3336 | } |
3089 | 3337 | ||
3090 | static int svm_nmi_allowed(struct kvm_vcpu *vcpu) | 3338 | static int svm_nmi_allowed(struct kvm_vcpu *vcpu) |
@@ -3112,10 +3360,10 @@ static void svm_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked) | |||
3112 | 3360 | ||
3113 | if (masked) { | 3361 | if (masked) { |
3114 | svm->vcpu.arch.hflags |= HF_NMI_MASK; | 3362 | svm->vcpu.arch.hflags |= HF_NMI_MASK; |
3115 | svm->vmcb->control.intercept |= (1ULL << INTERCEPT_IRET); | 3363 | set_intercept(svm, INTERCEPT_IRET); |
3116 | } else { | 3364 | } else { |
3117 | svm->vcpu.arch.hflags &= ~HF_NMI_MASK; | 3365 | svm->vcpu.arch.hflags &= ~HF_NMI_MASK; |
3118 | svm->vmcb->control.intercept &= ~(1ULL << INTERCEPT_IRET); | 3366 | clr_intercept(svm, INTERCEPT_IRET); |
3119 | } | 3367 | } |
3120 | } | 3368 | } |
3121 | 3369 | ||
@@ -3131,7 +3379,7 @@ static int svm_interrupt_allowed(struct kvm_vcpu *vcpu) | |||
3131 | 3379 | ||
3132 | ret = !!(vmcb->save.rflags & X86_EFLAGS_IF); | 3380 | ret = !!(vmcb->save.rflags & X86_EFLAGS_IF); |
3133 | 3381 | ||
3134 | if (is_nested(svm)) | 3382 | if (is_guest_mode(vcpu)) |
3135 | return ret && !(svm->vcpu.arch.hflags & HF_VINTR_MASK); | 3383 | return ret && !(svm->vcpu.arch.hflags & HF_VINTR_MASK); |
3136 | 3384 | ||
3137 | return ret; | 3385 | return ret; |
@@ -3177,7 +3425,12 @@ static int svm_set_tss_addr(struct kvm *kvm, unsigned int addr) | |||
3177 | 3425 | ||
3178 | static void svm_flush_tlb(struct kvm_vcpu *vcpu) | 3426 | static void svm_flush_tlb(struct kvm_vcpu *vcpu) |
3179 | { | 3427 | { |
3180 | force_new_asid(vcpu); | 3428 | struct vcpu_svm *svm = to_svm(vcpu); |
3429 | |||
3430 | if (static_cpu_has(X86_FEATURE_FLUSHBYASID)) | ||
3431 | svm->vmcb->control.tlb_ctl = TLB_CONTROL_FLUSH_ASID; | ||
3432 | else | ||
3433 | svm->asid_generation--; | ||
3181 | } | 3434 | } |
3182 | 3435 | ||
3183 | static void svm_prepare_guest_switch(struct kvm_vcpu *vcpu) | 3436 | static void svm_prepare_guest_switch(struct kvm_vcpu *vcpu) |
@@ -3188,10 +3441,10 @@ static inline void sync_cr8_to_lapic(struct kvm_vcpu *vcpu) | |||
3188 | { | 3441 | { |
3189 | struct vcpu_svm *svm = to_svm(vcpu); | 3442 | struct vcpu_svm *svm = to_svm(vcpu); |
3190 | 3443 | ||
3191 | if (is_nested(svm) && (vcpu->arch.hflags & HF_VINTR_MASK)) | 3444 | if (is_guest_mode(vcpu) && (vcpu->arch.hflags & HF_VINTR_MASK)) |
3192 | return; | 3445 | return; |
3193 | 3446 | ||
3194 | if (!(svm->vmcb->control.intercept_cr_write & INTERCEPT_CR8_MASK)) { | 3447 | if (!is_cr_intercept(svm, INTERCEPT_CR8_WRITE)) { |
3195 | int cr8 = svm->vmcb->control.int_ctl & V_TPR_MASK; | 3448 | int cr8 = svm->vmcb->control.int_ctl & V_TPR_MASK; |
3196 | kvm_set_cr8(vcpu, cr8); | 3449 | kvm_set_cr8(vcpu, cr8); |
3197 | } | 3450 | } |
@@ -3202,7 +3455,7 @@ static inline void sync_lapic_to_cr8(struct kvm_vcpu *vcpu) | |||
3202 | struct vcpu_svm *svm = to_svm(vcpu); | 3455 | struct vcpu_svm *svm = to_svm(vcpu); |
3203 | u64 cr8; | 3456 | u64 cr8; |
3204 | 3457 | ||
3205 | if (is_nested(svm) && (vcpu->arch.hflags & HF_VINTR_MASK)) | 3458 | if (is_guest_mode(vcpu) && (vcpu->arch.hflags & HF_VINTR_MASK)) |
3206 | return; | 3459 | return; |
3207 | 3460 | ||
3208 | cr8 = kvm_get_cr8(vcpu); | 3461 | cr8 = kvm_get_cr8(vcpu); |
@@ -3289,9 +3542,6 @@ static void svm_cancel_injection(struct kvm_vcpu *vcpu) | |||
3289 | static void svm_vcpu_run(struct kvm_vcpu *vcpu) | 3542 | static void svm_vcpu_run(struct kvm_vcpu *vcpu) |
3290 | { | 3543 | { |
3291 | struct vcpu_svm *svm = to_svm(vcpu); | 3544 | struct vcpu_svm *svm = to_svm(vcpu); |
3292 | u16 fs_selector; | ||
3293 | u16 gs_selector; | ||
3294 | u16 ldt_selector; | ||
3295 | 3545 | ||
3296 | svm->vmcb->save.rax = vcpu->arch.regs[VCPU_REGS_RAX]; | 3546 | svm->vmcb->save.rax = vcpu->arch.regs[VCPU_REGS_RAX]; |
3297 | svm->vmcb->save.rsp = vcpu->arch.regs[VCPU_REGS_RSP]; | 3547 | svm->vmcb->save.rsp = vcpu->arch.regs[VCPU_REGS_RSP]; |
@@ -3308,10 +3558,6 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu) | |||
3308 | 3558 | ||
3309 | sync_lapic_to_cr8(vcpu); | 3559 | sync_lapic_to_cr8(vcpu); |
3310 | 3560 | ||
3311 | save_host_msrs(vcpu); | ||
3312 | savesegment(fs, fs_selector); | ||
3313 | savesegment(gs, gs_selector); | ||
3314 | ldt_selector = kvm_read_ldt(); | ||
3315 | svm->vmcb->save.cr2 = vcpu->arch.cr2; | 3561 | svm->vmcb->save.cr2 = vcpu->arch.cr2; |
3316 | 3562 | ||
3317 | clgi(); | 3563 | clgi(); |
@@ -3389,19 +3635,10 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu) | |||
3389 | #endif | 3635 | #endif |
3390 | ); | 3636 | ); |
3391 | 3637 | ||
3392 | vcpu->arch.cr2 = svm->vmcb->save.cr2; | ||
3393 | vcpu->arch.regs[VCPU_REGS_RAX] = svm->vmcb->save.rax; | ||
3394 | vcpu->arch.regs[VCPU_REGS_RSP] = svm->vmcb->save.rsp; | ||
3395 | vcpu->arch.regs[VCPU_REGS_RIP] = svm->vmcb->save.rip; | ||
3396 | |||
3397 | load_host_msrs(vcpu); | ||
3398 | kvm_load_ldt(ldt_selector); | ||
3399 | loadsegment(fs, fs_selector); | ||
3400 | #ifdef CONFIG_X86_64 | 3638 | #ifdef CONFIG_X86_64 |
3401 | load_gs_index(gs_selector); | 3639 | wrmsrl(MSR_GS_BASE, svm->host.gs_base); |
3402 | wrmsrl(MSR_KERNEL_GS_BASE, current->thread.gs); | ||
3403 | #else | 3640 | #else |
3404 | loadsegment(gs, gs_selector); | 3641 | loadsegment(fs, svm->host.fs); |
3405 | #endif | 3642 | #endif |
3406 | 3643 | ||
3407 | reload_tss(vcpu); | 3644 | reload_tss(vcpu); |
@@ -3410,10 +3647,21 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu) | |||
3410 | 3647 | ||
3411 | stgi(); | 3648 | stgi(); |
3412 | 3649 | ||
3650 | vcpu->arch.cr2 = svm->vmcb->save.cr2; | ||
3651 | vcpu->arch.regs[VCPU_REGS_RAX] = svm->vmcb->save.rax; | ||
3652 | vcpu->arch.regs[VCPU_REGS_RSP] = svm->vmcb->save.rsp; | ||
3653 | vcpu->arch.regs[VCPU_REGS_RIP] = svm->vmcb->save.rip; | ||
3654 | |||
3413 | sync_cr8_to_lapic(vcpu); | 3655 | sync_cr8_to_lapic(vcpu); |
3414 | 3656 | ||
3415 | svm->next_rip = 0; | 3657 | svm->next_rip = 0; |
3416 | 3658 | ||
3659 | svm->vmcb->control.tlb_ctl = TLB_CONTROL_DO_NOTHING; | ||
3660 | |||
3661 | /* if exit due to PF check for async PF */ | ||
3662 | if (svm->vmcb->control.exit_code == SVM_EXIT_EXCP_BASE + PF_VECTOR) | ||
3663 | svm->apf_reason = kvm_read_and_reset_pf_reason(); | ||
3664 | |||
3417 | if (npt_enabled) { | 3665 | if (npt_enabled) { |
3418 | vcpu->arch.regs_avail &= ~(1 << VCPU_EXREG_PDPTR); | 3666 | vcpu->arch.regs_avail &= ~(1 << VCPU_EXREG_PDPTR); |
3419 | vcpu->arch.regs_dirty &= ~(1 << VCPU_EXREG_PDPTR); | 3667 | vcpu->arch.regs_dirty &= ~(1 << VCPU_EXREG_PDPTR); |
@@ -3426,6 +3674,8 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu) | |||
3426 | if (unlikely(svm->vmcb->control.exit_code == | 3674 | if (unlikely(svm->vmcb->control.exit_code == |
3427 | SVM_EXIT_EXCP_BASE + MC_VECTOR)) | 3675 | SVM_EXIT_EXCP_BASE + MC_VECTOR)) |
3428 | svm_handle_mce(svm); | 3676 | svm_handle_mce(svm); |
3677 | |||
3678 | mark_all_clean(svm->vmcb); | ||
3429 | } | 3679 | } |
3430 | 3680 | ||
3431 | #undef R | 3681 | #undef R |
@@ -3435,7 +3685,8 @@ static void svm_set_cr3(struct kvm_vcpu *vcpu, unsigned long root) | |||
3435 | struct vcpu_svm *svm = to_svm(vcpu); | 3685 | struct vcpu_svm *svm = to_svm(vcpu); |
3436 | 3686 | ||
3437 | svm->vmcb->save.cr3 = root; | 3687 | svm->vmcb->save.cr3 = root; |
3438 | force_new_asid(vcpu); | 3688 | mark_dirty(svm->vmcb, VMCB_CR); |
3689 | svm_flush_tlb(vcpu); | ||
3439 | } | 3690 | } |
3440 | 3691 | ||
3441 | static void set_tdp_cr3(struct kvm_vcpu *vcpu, unsigned long root) | 3692 | static void set_tdp_cr3(struct kvm_vcpu *vcpu, unsigned long root) |
@@ -3443,11 +3694,13 @@ static void set_tdp_cr3(struct kvm_vcpu *vcpu, unsigned long root) | |||
3443 | struct vcpu_svm *svm = to_svm(vcpu); | 3694 | struct vcpu_svm *svm = to_svm(vcpu); |
3444 | 3695 | ||
3445 | svm->vmcb->control.nested_cr3 = root; | 3696 | svm->vmcb->control.nested_cr3 = root; |
3697 | mark_dirty(svm->vmcb, VMCB_NPT); | ||
3446 | 3698 | ||
3447 | /* Also sync guest cr3 here in case we live migrate */ | 3699 | /* Also sync guest cr3 here in case we live migrate */ |
3448 | svm->vmcb->save.cr3 = vcpu->arch.cr3; | 3700 | svm->vmcb->save.cr3 = kvm_read_cr3(vcpu); |
3701 | mark_dirty(svm->vmcb, VMCB_CR); | ||
3449 | 3702 | ||
3450 | force_new_asid(vcpu); | 3703 | svm_flush_tlb(vcpu); |
3451 | } | 3704 | } |
3452 | 3705 | ||
3453 | static int is_disabled(void) | 3706 | static int is_disabled(void) |
@@ -3494,10 +3747,6 @@ static void svm_cpuid_update(struct kvm_vcpu *vcpu) | |||
3494 | static void svm_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry) | 3747 | static void svm_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry) |
3495 | { | 3748 | { |
3496 | switch (func) { | 3749 | switch (func) { |
3497 | case 0x00000001: | ||
3498 | /* Mask out xsave bit as long as it is not supported by SVM */ | ||
3499 | entry->ecx &= ~(bit(X86_FEATURE_XSAVE)); | ||
3500 | break; | ||
3501 | case 0x80000001: | 3750 | case 0x80000001: |
3502 | if (nested) | 3751 | if (nested) |
3503 | entry->ecx |= (1 << 2); /* Set SVM bit */ | 3752 | entry->ecx |= (1 << 2); /* Set SVM bit */ |
@@ -3511,7 +3760,7 @@ static void svm_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry) | |||
3511 | additional features */ | 3760 | additional features */ |
3512 | 3761 | ||
3513 | /* Support next_rip if host supports it */ | 3762 | /* Support next_rip if host supports it */ |
3514 | if (svm_has(SVM_FEATURE_NRIP)) | 3763 | if (boot_cpu_has(X86_FEATURE_NRIPS)) |
3515 | entry->edx |= SVM_FEATURE_NRIP; | 3764 | entry->edx |= SVM_FEATURE_NRIP; |
3516 | 3765 | ||
3517 | /* Support NPT for the guest if enabled */ | 3766 | /* Support NPT for the guest if enabled */ |
@@ -3571,6 +3820,7 @@ static const struct trace_print_flags svm_exit_reasons_str[] = { | |||
3571 | { SVM_EXIT_WBINVD, "wbinvd" }, | 3820 | { SVM_EXIT_WBINVD, "wbinvd" }, |
3572 | { SVM_EXIT_MONITOR, "monitor" }, | 3821 | { SVM_EXIT_MONITOR, "monitor" }, |
3573 | { SVM_EXIT_MWAIT, "mwait" }, | 3822 | { SVM_EXIT_MWAIT, "mwait" }, |
3823 | { SVM_EXIT_XSETBV, "xsetbv" }, | ||
3574 | { SVM_EXIT_NPF, "npf" }, | 3824 | { SVM_EXIT_NPF, "npf" }, |
3575 | { -1, NULL } | 3825 | { -1, NULL } |
3576 | }; | 3826 | }; |
@@ -3594,9 +3844,7 @@ static void svm_fpu_deactivate(struct kvm_vcpu *vcpu) | |||
3594 | { | 3844 | { |
3595 | struct vcpu_svm *svm = to_svm(vcpu); | 3845 | struct vcpu_svm *svm = to_svm(vcpu); |
3596 | 3846 | ||
3597 | svm->vmcb->control.intercept_exceptions |= 1 << NM_VECTOR; | 3847 | set_exception_intercept(svm, NM_VECTOR); |
3598 | if (is_nested(svm)) | ||
3599 | svm->nested.hsave->control.intercept_exceptions |= 1 << NM_VECTOR; | ||
3600 | update_cr0_intercept(svm); | 3848 | update_cr0_intercept(svm); |
3601 | } | 3849 | } |
3602 | 3850 | ||
@@ -3627,6 +3875,7 @@ static struct kvm_x86_ops svm_x86_ops = { | |||
3627 | .get_cpl = svm_get_cpl, | 3875 | .get_cpl = svm_get_cpl, |
3628 | .get_cs_db_l_bits = kvm_get_cs_db_l_bits, | 3876 | .get_cs_db_l_bits = kvm_get_cs_db_l_bits, |
3629 | .decache_cr0_guest_bits = svm_decache_cr0_guest_bits, | 3877 | .decache_cr0_guest_bits = svm_decache_cr0_guest_bits, |
3878 | .decache_cr3 = svm_decache_cr3, | ||
3630 | .decache_cr4_guest_bits = svm_decache_cr4_guest_bits, | 3879 | .decache_cr4_guest_bits = svm_decache_cr4_guest_bits, |
3631 | .set_cr0 = svm_set_cr0, | 3880 | .set_cr0 = svm_set_cr0, |
3632 | .set_cr3 = svm_set_cr3, | 3881 | .set_cr3 = svm_set_cr3, |
@@ -3667,7 +3916,9 @@ static struct kvm_x86_ops svm_x86_ops = { | |||
3667 | .get_tdp_level = get_npt_level, | 3916 | .get_tdp_level = get_npt_level, |
3668 | .get_mt_mask = svm_get_mt_mask, | 3917 | .get_mt_mask = svm_get_mt_mask, |
3669 | 3918 | ||
3919 | .get_exit_info = svm_get_exit_info, | ||
3670 | .exit_reasons_str = svm_exit_reasons_str, | 3920 | .exit_reasons_str = svm_exit_reasons_str, |
3921 | |||
3671 | .get_lpage_level = svm_get_lpage_level, | 3922 | .get_lpage_level = svm_get_lpage_level, |
3672 | 3923 | ||
3673 | .cpuid_update = svm_cpuid_update, | 3924 | .cpuid_update = svm_cpuid_update, |
diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h index a6544b8e7c0f..1357d7cf4ec8 100644 --- a/arch/x86/kvm/trace.h +++ b/arch/x86/kvm/trace.h | |||
@@ -178,27 +178,36 @@ TRACE_EVENT(kvm_apic, | |||
178 | #define trace_kvm_apic_read(reg, val) trace_kvm_apic(0, reg, val) | 178 | #define trace_kvm_apic_read(reg, val) trace_kvm_apic(0, reg, val) |
179 | #define trace_kvm_apic_write(reg, val) trace_kvm_apic(1, reg, val) | 179 | #define trace_kvm_apic_write(reg, val) trace_kvm_apic(1, reg, val) |
180 | 180 | ||
181 | #define KVM_ISA_VMX 1 | ||
182 | #define KVM_ISA_SVM 2 | ||
183 | |||
181 | /* | 184 | /* |
182 | * Tracepoint for kvm guest exit: | 185 | * Tracepoint for kvm guest exit: |
183 | */ | 186 | */ |
184 | TRACE_EVENT(kvm_exit, | 187 | TRACE_EVENT(kvm_exit, |
185 | TP_PROTO(unsigned int exit_reason, struct kvm_vcpu *vcpu), | 188 | TP_PROTO(unsigned int exit_reason, struct kvm_vcpu *vcpu, u32 isa), |
186 | TP_ARGS(exit_reason, vcpu), | 189 | TP_ARGS(exit_reason, vcpu, isa), |
187 | 190 | ||
188 | TP_STRUCT__entry( | 191 | TP_STRUCT__entry( |
189 | __field( unsigned int, exit_reason ) | 192 | __field( unsigned int, exit_reason ) |
190 | __field( unsigned long, guest_rip ) | 193 | __field( unsigned long, guest_rip ) |
194 | __field( u32, isa ) | ||
195 | __field( u64, info1 ) | ||
196 | __field( u64, info2 ) | ||
191 | ), | 197 | ), |
192 | 198 | ||
193 | TP_fast_assign( | 199 | TP_fast_assign( |
194 | __entry->exit_reason = exit_reason; | 200 | __entry->exit_reason = exit_reason; |
195 | __entry->guest_rip = kvm_rip_read(vcpu); | 201 | __entry->guest_rip = kvm_rip_read(vcpu); |
202 | __entry->isa = isa; | ||
203 | kvm_x86_ops->get_exit_info(vcpu, &__entry->info1, | ||
204 | &__entry->info2); | ||
196 | ), | 205 | ), |
197 | 206 | ||
198 | TP_printk("reason %s rip 0x%lx", | 207 | TP_printk("reason %s rip 0x%lx info %llx %llx", |
199 | ftrace_print_symbols_seq(p, __entry->exit_reason, | 208 | ftrace_print_symbols_seq(p, __entry->exit_reason, |
200 | kvm_x86_ops->exit_reasons_str), | 209 | kvm_x86_ops->exit_reasons_str), |
201 | __entry->guest_rip) | 210 | __entry->guest_rip, __entry->info1, __entry->info2) |
202 | ); | 211 | ); |
203 | 212 | ||
204 | /* | 213 | /* |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 81fcbe9515c5..bf89ec2cfb82 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -69,6 +69,9 @@ module_param(emulate_invalid_guest_state, bool, S_IRUGO); | |||
69 | static int __read_mostly vmm_exclusive = 1; | 69 | static int __read_mostly vmm_exclusive = 1; |
70 | module_param(vmm_exclusive, bool, S_IRUGO); | 70 | module_param(vmm_exclusive, bool, S_IRUGO); |
71 | 71 | ||
72 | static int __read_mostly yield_on_hlt = 1; | ||
73 | module_param(yield_on_hlt, bool, S_IRUGO); | ||
74 | |||
72 | #define KVM_GUEST_CR0_MASK_UNRESTRICTED_GUEST \ | 75 | #define KVM_GUEST_CR0_MASK_UNRESTRICTED_GUEST \ |
73 | (X86_CR0_WP | X86_CR0_NE | X86_CR0_NW | X86_CR0_CD) | 76 | (X86_CR0_WP | X86_CR0_NE | X86_CR0_NW | X86_CR0_CD) |
74 | #define KVM_GUEST_CR0_MASK \ | 77 | #define KVM_GUEST_CR0_MASK \ |
@@ -177,6 +180,7 @@ static int init_rmode(struct kvm *kvm); | |||
177 | static u64 construct_eptp(unsigned long root_hpa); | 180 | static u64 construct_eptp(unsigned long root_hpa); |
178 | static void kvm_cpu_vmxon(u64 addr); | 181 | static void kvm_cpu_vmxon(u64 addr); |
179 | static void kvm_cpu_vmxoff(void); | 182 | static void kvm_cpu_vmxoff(void); |
183 | static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3); | ||
180 | 184 | ||
181 | static DEFINE_PER_CPU(struct vmcs *, vmxarea); | 185 | static DEFINE_PER_CPU(struct vmcs *, vmxarea); |
182 | static DEFINE_PER_CPU(struct vmcs *, current_vmcs); | 186 | static DEFINE_PER_CPU(struct vmcs *, current_vmcs); |
@@ -188,6 +192,8 @@ static unsigned long *vmx_io_bitmap_b; | |||
188 | static unsigned long *vmx_msr_bitmap_legacy; | 192 | static unsigned long *vmx_msr_bitmap_legacy; |
189 | static unsigned long *vmx_msr_bitmap_longmode; | 193 | static unsigned long *vmx_msr_bitmap_longmode; |
190 | 194 | ||
195 | static bool cpu_has_load_ia32_efer; | ||
196 | |||
191 | static DECLARE_BITMAP(vmx_vpid_bitmap, VMX_NR_VPIDS); | 197 | static DECLARE_BITMAP(vmx_vpid_bitmap, VMX_NR_VPIDS); |
192 | static DEFINE_SPINLOCK(vmx_vpid_lock); | 198 | static DEFINE_SPINLOCK(vmx_vpid_lock); |
193 | 199 | ||
@@ -472,7 +478,7 @@ static void vmcs_clear(struct vmcs *vmcs) | |||
472 | u8 error; | 478 | u8 error; |
473 | 479 | ||
474 | asm volatile (__ex(ASM_VMX_VMCLEAR_RAX) "; setna %0" | 480 | asm volatile (__ex(ASM_VMX_VMCLEAR_RAX) "; setna %0" |
475 | : "=g"(error) : "a"(&phys_addr), "m"(phys_addr) | 481 | : "=qm"(error) : "a"(&phys_addr), "m"(phys_addr) |
476 | : "cc", "memory"); | 482 | : "cc", "memory"); |
477 | if (error) | 483 | if (error) |
478 | printk(KERN_ERR "kvm: vmclear fail: %p/%llx\n", | 484 | printk(KERN_ERR "kvm: vmclear fail: %p/%llx\n", |
@@ -485,7 +491,7 @@ static void vmcs_load(struct vmcs *vmcs) | |||
485 | u8 error; | 491 | u8 error; |
486 | 492 | ||
487 | asm volatile (__ex(ASM_VMX_VMPTRLD_RAX) "; setna %0" | 493 | asm volatile (__ex(ASM_VMX_VMPTRLD_RAX) "; setna %0" |
488 | : "=g"(error) : "a"(&phys_addr), "m"(phys_addr) | 494 | : "=qm"(error) : "a"(&phys_addr), "m"(phys_addr) |
489 | : "cc", "memory"); | 495 | : "cc", "memory"); |
490 | if (error) | 496 | if (error) |
491 | printk(KERN_ERR "kvm: vmptrld %p/%llx fail\n", | 497 | printk(KERN_ERR "kvm: vmptrld %p/%llx fail\n", |
@@ -565,10 +571,10 @@ static inline void ept_sync_individual_addr(u64 eptp, gpa_t gpa) | |||
565 | 571 | ||
566 | static unsigned long vmcs_readl(unsigned long field) | 572 | static unsigned long vmcs_readl(unsigned long field) |
567 | { | 573 | { |
568 | unsigned long value; | 574 | unsigned long value = 0; |
569 | 575 | ||
570 | asm volatile (__ex(ASM_VMX_VMREAD_RDX_RAX) | 576 | asm volatile (__ex(ASM_VMX_VMREAD_RDX_RAX) |
571 | : "=a"(value) : "d"(field) : "cc"); | 577 | : "+a"(value) : "d"(field) : "cc"); |
572 | return value; | 578 | return value; |
573 | } | 579 | } |
574 | 580 | ||
@@ -661,6 +667,12 @@ static void clear_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr) | |||
661 | unsigned i; | 667 | unsigned i; |
662 | struct msr_autoload *m = &vmx->msr_autoload; | 668 | struct msr_autoload *m = &vmx->msr_autoload; |
663 | 669 | ||
670 | if (msr == MSR_EFER && cpu_has_load_ia32_efer) { | ||
671 | vmcs_clear_bits(VM_ENTRY_CONTROLS, VM_ENTRY_LOAD_IA32_EFER); | ||
672 | vmcs_clear_bits(VM_EXIT_CONTROLS, VM_EXIT_LOAD_IA32_EFER); | ||
673 | return; | ||
674 | } | ||
675 | |||
664 | for (i = 0; i < m->nr; ++i) | 676 | for (i = 0; i < m->nr; ++i) |
665 | if (m->guest[i].index == msr) | 677 | if (m->guest[i].index == msr) |
666 | break; | 678 | break; |
@@ -680,6 +692,14 @@ static void add_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr, | |||
680 | unsigned i; | 692 | unsigned i; |
681 | struct msr_autoload *m = &vmx->msr_autoload; | 693 | struct msr_autoload *m = &vmx->msr_autoload; |
682 | 694 | ||
695 | if (msr == MSR_EFER && cpu_has_load_ia32_efer) { | ||
696 | vmcs_write64(GUEST_IA32_EFER, guest_val); | ||
697 | vmcs_write64(HOST_IA32_EFER, host_val); | ||
698 | vmcs_set_bits(VM_ENTRY_CONTROLS, VM_ENTRY_LOAD_IA32_EFER); | ||
699 | vmcs_set_bits(VM_EXIT_CONTROLS, VM_EXIT_LOAD_IA32_EFER); | ||
700 | return; | ||
701 | } | ||
702 | |||
683 | for (i = 0; i < m->nr; ++i) | 703 | for (i = 0; i < m->nr; ++i) |
684 | if (m->guest[i].index == msr) | 704 | if (m->guest[i].index == msr) |
685 | break; | 705 | break; |
@@ -1009,6 +1029,17 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu) | |||
1009 | vmx_set_interrupt_shadow(vcpu, 0); | 1029 | vmx_set_interrupt_shadow(vcpu, 0); |
1010 | } | 1030 | } |
1011 | 1031 | ||
1032 | static void vmx_clear_hlt(struct kvm_vcpu *vcpu) | ||
1033 | { | ||
1034 | /* Ensure that we clear the HLT state in the VMCS. We don't need to | ||
1035 | * explicitly skip the instruction because if the HLT state is set, then | ||
1036 | * the instruction is already executing and RIP has already been | ||
1037 | * advanced. */ | ||
1038 | if (!yield_on_hlt && | ||
1039 | vmcs_read32(GUEST_ACTIVITY_STATE) == GUEST_ACTIVITY_HLT) | ||
1040 | vmcs_write32(GUEST_ACTIVITY_STATE, GUEST_ACTIVITY_ACTIVE); | ||
1041 | } | ||
1042 | |||
1012 | static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, | 1043 | static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, |
1013 | bool has_error_code, u32 error_code, | 1044 | bool has_error_code, u32 error_code, |
1014 | bool reinject) | 1045 | bool reinject) |
@@ -1035,6 +1066,7 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, | |||
1035 | intr_info |= INTR_TYPE_HARD_EXCEPTION; | 1066 | intr_info |= INTR_TYPE_HARD_EXCEPTION; |
1036 | 1067 | ||
1037 | vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info); | 1068 | vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info); |
1069 | vmx_clear_hlt(vcpu); | ||
1038 | } | 1070 | } |
1039 | 1071 | ||
1040 | static bool vmx_rdtscp_supported(void) | 1072 | static bool vmx_rdtscp_supported(void) |
@@ -1305,8 +1337,11 @@ static __init int vmx_disabled_by_bios(void) | |||
1305 | && tboot_enabled()) | 1337 | && tboot_enabled()) |
1306 | return 1; | 1338 | return 1; |
1307 | if (!(msr & FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX) | 1339 | if (!(msr & FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX) |
1308 | && !tboot_enabled()) | 1340 | && !tboot_enabled()) { |
1341 | printk(KERN_WARNING "kvm: disable TXT in the BIOS or " | ||
1342 | " activate TXT before enabling KVM\n"); | ||
1309 | return 1; | 1343 | return 1; |
1344 | } | ||
1310 | } | 1345 | } |
1311 | 1346 | ||
1312 | return 0; | 1347 | return 0; |
@@ -1400,6 +1435,14 @@ static __init int adjust_vmx_controls(u32 ctl_min, u32 ctl_opt, | |||
1400 | return 0; | 1435 | return 0; |
1401 | } | 1436 | } |
1402 | 1437 | ||
1438 | static __init bool allow_1_setting(u32 msr, u32 ctl) | ||
1439 | { | ||
1440 | u32 vmx_msr_low, vmx_msr_high; | ||
1441 | |||
1442 | rdmsr(msr, vmx_msr_low, vmx_msr_high); | ||
1443 | return vmx_msr_high & ctl; | ||
1444 | } | ||
1445 | |||
1403 | static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) | 1446 | static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) |
1404 | { | 1447 | { |
1405 | u32 vmx_msr_low, vmx_msr_high; | 1448 | u32 vmx_msr_low, vmx_msr_high; |
@@ -1416,7 +1459,7 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) | |||
1416 | &_pin_based_exec_control) < 0) | 1459 | &_pin_based_exec_control) < 0) |
1417 | return -EIO; | 1460 | return -EIO; |
1418 | 1461 | ||
1419 | min = CPU_BASED_HLT_EXITING | | 1462 | min = |
1420 | #ifdef CONFIG_X86_64 | 1463 | #ifdef CONFIG_X86_64 |
1421 | CPU_BASED_CR8_LOAD_EXITING | | 1464 | CPU_BASED_CR8_LOAD_EXITING | |
1422 | CPU_BASED_CR8_STORE_EXITING | | 1465 | CPU_BASED_CR8_STORE_EXITING | |
@@ -1429,6 +1472,10 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) | |||
1429 | CPU_BASED_MWAIT_EXITING | | 1472 | CPU_BASED_MWAIT_EXITING | |
1430 | CPU_BASED_MONITOR_EXITING | | 1473 | CPU_BASED_MONITOR_EXITING | |
1431 | CPU_BASED_INVLPG_EXITING; | 1474 | CPU_BASED_INVLPG_EXITING; |
1475 | |||
1476 | if (yield_on_hlt) | ||
1477 | min |= CPU_BASED_HLT_EXITING; | ||
1478 | |||
1432 | opt = CPU_BASED_TPR_SHADOW | | 1479 | opt = CPU_BASED_TPR_SHADOW | |
1433 | CPU_BASED_USE_MSR_BITMAPS | | 1480 | CPU_BASED_USE_MSR_BITMAPS | |
1434 | CPU_BASED_ACTIVATE_SECONDARY_CONTROLS; | 1481 | CPU_BASED_ACTIVATE_SECONDARY_CONTROLS; |
@@ -1510,6 +1557,12 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) | |||
1510 | vmcs_conf->vmexit_ctrl = _vmexit_control; | 1557 | vmcs_conf->vmexit_ctrl = _vmexit_control; |
1511 | vmcs_conf->vmentry_ctrl = _vmentry_control; | 1558 | vmcs_conf->vmentry_ctrl = _vmentry_control; |
1512 | 1559 | ||
1560 | cpu_has_load_ia32_efer = | ||
1561 | allow_1_setting(MSR_IA32_VMX_ENTRY_CTLS, | ||
1562 | VM_ENTRY_LOAD_IA32_EFER) | ||
1563 | && allow_1_setting(MSR_IA32_VMX_EXIT_CTLS, | ||
1564 | VM_EXIT_LOAD_IA32_EFER); | ||
1565 | |||
1513 | return 0; | 1566 | return 0; |
1514 | } | 1567 | } |
1515 | 1568 | ||
@@ -1683,9 +1736,13 @@ static void fix_rmode_seg(int seg, struct kvm_save_segment *save) | |||
1683 | save->limit = vmcs_read32(sf->limit); | 1736 | save->limit = vmcs_read32(sf->limit); |
1684 | save->ar = vmcs_read32(sf->ar_bytes); | 1737 | save->ar = vmcs_read32(sf->ar_bytes); |
1685 | vmcs_write16(sf->selector, save->base >> 4); | 1738 | vmcs_write16(sf->selector, save->base >> 4); |
1686 | vmcs_write32(sf->base, save->base & 0xfffff); | 1739 | vmcs_write32(sf->base, save->base & 0xffff0); |
1687 | vmcs_write32(sf->limit, 0xffff); | 1740 | vmcs_write32(sf->limit, 0xffff); |
1688 | vmcs_write32(sf->ar_bytes, 0xf3); | 1741 | vmcs_write32(sf->ar_bytes, 0xf3); |
1742 | if (save->base & 0xf) | ||
1743 | printk_once(KERN_WARNING "kvm: segment base is not paragraph" | ||
1744 | " aligned when entering protected mode (seg=%d)", | ||
1745 | seg); | ||
1689 | } | 1746 | } |
1690 | 1747 | ||
1691 | static void enter_rmode(struct kvm_vcpu *vcpu) | 1748 | static void enter_rmode(struct kvm_vcpu *vcpu) |
@@ -1814,6 +1871,13 @@ static void vmx_decache_cr0_guest_bits(struct kvm_vcpu *vcpu) | |||
1814 | vcpu->arch.cr0 |= vmcs_readl(GUEST_CR0) & cr0_guest_owned_bits; | 1871 | vcpu->arch.cr0 |= vmcs_readl(GUEST_CR0) & cr0_guest_owned_bits; |
1815 | } | 1872 | } |
1816 | 1873 | ||
1874 | static void vmx_decache_cr3(struct kvm_vcpu *vcpu) | ||
1875 | { | ||
1876 | if (enable_ept && is_paging(vcpu)) | ||
1877 | vcpu->arch.cr3 = vmcs_readl(GUEST_CR3); | ||
1878 | __set_bit(VCPU_EXREG_CR3, (ulong *)&vcpu->arch.regs_avail); | ||
1879 | } | ||
1880 | |||
1817 | static void vmx_decache_cr4_guest_bits(struct kvm_vcpu *vcpu) | 1881 | static void vmx_decache_cr4_guest_bits(struct kvm_vcpu *vcpu) |
1818 | { | 1882 | { |
1819 | ulong cr4_guest_owned_bits = vcpu->arch.cr4_guest_owned_bits; | 1883 | ulong cr4_guest_owned_bits = vcpu->arch.cr4_guest_owned_bits; |
@@ -1857,6 +1921,7 @@ static void ept_update_paging_mode_cr0(unsigned long *hw_cr0, | |||
1857 | unsigned long cr0, | 1921 | unsigned long cr0, |
1858 | struct kvm_vcpu *vcpu) | 1922 | struct kvm_vcpu *vcpu) |
1859 | { | 1923 | { |
1924 | vmx_decache_cr3(vcpu); | ||
1860 | if (!(cr0 & X86_CR0_PG)) { | 1925 | if (!(cr0 & X86_CR0_PG)) { |
1861 | /* From paging/starting to nonpaging */ | 1926 | /* From paging/starting to nonpaging */ |
1862 | vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, | 1927 | vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, |
@@ -1937,7 +2002,7 @@ static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) | |||
1937 | if (enable_ept) { | 2002 | if (enable_ept) { |
1938 | eptp = construct_eptp(cr3); | 2003 | eptp = construct_eptp(cr3); |
1939 | vmcs_write64(EPT_POINTER, eptp); | 2004 | vmcs_write64(EPT_POINTER, eptp); |
1940 | guest_cr3 = is_paging(vcpu) ? vcpu->arch.cr3 : | 2005 | guest_cr3 = is_paging(vcpu) ? kvm_read_cr3(vcpu) : |
1941 | vcpu->kvm->arch.ept_identity_map_addr; | 2006 | vcpu->kvm->arch.ept_identity_map_addr; |
1942 | ept_load_pdptrs(vcpu); | 2007 | ept_load_pdptrs(vcpu); |
1943 | } | 2008 | } |
@@ -2725,7 +2790,7 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu) | |||
2725 | vmcs_writel(GUEST_IDTR_BASE, 0); | 2790 | vmcs_writel(GUEST_IDTR_BASE, 0); |
2726 | vmcs_write32(GUEST_IDTR_LIMIT, 0xffff); | 2791 | vmcs_write32(GUEST_IDTR_LIMIT, 0xffff); |
2727 | 2792 | ||
2728 | vmcs_write32(GUEST_ACTIVITY_STATE, 0); | 2793 | vmcs_write32(GUEST_ACTIVITY_STATE, GUEST_ACTIVITY_ACTIVE); |
2729 | vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, 0); | 2794 | vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, 0); |
2730 | vmcs_write32(GUEST_PENDING_DBG_EXCEPTIONS, 0); | 2795 | vmcs_write32(GUEST_PENDING_DBG_EXCEPTIONS, 0); |
2731 | 2796 | ||
@@ -2787,6 +2852,10 @@ static void enable_nmi_window(struct kvm_vcpu *vcpu) | |||
2787 | return; | 2852 | return; |
2788 | } | 2853 | } |
2789 | 2854 | ||
2855 | if (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & GUEST_INTR_STATE_STI) { | ||
2856 | enable_irq_window(vcpu); | ||
2857 | return; | ||
2858 | } | ||
2790 | cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL); | 2859 | cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL); |
2791 | cpu_based_vm_exec_control |= CPU_BASED_VIRTUAL_NMI_PENDING; | 2860 | cpu_based_vm_exec_control |= CPU_BASED_VIRTUAL_NMI_PENDING; |
2792 | vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control); | 2861 | vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control); |
@@ -2814,6 +2883,7 @@ static void vmx_inject_irq(struct kvm_vcpu *vcpu) | |||
2814 | } else | 2883 | } else |
2815 | intr |= INTR_TYPE_EXT_INTR; | 2884 | intr |= INTR_TYPE_EXT_INTR; |
2816 | vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr); | 2885 | vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr); |
2886 | vmx_clear_hlt(vcpu); | ||
2817 | } | 2887 | } |
2818 | 2888 | ||
2819 | static void vmx_inject_nmi(struct kvm_vcpu *vcpu) | 2889 | static void vmx_inject_nmi(struct kvm_vcpu *vcpu) |
@@ -2841,6 +2911,7 @@ static void vmx_inject_nmi(struct kvm_vcpu *vcpu) | |||
2841 | } | 2911 | } |
2842 | vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, | 2912 | vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, |
2843 | INTR_TYPE_NMI_INTR | INTR_INFO_VALID_MASK | NMI_VECTOR); | 2913 | INTR_TYPE_NMI_INTR | INTR_INFO_VALID_MASK | NMI_VECTOR); |
2914 | vmx_clear_hlt(vcpu); | ||
2844 | } | 2915 | } |
2845 | 2916 | ||
2846 | static int vmx_nmi_allowed(struct kvm_vcpu *vcpu) | 2917 | static int vmx_nmi_allowed(struct kvm_vcpu *vcpu) |
@@ -2849,7 +2920,8 @@ static int vmx_nmi_allowed(struct kvm_vcpu *vcpu) | |||
2849 | return 0; | 2920 | return 0; |
2850 | 2921 | ||
2851 | return !(vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & | 2922 | return !(vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & |
2852 | (GUEST_INTR_STATE_MOV_SS | GUEST_INTR_STATE_NMI)); | 2923 | (GUEST_INTR_STATE_MOV_SS | GUEST_INTR_STATE_STI |
2924 | | GUEST_INTR_STATE_NMI)); | ||
2853 | } | 2925 | } |
2854 | 2926 | ||
2855 | static bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu) | 2927 | static bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu) |
@@ -2910,7 +2982,7 @@ static int handle_rmode_exception(struct kvm_vcpu *vcpu, | |||
2910 | * Cause the #SS fault with 0 error code in VM86 mode. | 2982 | * Cause the #SS fault with 0 error code in VM86 mode. |
2911 | */ | 2983 | */ |
2912 | if (((vec == GP_VECTOR) || (vec == SS_VECTOR)) && err_code == 0) | 2984 | if (((vec == GP_VECTOR) || (vec == SS_VECTOR)) && err_code == 0) |
2913 | if (emulate_instruction(vcpu, 0, 0, 0) == EMULATE_DONE) | 2985 | if (emulate_instruction(vcpu, 0) == EMULATE_DONE) |
2914 | return 1; | 2986 | return 1; |
2915 | /* | 2987 | /* |
2916 | * Forward all other exceptions that are valid in real mode. | 2988 | * Forward all other exceptions that are valid in real mode. |
@@ -3007,7 +3079,7 @@ static int handle_exception(struct kvm_vcpu *vcpu) | |||
3007 | } | 3079 | } |
3008 | 3080 | ||
3009 | if (is_invalid_opcode(intr_info)) { | 3081 | if (is_invalid_opcode(intr_info)) { |
3010 | er = emulate_instruction(vcpu, 0, 0, EMULTYPE_TRAP_UD); | 3082 | er = emulate_instruction(vcpu, EMULTYPE_TRAP_UD); |
3011 | if (er != EMULATE_DONE) | 3083 | if (er != EMULATE_DONE) |
3012 | kvm_queue_exception(vcpu, UD_VECTOR); | 3084 | kvm_queue_exception(vcpu, UD_VECTOR); |
3013 | return 1; | 3085 | return 1; |
@@ -3026,7 +3098,7 @@ static int handle_exception(struct kvm_vcpu *vcpu) | |||
3026 | 3098 | ||
3027 | if (kvm_event_needs_reinjection(vcpu)) | 3099 | if (kvm_event_needs_reinjection(vcpu)) |
3028 | kvm_mmu_unprotect_page_virt(vcpu, cr2); | 3100 | kvm_mmu_unprotect_page_virt(vcpu, cr2); |
3029 | return kvm_mmu_page_fault(vcpu, cr2, error_code); | 3101 | return kvm_mmu_page_fault(vcpu, cr2, error_code, NULL, 0); |
3030 | } | 3102 | } |
3031 | 3103 | ||
3032 | if (vmx->rmode.vm86_active && | 3104 | if (vmx->rmode.vm86_active && |
@@ -3098,7 +3170,7 @@ static int handle_io(struct kvm_vcpu *vcpu) | |||
3098 | ++vcpu->stat.io_exits; | 3170 | ++vcpu->stat.io_exits; |
3099 | 3171 | ||
3100 | if (string || in) | 3172 | if (string || in) |
3101 | return emulate_instruction(vcpu, 0, 0, 0) == EMULATE_DONE; | 3173 | return emulate_instruction(vcpu, 0) == EMULATE_DONE; |
3102 | 3174 | ||
3103 | port = exit_qualification >> 16; | 3175 | port = exit_qualification >> 16; |
3104 | size = (exit_qualification & 7) + 1; | 3176 | size = (exit_qualification & 7) + 1; |
@@ -3118,14 +3190,6 @@ vmx_patch_hypercall(struct kvm_vcpu *vcpu, unsigned char *hypercall) | |||
3118 | hypercall[2] = 0xc1; | 3190 | hypercall[2] = 0xc1; |
3119 | } | 3191 | } |
3120 | 3192 | ||
3121 | static void complete_insn_gp(struct kvm_vcpu *vcpu, int err) | ||
3122 | { | ||
3123 | if (err) | ||
3124 | kvm_inject_gp(vcpu, 0); | ||
3125 | else | ||
3126 | skip_emulated_instruction(vcpu); | ||
3127 | } | ||
3128 | |||
3129 | static int handle_cr(struct kvm_vcpu *vcpu) | 3193 | static int handle_cr(struct kvm_vcpu *vcpu) |
3130 | { | 3194 | { |
3131 | unsigned long exit_qualification, val; | 3195 | unsigned long exit_qualification, val; |
@@ -3143,21 +3207,21 @@ static int handle_cr(struct kvm_vcpu *vcpu) | |||
3143 | switch (cr) { | 3207 | switch (cr) { |
3144 | case 0: | 3208 | case 0: |
3145 | err = kvm_set_cr0(vcpu, val); | 3209 | err = kvm_set_cr0(vcpu, val); |
3146 | complete_insn_gp(vcpu, err); | 3210 | kvm_complete_insn_gp(vcpu, err); |
3147 | return 1; | 3211 | return 1; |
3148 | case 3: | 3212 | case 3: |
3149 | err = kvm_set_cr3(vcpu, val); | 3213 | err = kvm_set_cr3(vcpu, val); |
3150 | complete_insn_gp(vcpu, err); | 3214 | kvm_complete_insn_gp(vcpu, err); |
3151 | return 1; | 3215 | return 1; |
3152 | case 4: | 3216 | case 4: |
3153 | err = kvm_set_cr4(vcpu, val); | 3217 | err = kvm_set_cr4(vcpu, val); |
3154 | complete_insn_gp(vcpu, err); | 3218 | kvm_complete_insn_gp(vcpu, err); |
3155 | return 1; | 3219 | return 1; |
3156 | case 8: { | 3220 | case 8: { |
3157 | u8 cr8_prev = kvm_get_cr8(vcpu); | 3221 | u8 cr8_prev = kvm_get_cr8(vcpu); |
3158 | u8 cr8 = kvm_register_read(vcpu, reg); | 3222 | u8 cr8 = kvm_register_read(vcpu, reg); |
3159 | kvm_set_cr8(vcpu, cr8); | 3223 | err = kvm_set_cr8(vcpu, cr8); |
3160 | skip_emulated_instruction(vcpu); | 3224 | kvm_complete_insn_gp(vcpu, err); |
3161 | if (irqchip_in_kernel(vcpu->kvm)) | 3225 | if (irqchip_in_kernel(vcpu->kvm)) |
3162 | return 1; | 3226 | return 1; |
3163 | if (cr8_prev <= cr8) | 3227 | if (cr8_prev <= cr8) |
@@ -3176,8 +3240,9 @@ static int handle_cr(struct kvm_vcpu *vcpu) | |||
3176 | case 1: /*mov from cr*/ | 3240 | case 1: /*mov from cr*/ |
3177 | switch (cr) { | 3241 | switch (cr) { |
3178 | case 3: | 3242 | case 3: |
3179 | kvm_register_write(vcpu, reg, vcpu->arch.cr3); | 3243 | val = kvm_read_cr3(vcpu); |
3180 | trace_kvm_cr_read(cr, vcpu->arch.cr3); | 3244 | kvm_register_write(vcpu, reg, val); |
3245 | trace_kvm_cr_read(cr, val); | ||
3181 | skip_emulated_instruction(vcpu); | 3246 | skip_emulated_instruction(vcpu); |
3182 | return 1; | 3247 | return 1; |
3183 | case 8: | 3248 | case 8: |
@@ -3349,6 +3414,11 @@ static int handle_vmx_insn(struct kvm_vcpu *vcpu) | |||
3349 | return 1; | 3414 | return 1; |
3350 | } | 3415 | } |
3351 | 3416 | ||
3417 | static int handle_invd(struct kvm_vcpu *vcpu) | ||
3418 | { | ||
3419 | return emulate_instruction(vcpu, 0) == EMULATE_DONE; | ||
3420 | } | ||
3421 | |||
3352 | static int handle_invlpg(struct kvm_vcpu *vcpu) | 3422 | static int handle_invlpg(struct kvm_vcpu *vcpu) |
3353 | { | 3423 | { |
3354 | unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION); | 3424 | unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION); |
@@ -3377,7 +3447,7 @@ static int handle_xsetbv(struct kvm_vcpu *vcpu) | |||
3377 | 3447 | ||
3378 | static int handle_apic_access(struct kvm_vcpu *vcpu) | 3448 | static int handle_apic_access(struct kvm_vcpu *vcpu) |
3379 | { | 3449 | { |
3380 | return emulate_instruction(vcpu, 0, 0, 0) == EMULATE_DONE; | 3450 | return emulate_instruction(vcpu, 0) == EMULATE_DONE; |
3381 | } | 3451 | } |
3382 | 3452 | ||
3383 | static int handle_task_switch(struct kvm_vcpu *vcpu) | 3453 | static int handle_task_switch(struct kvm_vcpu *vcpu) |
@@ -3476,7 +3546,7 @@ static int handle_ept_violation(struct kvm_vcpu *vcpu) | |||
3476 | 3546 | ||
3477 | gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS); | 3547 | gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS); |
3478 | trace_kvm_page_fault(gpa, exit_qualification); | 3548 | trace_kvm_page_fault(gpa, exit_qualification); |
3479 | return kvm_mmu_page_fault(vcpu, gpa & PAGE_MASK, 0); | 3549 | return kvm_mmu_page_fault(vcpu, gpa, exit_qualification & 0x3, NULL, 0); |
3480 | } | 3550 | } |
3481 | 3551 | ||
3482 | static u64 ept_rsvd_mask(u64 spte, int level) | 3552 | static u64 ept_rsvd_mask(u64 spte, int level) |
@@ -3592,7 +3662,7 @@ static int handle_invalid_guest_state(struct kvm_vcpu *vcpu) | |||
3592 | && (kvm_get_rflags(&vmx->vcpu) & X86_EFLAGS_IF)) | 3662 | && (kvm_get_rflags(&vmx->vcpu) & X86_EFLAGS_IF)) |
3593 | return handle_interrupt_window(&vmx->vcpu); | 3663 | return handle_interrupt_window(&vmx->vcpu); |
3594 | 3664 | ||
3595 | err = emulate_instruction(vcpu, 0, 0, 0); | 3665 | err = emulate_instruction(vcpu, 0); |
3596 | 3666 | ||
3597 | if (err == EMULATE_DO_MMIO) { | 3667 | if (err == EMULATE_DO_MMIO) { |
3598 | ret = 0; | 3668 | ret = 0; |
@@ -3649,6 +3719,7 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = { | |||
3649 | [EXIT_REASON_MSR_WRITE] = handle_wrmsr, | 3719 | [EXIT_REASON_MSR_WRITE] = handle_wrmsr, |
3650 | [EXIT_REASON_PENDING_INTERRUPT] = handle_interrupt_window, | 3720 | [EXIT_REASON_PENDING_INTERRUPT] = handle_interrupt_window, |
3651 | [EXIT_REASON_HLT] = handle_halt, | 3721 | [EXIT_REASON_HLT] = handle_halt, |
3722 | [EXIT_REASON_INVD] = handle_invd, | ||
3652 | [EXIT_REASON_INVLPG] = handle_invlpg, | 3723 | [EXIT_REASON_INVLPG] = handle_invlpg, |
3653 | [EXIT_REASON_VMCALL] = handle_vmcall, | 3724 | [EXIT_REASON_VMCALL] = handle_vmcall, |
3654 | [EXIT_REASON_VMCLEAR] = handle_vmx_insn, | 3725 | [EXIT_REASON_VMCLEAR] = handle_vmx_insn, |
@@ -3676,6 +3747,12 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = { | |||
3676 | static const int kvm_vmx_max_exit_handlers = | 3747 | static const int kvm_vmx_max_exit_handlers = |
3677 | ARRAY_SIZE(kvm_vmx_exit_handlers); | 3748 | ARRAY_SIZE(kvm_vmx_exit_handlers); |
3678 | 3749 | ||
3750 | static void vmx_get_exit_info(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2) | ||
3751 | { | ||
3752 | *info1 = vmcs_readl(EXIT_QUALIFICATION); | ||
3753 | *info2 = vmcs_read32(VM_EXIT_INTR_INFO); | ||
3754 | } | ||
3755 | |||
3679 | /* | 3756 | /* |
3680 | * The guest has exited. See if we can fix it or if we need userspace | 3757 | * The guest has exited. See if we can fix it or if we need userspace |
3681 | * assistance. | 3758 | * assistance. |
@@ -3686,17 +3763,12 @@ static int vmx_handle_exit(struct kvm_vcpu *vcpu) | |||
3686 | u32 exit_reason = vmx->exit_reason; | 3763 | u32 exit_reason = vmx->exit_reason; |
3687 | u32 vectoring_info = vmx->idt_vectoring_info; | 3764 | u32 vectoring_info = vmx->idt_vectoring_info; |
3688 | 3765 | ||
3689 | trace_kvm_exit(exit_reason, vcpu); | 3766 | trace_kvm_exit(exit_reason, vcpu, KVM_ISA_VMX); |
3690 | 3767 | ||
3691 | /* If guest state is invalid, start emulating */ | 3768 | /* If guest state is invalid, start emulating */ |
3692 | if (vmx->emulation_required && emulate_invalid_guest_state) | 3769 | if (vmx->emulation_required && emulate_invalid_guest_state) |
3693 | return handle_invalid_guest_state(vcpu); | 3770 | return handle_invalid_guest_state(vcpu); |
3694 | 3771 | ||
3695 | /* Access CR3 don't cause VMExit in paging mode, so we need | ||
3696 | * to sync with guest real CR3. */ | ||
3697 | if (enable_ept && is_paging(vcpu)) | ||
3698 | vcpu->arch.cr3 = vmcs_readl(GUEST_CR3); | ||
3699 | |||
3700 | if (exit_reason & VMX_EXIT_REASONS_FAILED_VMENTRY) { | 3772 | if (exit_reason & VMX_EXIT_REASONS_FAILED_VMENTRY) { |
3701 | vcpu->run->exit_reason = KVM_EXIT_FAIL_ENTRY; | 3773 | vcpu->run->exit_reason = KVM_EXIT_FAIL_ENTRY; |
3702 | vcpu->run->fail_entry.hardware_entry_failure_reason | 3774 | vcpu->run->fail_entry.hardware_entry_failure_reason |
@@ -4013,7 +4085,8 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu) | |||
4013 | ); | 4085 | ); |
4014 | 4086 | ||
4015 | vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP) | 4087 | vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP) |
4016 | | (1 << VCPU_EXREG_PDPTR)); | 4088 | | (1 << VCPU_EXREG_PDPTR) |
4089 | | (1 << VCPU_EXREG_CR3)); | ||
4017 | vcpu->arch.regs_dirty = 0; | 4090 | vcpu->arch.regs_dirty = 0; |
4018 | 4091 | ||
4019 | vmx->idt_vectoring_info = vmcs_read32(IDT_VECTORING_INFO_FIELD); | 4092 | vmx->idt_vectoring_info = vmcs_read32(IDT_VECTORING_INFO_FIELD); |
@@ -4280,6 +4353,7 @@ static struct kvm_x86_ops vmx_x86_ops = { | |||
4280 | .get_cpl = vmx_get_cpl, | 4353 | .get_cpl = vmx_get_cpl, |
4281 | .get_cs_db_l_bits = vmx_get_cs_db_l_bits, | 4354 | .get_cs_db_l_bits = vmx_get_cs_db_l_bits, |
4282 | .decache_cr0_guest_bits = vmx_decache_cr0_guest_bits, | 4355 | .decache_cr0_guest_bits = vmx_decache_cr0_guest_bits, |
4356 | .decache_cr3 = vmx_decache_cr3, | ||
4283 | .decache_cr4_guest_bits = vmx_decache_cr4_guest_bits, | 4357 | .decache_cr4_guest_bits = vmx_decache_cr4_guest_bits, |
4284 | .set_cr0 = vmx_set_cr0, | 4358 | .set_cr0 = vmx_set_cr0, |
4285 | .set_cr3 = vmx_set_cr3, | 4359 | .set_cr3 = vmx_set_cr3, |
@@ -4320,7 +4394,9 @@ static struct kvm_x86_ops vmx_x86_ops = { | |||
4320 | .get_tdp_level = get_ept_level, | 4394 | .get_tdp_level = get_ept_level, |
4321 | .get_mt_mask = vmx_get_mt_mask, | 4395 | .get_mt_mask = vmx_get_mt_mask, |
4322 | 4396 | ||
4397 | .get_exit_info = vmx_get_exit_info, | ||
4323 | .exit_reasons_str = vmx_exit_reasons_str, | 4398 | .exit_reasons_str = vmx_exit_reasons_str, |
4399 | |||
4324 | .get_lpage_level = vmx_get_lpage_level, | 4400 | .get_lpage_level = vmx_get_lpage_level, |
4325 | 4401 | ||
4326 | .cpuid_update = vmx_cpuid_update, | 4402 | .cpuid_update = vmx_cpuid_update, |
@@ -4396,8 +4472,6 @@ static int __init vmx_init(void) | |||
4396 | 4472 | ||
4397 | if (enable_ept) { | 4473 | if (enable_ept) { |
4398 | bypass_guest_pf = 0; | 4474 | bypass_guest_pf = 0; |
4399 | kvm_mmu_set_base_ptes(VMX_EPT_READABLE_MASK | | ||
4400 | VMX_EPT_WRITABLE_MASK); | ||
4401 | kvm_mmu_set_mask_ptes(0ull, 0ull, 0ull, 0ull, | 4475 | kvm_mmu_set_mask_ptes(0ull, 0ull, 0ull, 0ull, |
4402 | VMX_EPT_EXECUTABLE_MASK); | 4476 | VMX_EPT_EXECUTABLE_MASK); |
4403 | kvm_enable_tdp(); | 4477 | kvm_enable_tdp(); |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 46a368cb651e..bcc0efce85bf 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <linux/slab.h> | 43 | #include <linux/slab.h> |
44 | #include <linux/perf_event.h> | 44 | #include <linux/perf_event.h> |
45 | #include <linux/uaccess.h> | 45 | #include <linux/uaccess.h> |
46 | #include <linux/hash.h> | ||
46 | #include <trace/events/kvm.h> | 47 | #include <trace/events/kvm.h> |
47 | 48 | ||
48 | #define CREATE_TRACE_POINTS | 49 | #define CREATE_TRACE_POINTS |
@@ -155,6 +156,13 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { | |||
155 | 156 | ||
156 | u64 __read_mostly host_xcr0; | 157 | u64 __read_mostly host_xcr0; |
157 | 158 | ||
159 | static inline void kvm_async_pf_hash_reset(struct kvm_vcpu *vcpu) | ||
160 | { | ||
161 | int i; | ||
162 | for (i = 0; i < roundup_pow_of_two(ASYNC_PF_PER_VCPU); i++) | ||
163 | vcpu->arch.apf.gfns[i] = ~0; | ||
164 | } | ||
165 | |||
158 | static void kvm_on_user_return(struct user_return_notifier *urn) | 166 | static void kvm_on_user_return(struct user_return_notifier *urn) |
159 | { | 167 | { |
160 | unsigned slot; | 168 | unsigned slot; |
@@ -326,23 +334,28 @@ void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned nr) | |||
326 | } | 334 | } |
327 | EXPORT_SYMBOL_GPL(kvm_requeue_exception); | 335 | EXPORT_SYMBOL_GPL(kvm_requeue_exception); |
328 | 336 | ||
329 | void kvm_inject_page_fault(struct kvm_vcpu *vcpu) | 337 | void kvm_complete_insn_gp(struct kvm_vcpu *vcpu, int err) |
330 | { | 338 | { |
331 | unsigned error_code = vcpu->arch.fault.error_code; | 339 | if (err) |
340 | kvm_inject_gp(vcpu, 0); | ||
341 | else | ||
342 | kvm_x86_ops->skip_emulated_instruction(vcpu); | ||
343 | } | ||
344 | EXPORT_SYMBOL_GPL(kvm_complete_insn_gp); | ||
332 | 345 | ||
346 | void kvm_inject_page_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault) | ||
347 | { | ||
333 | ++vcpu->stat.pf_guest; | 348 | ++vcpu->stat.pf_guest; |
334 | vcpu->arch.cr2 = vcpu->arch.fault.address; | 349 | vcpu->arch.cr2 = fault->address; |
335 | kvm_queue_exception_e(vcpu, PF_VECTOR, error_code); | 350 | kvm_queue_exception_e(vcpu, PF_VECTOR, fault->error_code); |
336 | } | 351 | } |
337 | 352 | ||
338 | void kvm_propagate_fault(struct kvm_vcpu *vcpu) | 353 | void kvm_propagate_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault) |
339 | { | 354 | { |
340 | if (mmu_is_nested(vcpu) && !vcpu->arch.fault.nested) | 355 | if (mmu_is_nested(vcpu) && !fault->nested_page_fault) |
341 | vcpu->arch.nested_mmu.inject_page_fault(vcpu); | 356 | vcpu->arch.nested_mmu.inject_page_fault(vcpu, fault); |
342 | else | 357 | else |
343 | vcpu->arch.mmu.inject_page_fault(vcpu); | 358 | vcpu->arch.mmu.inject_page_fault(vcpu, fault); |
344 | |||
345 | vcpu->arch.fault.nested = false; | ||
346 | } | 359 | } |
347 | 360 | ||
348 | void kvm_inject_nmi(struct kvm_vcpu *vcpu) | 361 | void kvm_inject_nmi(struct kvm_vcpu *vcpu) |
@@ -460,8 +473,8 @@ static bool pdptrs_changed(struct kvm_vcpu *vcpu) | |||
460 | (unsigned long *)&vcpu->arch.regs_avail)) | 473 | (unsigned long *)&vcpu->arch.regs_avail)) |
461 | return true; | 474 | return true; |
462 | 475 | ||
463 | gfn = (vcpu->arch.cr3 & ~31u) >> PAGE_SHIFT; | 476 | gfn = (kvm_read_cr3(vcpu) & ~31u) >> PAGE_SHIFT; |
464 | offset = (vcpu->arch.cr3 & ~31u) & (PAGE_SIZE - 1); | 477 | offset = (kvm_read_cr3(vcpu) & ~31u) & (PAGE_SIZE - 1); |
465 | r = kvm_read_nested_guest_page(vcpu, gfn, pdpte, offset, sizeof(pdpte), | 478 | r = kvm_read_nested_guest_page(vcpu, gfn, pdpte, offset, sizeof(pdpte), |
466 | PFERR_USER_MASK | PFERR_WRITE_MASK); | 479 | PFERR_USER_MASK | PFERR_WRITE_MASK); |
467 | if (r < 0) | 480 | if (r < 0) |
@@ -506,12 +519,15 @@ int kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) | |||
506 | } else | 519 | } else |
507 | #endif | 520 | #endif |
508 | if (is_pae(vcpu) && !load_pdptrs(vcpu, vcpu->arch.walk_mmu, | 521 | if (is_pae(vcpu) && !load_pdptrs(vcpu, vcpu->arch.walk_mmu, |
509 | vcpu->arch.cr3)) | 522 | kvm_read_cr3(vcpu))) |
510 | return 1; | 523 | return 1; |
511 | } | 524 | } |
512 | 525 | ||
513 | kvm_x86_ops->set_cr0(vcpu, cr0); | 526 | kvm_x86_ops->set_cr0(vcpu, cr0); |
514 | 527 | ||
528 | if ((cr0 ^ old_cr0) & X86_CR0_PG) | ||
529 | kvm_clear_async_pf_completion_queue(vcpu); | ||
530 | |||
515 | if ((cr0 ^ old_cr0) & update_bits) | 531 | if ((cr0 ^ old_cr0) & update_bits) |
516 | kvm_mmu_reset_context(vcpu); | 532 | kvm_mmu_reset_context(vcpu); |
517 | return 0; | 533 | return 0; |
@@ -595,7 +611,8 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) | |||
595 | return 1; | 611 | return 1; |
596 | } else if (is_paging(vcpu) && (cr4 & X86_CR4_PAE) | 612 | } else if (is_paging(vcpu) && (cr4 & X86_CR4_PAE) |
597 | && ((cr4 ^ old_cr4) & pdptr_bits) | 613 | && ((cr4 ^ old_cr4) & pdptr_bits) |
598 | && !load_pdptrs(vcpu, vcpu->arch.walk_mmu, vcpu->arch.cr3)) | 614 | && !load_pdptrs(vcpu, vcpu->arch.walk_mmu, |
615 | kvm_read_cr3(vcpu))) | ||
599 | return 1; | 616 | return 1; |
600 | 617 | ||
601 | if (cr4 & X86_CR4_VMXE) | 618 | if (cr4 & X86_CR4_VMXE) |
@@ -615,7 +632,7 @@ EXPORT_SYMBOL_GPL(kvm_set_cr4); | |||
615 | 632 | ||
616 | int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) | 633 | int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) |
617 | { | 634 | { |
618 | if (cr3 == vcpu->arch.cr3 && !pdptrs_changed(vcpu)) { | 635 | if (cr3 == kvm_read_cr3(vcpu) && !pdptrs_changed(vcpu)) { |
619 | kvm_mmu_sync_roots(vcpu); | 636 | kvm_mmu_sync_roots(vcpu); |
620 | kvm_mmu_flush_tlb(vcpu); | 637 | kvm_mmu_flush_tlb(vcpu); |
621 | return 0; | 638 | return 0; |
@@ -650,12 +667,13 @@ int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) | |||
650 | if (unlikely(!gfn_to_memslot(vcpu->kvm, cr3 >> PAGE_SHIFT))) | 667 | if (unlikely(!gfn_to_memslot(vcpu->kvm, cr3 >> PAGE_SHIFT))) |
651 | return 1; | 668 | return 1; |
652 | vcpu->arch.cr3 = cr3; | 669 | vcpu->arch.cr3 = cr3; |
670 | __set_bit(VCPU_EXREG_CR3, (ulong *)&vcpu->arch.regs_avail); | ||
653 | vcpu->arch.mmu.new_cr3(vcpu); | 671 | vcpu->arch.mmu.new_cr3(vcpu); |
654 | return 0; | 672 | return 0; |
655 | } | 673 | } |
656 | EXPORT_SYMBOL_GPL(kvm_set_cr3); | 674 | EXPORT_SYMBOL_GPL(kvm_set_cr3); |
657 | 675 | ||
658 | int __kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8) | 676 | int kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8) |
659 | { | 677 | { |
660 | if (cr8 & CR8_RESERVED_BITS) | 678 | if (cr8 & CR8_RESERVED_BITS) |
661 | return 1; | 679 | return 1; |
@@ -665,12 +683,6 @@ int __kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8) | |||
665 | vcpu->arch.cr8 = cr8; | 683 | vcpu->arch.cr8 = cr8; |
666 | return 0; | 684 | return 0; |
667 | } | 685 | } |
668 | |||
669 | void kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8) | ||
670 | { | ||
671 | if (__kvm_set_cr8(vcpu, cr8)) | ||
672 | kvm_inject_gp(vcpu, 0); | ||
673 | } | ||
674 | EXPORT_SYMBOL_GPL(kvm_set_cr8); | 686 | EXPORT_SYMBOL_GPL(kvm_set_cr8); |
675 | 687 | ||
676 | unsigned long kvm_get_cr8(struct kvm_vcpu *vcpu) | 688 | unsigned long kvm_get_cr8(struct kvm_vcpu *vcpu) |
@@ -775,12 +787,12 @@ EXPORT_SYMBOL_GPL(kvm_get_dr); | |||
775 | * kvm-specific. Those are put in the beginning of the list. | 787 | * kvm-specific. Those are put in the beginning of the list. |
776 | */ | 788 | */ |
777 | 789 | ||
778 | #define KVM_SAVE_MSRS_BEGIN 7 | 790 | #define KVM_SAVE_MSRS_BEGIN 8 |
779 | static u32 msrs_to_save[] = { | 791 | static u32 msrs_to_save[] = { |
780 | MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK, | 792 | MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK, |
781 | MSR_KVM_SYSTEM_TIME_NEW, MSR_KVM_WALL_CLOCK_NEW, | 793 | MSR_KVM_SYSTEM_TIME_NEW, MSR_KVM_WALL_CLOCK_NEW, |
782 | HV_X64_MSR_GUEST_OS_ID, HV_X64_MSR_HYPERCALL, | 794 | HV_X64_MSR_GUEST_OS_ID, HV_X64_MSR_HYPERCALL, |
783 | HV_X64_MSR_APIC_ASSIST_PAGE, | 795 | HV_X64_MSR_APIC_ASSIST_PAGE, MSR_KVM_ASYNC_PF_EN, |
784 | MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP, | 796 | MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP, |
785 | MSR_STAR, | 797 | MSR_STAR, |
786 | #ifdef CONFIG_X86_64 | 798 | #ifdef CONFIG_X86_64 |
@@ -830,7 +842,6 @@ static int set_efer(struct kvm_vcpu *vcpu, u64 efer) | |||
830 | kvm_x86_ops->set_efer(vcpu, efer); | 842 | kvm_x86_ops->set_efer(vcpu, efer); |
831 | 843 | ||
832 | vcpu->arch.mmu.base_role.nxe = (efer & EFER_NX) && !tdp_enabled; | 844 | vcpu->arch.mmu.base_role.nxe = (efer & EFER_NX) && !tdp_enabled; |
833 | kvm_mmu_reset_context(vcpu); | ||
834 | 845 | ||
835 | /* Update reserved bits */ | 846 | /* Update reserved bits */ |
836 | if ((efer ^ old_efer) & EFER_NX) | 847 | if ((efer ^ old_efer) & EFER_NX) |
@@ -1418,6 +1429,30 @@ static int set_msr_hyperv(struct kvm_vcpu *vcpu, u32 msr, u64 data) | |||
1418 | return 0; | 1429 | return 0; |
1419 | } | 1430 | } |
1420 | 1431 | ||
1432 | static int kvm_pv_enable_async_pf(struct kvm_vcpu *vcpu, u64 data) | ||
1433 | { | ||
1434 | gpa_t gpa = data & ~0x3f; | ||
1435 | |||
1436 | /* Bits 2:5 are resrved, Should be zero */ | ||
1437 | if (data & 0x3c) | ||
1438 | return 1; | ||
1439 | |||
1440 | vcpu->arch.apf.msr_val = data; | ||
1441 | |||
1442 | if (!(data & KVM_ASYNC_PF_ENABLED)) { | ||
1443 | kvm_clear_async_pf_completion_queue(vcpu); | ||
1444 | kvm_async_pf_hash_reset(vcpu); | ||
1445 | return 0; | ||
1446 | } | ||
1447 | |||
1448 | if (kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.apf.data, gpa)) | ||
1449 | return 1; | ||
1450 | |||
1451 | vcpu->arch.apf.send_user_only = !(data & KVM_ASYNC_PF_SEND_ALWAYS); | ||
1452 | kvm_async_pf_wakeup_all(vcpu); | ||
1453 | return 0; | ||
1454 | } | ||
1455 | |||
1421 | int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) | 1456 | int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) |
1422 | { | 1457 | { |
1423 | switch (msr) { | 1458 | switch (msr) { |
@@ -1499,6 +1534,10 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) | |||
1499 | } | 1534 | } |
1500 | break; | 1535 | break; |
1501 | } | 1536 | } |
1537 | case MSR_KVM_ASYNC_PF_EN: | ||
1538 | if (kvm_pv_enable_async_pf(vcpu, data)) | ||
1539 | return 1; | ||
1540 | break; | ||
1502 | case MSR_IA32_MCG_CTL: | 1541 | case MSR_IA32_MCG_CTL: |
1503 | case MSR_IA32_MCG_STATUS: | 1542 | case MSR_IA32_MCG_STATUS: |
1504 | case MSR_IA32_MC0_CTL ... MSR_IA32_MC0_CTL + 4 * KVM_MAX_MCE_BANKS - 1: | 1543 | case MSR_IA32_MC0_CTL ... MSR_IA32_MC0_CTL + 4 * KVM_MAX_MCE_BANKS - 1: |
@@ -1775,6 +1814,9 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) | |||
1775 | case MSR_KVM_SYSTEM_TIME_NEW: | 1814 | case MSR_KVM_SYSTEM_TIME_NEW: |
1776 | data = vcpu->arch.time; | 1815 | data = vcpu->arch.time; |
1777 | break; | 1816 | break; |
1817 | case MSR_KVM_ASYNC_PF_EN: | ||
1818 | data = vcpu->arch.apf.msr_val; | ||
1819 | break; | ||
1778 | case MSR_IA32_P5_MC_ADDR: | 1820 | case MSR_IA32_P5_MC_ADDR: |
1779 | case MSR_IA32_P5_MC_TYPE: | 1821 | case MSR_IA32_P5_MC_TYPE: |
1780 | case MSR_IA32_MCG_CAP: | 1822 | case MSR_IA32_MCG_CAP: |
@@ -1904,6 +1946,7 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
1904 | case KVM_CAP_NOP_IO_DELAY: | 1946 | case KVM_CAP_NOP_IO_DELAY: |
1905 | case KVM_CAP_MP_STATE: | 1947 | case KVM_CAP_MP_STATE: |
1906 | case KVM_CAP_SYNC_MMU: | 1948 | case KVM_CAP_SYNC_MMU: |
1949 | case KVM_CAP_USER_NMI: | ||
1907 | case KVM_CAP_REINJECT_CONTROL: | 1950 | case KVM_CAP_REINJECT_CONTROL: |
1908 | case KVM_CAP_IRQ_INJECT_STATUS: | 1951 | case KVM_CAP_IRQ_INJECT_STATUS: |
1909 | case KVM_CAP_ASSIGN_DEV_IRQ: | 1952 | case KVM_CAP_ASSIGN_DEV_IRQ: |
@@ -1922,6 +1965,7 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
1922 | case KVM_CAP_DEBUGREGS: | 1965 | case KVM_CAP_DEBUGREGS: |
1923 | case KVM_CAP_X86_ROBUST_SINGLESTEP: | 1966 | case KVM_CAP_X86_ROBUST_SINGLESTEP: |
1924 | case KVM_CAP_XSAVE: | 1967 | case KVM_CAP_XSAVE: |
1968 | case KVM_CAP_ASYNC_PF: | ||
1925 | r = 1; | 1969 | r = 1; |
1926 | break; | 1970 | break; |
1927 | case KVM_CAP_COALESCED_MMIO: | 1971 | case KVM_CAP_COALESCED_MMIO: |
@@ -2185,6 +2229,11 @@ out: | |||
2185 | return r; | 2229 | return r; |
2186 | } | 2230 | } |
2187 | 2231 | ||
2232 | static void cpuid_mask(u32 *word, int wordnum) | ||
2233 | { | ||
2234 | *word &= boot_cpu_data.x86_capability[wordnum]; | ||
2235 | } | ||
2236 | |||
2188 | static void do_cpuid_1_ent(struct kvm_cpuid_entry2 *entry, u32 function, | 2237 | static void do_cpuid_1_ent(struct kvm_cpuid_entry2 *entry, u32 function, |
2189 | u32 index) | 2238 | u32 index) |
2190 | { | 2239 | { |
@@ -2259,7 +2308,9 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, | |||
2259 | break; | 2308 | break; |
2260 | case 1: | 2309 | case 1: |
2261 | entry->edx &= kvm_supported_word0_x86_features; | 2310 | entry->edx &= kvm_supported_word0_x86_features; |
2311 | cpuid_mask(&entry->edx, 0); | ||
2262 | entry->ecx &= kvm_supported_word4_x86_features; | 2312 | entry->ecx &= kvm_supported_word4_x86_features; |
2313 | cpuid_mask(&entry->ecx, 4); | ||
2263 | /* we support x2apic emulation even if host does not support | 2314 | /* we support x2apic emulation even if host does not support |
2264 | * it since we emulate x2apic in software */ | 2315 | * it since we emulate x2apic in software */ |
2265 | entry->ecx |= F(X2APIC); | 2316 | entry->ecx |= F(X2APIC); |
@@ -2350,7 +2401,9 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, | |||
2350 | break; | 2401 | break; |
2351 | case 0x80000001: | 2402 | case 0x80000001: |
2352 | entry->edx &= kvm_supported_word1_x86_features; | 2403 | entry->edx &= kvm_supported_word1_x86_features; |
2404 | cpuid_mask(&entry->edx, 1); | ||
2353 | entry->ecx &= kvm_supported_word6_x86_features; | 2405 | entry->ecx &= kvm_supported_word6_x86_features; |
2406 | cpuid_mask(&entry->ecx, 6); | ||
2354 | break; | 2407 | break; |
2355 | } | 2408 | } |
2356 | 2409 | ||
@@ -3169,20 +3222,18 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, | |||
3169 | struct kvm_memslots *slots, *old_slots; | 3222 | struct kvm_memslots *slots, *old_slots; |
3170 | unsigned long *dirty_bitmap; | 3223 | unsigned long *dirty_bitmap; |
3171 | 3224 | ||
3172 | r = -ENOMEM; | 3225 | dirty_bitmap = memslot->dirty_bitmap_head; |
3173 | dirty_bitmap = vmalloc(n); | 3226 | if (memslot->dirty_bitmap == dirty_bitmap) |
3174 | if (!dirty_bitmap) | 3227 | dirty_bitmap += n / sizeof(long); |
3175 | goto out; | ||
3176 | memset(dirty_bitmap, 0, n); | 3228 | memset(dirty_bitmap, 0, n); |
3177 | 3229 | ||
3178 | r = -ENOMEM; | 3230 | r = -ENOMEM; |
3179 | slots = kzalloc(sizeof(struct kvm_memslots), GFP_KERNEL); | 3231 | slots = kzalloc(sizeof(struct kvm_memslots), GFP_KERNEL); |
3180 | if (!slots) { | 3232 | if (!slots) |
3181 | vfree(dirty_bitmap); | ||
3182 | goto out; | 3233 | goto out; |
3183 | } | ||
3184 | memcpy(slots, kvm->memslots, sizeof(struct kvm_memslots)); | 3234 | memcpy(slots, kvm->memslots, sizeof(struct kvm_memslots)); |
3185 | slots->memslots[log->slot].dirty_bitmap = dirty_bitmap; | 3235 | slots->memslots[log->slot].dirty_bitmap = dirty_bitmap; |
3236 | slots->generation++; | ||
3186 | 3237 | ||
3187 | old_slots = kvm->memslots; | 3238 | old_slots = kvm->memslots; |
3188 | rcu_assign_pointer(kvm->memslots, slots); | 3239 | rcu_assign_pointer(kvm->memslots, slots); |
@@ -3195,11 +3246,8 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, | |||
3195 | spin_unlock(&kvm->mmu_lock); | 3246 | spin_unlock(&kvm->mmu_lock); |
3196 | 3247 | ||
3197 | r = -EFAULT; | 3248 | r = -EFAULT; |
3198 | if (copy_to_user(log->dirty_bitmap, dirty_bitmap, n)) { | 3249 | if (copy_to_user(log->dirty_bitmap, dirty_bitmap, n)) |
3199 | vfree(dirty_bitmap); | ||
3200 | goto out; | 3250 | goto out; |
3201 | } | ||
3202 | vfree(dirty_bitmap); | ||
3203 | } else { | 3251 | } else { |
3204 | r = -EFAULT; | 3252 | r = -EFAULT; |
3205 | if (clear_user(log->dirty_bitmap, n)) | 3253 | if (clear_user(log->dirty_bitmap, n)) |
@@ -3266,8 +3314,10 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
3266 | if (vpic) { | 3314 | if (vpic) { |
3267 | r = kvm_ioapic_init(kvm); | 3315 | r = kvm_ioapic_init(kvm); |
3268 | if (r) { | 3316 | if (r) { |
3317 | mutex_lock(&kvm->slots_lock); | ||
3269 | kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, | 3318 | kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, |
3270 | &vpic->dev); | 3319 | &vpic->dev); |
3320 | mutex_unlock(&kvm->slots_lock); | ||
3271 | kfree(vpic); | 3321 | kfree(vpic); |
3272 | goto create_irqchip_unlock; | 3322 | goto create_irqchip_unlock; |
3273 | } | 3323 | } |
@@ -3278,10 +3328,12 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
3278 | smp_wmb(); | 3328 | smp_wmb(); |
3279 | r = kvm_setup_default_irq_routing(kvm); | 3329 | r = kvm_setup_default_irq_routing(kvm); |
3280 | if (r) { | 3330 | if (r) { |
3331 | mutex_lock(&kvm->slots_lock); | ||
3281 | mutex_lock(&kvm->irq_lock); | 3332 | mutex_lock(&kvm->irq_lock); |
3282 | kvm_ioapic_destroy(kvm); | 3333 | kvm_ioapic_destroy(kvm); |
3283 | kvm_destroy_pic(kvm); | 3334 | kvm_destroy_pic(kvm); |
3284 | mutex_unlock(&kvm->irq_lock); | 3335 | mutex_unlock(&kvm->irq_lock); |
3336 | mutex_unlock(&kvm->slots_lock); | ||
3285 | } | 3337 | } |
3286 | create_irqchip_unlock: | 3338 | create_irqchip_unlock: |
3287 | mutex_unlock(&kvm->lock); | 3339 | mutex_unlock(&kvm->lock); |
@@ -3557,63 +3609,63 @@ static gpa_t translate_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u32 access) | |||
3557 | static gpa_t translate_nested_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u32 access) | 3609 | static gpa_t translate_nested_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u32 access) |
3558 | { | 3610 | { |
3559 | gpa_t t_gpa; | 3611 | gpa_t t_gpa; |
3560 | u32 error; | 3612 | struct x86_exception exception; |
3561 | 3613 | ||
3562 | BUG_ON(!mmu_is_nested(vcpu)); | 3614 | BUG_ON(!mmu_is_nested(vcpu)); |
3563 | 3615 | ||
3564 | /* NPT walks are always user-walks */ | 3616 | /* NPT walks are always user-walks */ |
3565 | access |= PFERR_USER_MASK; | 3617 | access |= PFERR_USER_MASK; |
3566 | t_gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, gpa, access, &error); | 3618 | t_gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, gpa, access, &exception); |
3567 | if (t_gpa == UNMAPPED_GVA) | ||
3568 | vcpu->arch.fault.nested = true; | ||
3569 | 3619 | ||
3570 | return t_gpa; | 3620 | return t_gpa; |
3571 | } | 3621 | } |
3572 | 3622 | ||
3573 | gpa_t kvm_mmu_gva_to_gpa_read(struct kvm_vcpu *vcpu, gva_t gva, u32 *error) | 3623 | gpa_t kvm_mmu_gva_to_gpa_read(struct kvm_vcpu *vcpu, gva_t gva, |
3624 | struct x86_exception *exception) | ||
3574 | { | 3625 | { |
3575 | u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0; | 3626 | u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0; |
3576 | return vcpu->arch.walk_mmu->gva_to_gpa(vcpu, gva, access, error); | 3627 | return vcpu->arch.walk_mmu->gva_to_gpa(vcpu, gva, access, exception); |
3577 | } | 3628 | } |
3578 | 3629 | ||
3579 | gpa_t kvm_mmu_gva_to_gpa_fetch(struct kvm_vcpu *vcpu, gva_t gva, u32 *error) | 3630 | gpa_t kvm_mmu_gva_to_gpa_fetch(struct kvm_vcpu *vcpu, gva_t gva, |
3631 | struct x86_exception *exception) | ||
3580 | { | 3632 | { |
3581 | u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0; | 3633 | u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0; |
3582 | access |= PFERR_FETCH_MASK; | 3634 | access |= PFERR_FETCH_MASK; |
3583 | return vcpu->arch.walk_mmu->gva_to_gpa(vcpu, gva, access, error); | 3635 | return vcpu->arch.walk_mmu->gva_to_gpa(vcpu, gva, access, exception); |
3584 | } | 3636 | } |
3585 | 3637 | ||
3586 | gpa_t kvm_mmu_gva_to_gpa_write(struct kvm_vcpu *vcpu, gva_t gva, u32 *error) | 3638 | gpa_t kvm_mmu_gva_to_gpa_write(struct kvm_vcpu *vcpu, gva_t gva, |
3639 | struct x86_exception *exception) | ||
3587 | { | 3640 | { |
3588 | u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0; | 3641 | u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0; |
3589 | access |= PFERR_WRITE_MASK; | 3642 | access |= PFERR_WRITE_MASK; |
3590 | return vcpu->arch.walk_mmu->gva_to_gpa(vcpu, gva, access, error); | 3643 | return vcpu->arch.walk_mmu->gva_to_gpa(vcpu, gva, access, exception); |
3591 | } | 3644 | } |
3592 | 3645 | ||
3593 | /* uses this to access any guest's mapped memory without checking CPL */ | 3646 | /* uses this to access any guest's mapped memory without checking CPL */ |
3594 | gpa_t kvm_mmu_gva_to_gpa_system(struct kvm_vcpu *vcpu, gva_t gva, u32 *error) | 3647 | gpa_t kvm_mmu_gva_to_gpa_system(struct kvm_vcpu *vcpu, gva_t gva, |
3648 | struct x86_exception *exception) | ||
3595 | { | 3649 | { |
3596 | return vcpu->arch.walk_mmu->gva_to_gpa(vcpu, gva, 0, error); | 3650 | return vcpu->arch.walk_mmu->gva_to_gpa(vcpu, gva, 0, exception); |
3597 | } | 3651 | } |
3598 | 3652 | ||
3599 | static int kvm_read_guest_virt_helper(gva_t addr, void *val, unsigned int bytes, | 3653 | static int kvm_read_guest_virt_helper(gva_t addr, void *val, unsigned int bytes, |
3600 | struct kvm_vcpu *vcpu, u32 access, | 3654 | struct kvm_vcpu *vcpu, u32 access, |
3601 | u32 *error) | 3655 | struct x86_exception *exception) |
3602 | { | 3656 | { |
3603 | void *data = val; | 3657 | void *data = val; |
3604 | int r = X86EMUL_CONTINUE; | 3658 | int r = X86EMUL_CONTINUE; |
3605 | 3659 | ||
3606 | while (bytes) { | 3660 | while (bytes) { |
3607 | gpa_t gpa = vcpu->arch.walk_mmu->gva_to_gpa(vcpu, addr, access, | 3661 | gpa_t gpa = vcpu->arch.walk_mmu->gva_to_gpa(vcpu, addr, access, |
3608 | error); | 3662 | exception); |
3609 | unsigned offset = addr & (PAGE_SIZE-1); | 3663 | unsigned offset = addr & (PAGE_SIZE-1); |
3610 | unsigned toread = min(bytes, (unsigned)PAGE_SIZE - offset); | 3664 | unsigned toread = min(bytes, (unsigned)PAGE_SIZE - offset); |
3611 | int ret; | 3665 | int ret; |
3612 | 3666 | ||
3613 | if (gpa == UNMAPPED_GVA) { | 3667 | if (gpa == UNMAPPED_GVA) |
3614 | r = X86EMUL_PROPAGATE_FAULT; | 3668 | return X86EMUL_PROPAGATE_FAULT; |
3615 | goto out; | ||
3616 | } | ||
3617 | ret = kvm_read_guest(vcpu->kvm, gpa, data, toread); | 3669 | ret = kvm_read_guest(vcpu->kvm, gpa, data, toread); |
3618 | if (ret < 0) { | 3670 | if (ret < 0) { |
3619 | r = X86EMUL_IO_NEEDED; | 3671 | r = X86EMUL_IO_NEEDED; |
@@ -3630,31 +3682,35 @@ out: | |||
3630 | 3682 | ||
3631 | /* used for instruction fetching */ | 3683 | /* used for instruction fetching */ |
3632 | static int kvm_fetch_guest_virt(gva_t addr, void *val, unsigned int bytes, | 3684 | static int kvm_fetch_guest_virt(gva_t addr, void *val, unsigned int bytes, |
3633 | struct kvm_vcpu *vcpu, u32 *error) | 3685 | struct kvm_vcpu *vcpu, |
3686 | struct x86_exception *exception) | ||
3634 | { | 3687 | { |
3635 | u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0; | 3688 | u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0; |
3636 | return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, | 3689 | return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, |
3637 | access | PFERR_FETCH_MASK, error); | 3690 | access | PFERR_FETCH_MASK, |
3691 | exception); | ||
3638 | } | 3692 | } |
3639 | 3693 | ||
3640 | static int kvm_read_guest_virt(gva_t addr, void *val, unsigned int bytes, | 3694 | static int kvm_read_guest_virt(gva_t addr, void *val, unsigned int bytes, |
3641 | struct kvm_vcpu *vcpu, u32 *error) | 3695 | struct kvm_vcpu *vcpu, |
3696 | struct x86_exception *exception) | ||
3642 | { | 3697 | { |
3643 | u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0; | 3698 | u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0; |
3644 | return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, access, | 3699 | return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, access, |
3645 | error); | 3700 | exception); |
3646 | } | 3701 | } |
3647 | 3702 | ||
3648 | static int kvm_read_guest_virt_system(gva_t addr, void *val, unsigned int bytes, | 3703 | static int kvm_read_guest_virt_system(gva_t addr, void *val, unsigned int bytes, |
3649 | struct kvm_vcpu *vcpu, u32 *error) | 3704 | struct kvm_vcpu *vcpu, |
3705 | struct x86_exception *exception) | ||
3650 | { | 3706 | { |
3651 | return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, 0, error); | 3707 | return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, 0, exception); |
3652 | } | 3708 | } |
3653 | 3709 | ||
3654 | static int kvm_write_guest_virt_system(gva_t addr, void *val, | 3710 | static int kvm_write_guest_virt_system(gva_t addr, void *val, |
3655 | unsigned int bytes, | 3711 | unsigned int bytes, |
3656 | struct kvm_vcpu *vcpu, | 3712 | struct kvm_vcpu *vcpu, |
3657 | u32 *error) | 3713 | struct x86_exception *exception) |
3658 | { | 3714 | { |
3659 | void *data = val; | 3715 | void *data = val; |
3660 | int r = X86EMUL_CONTINUE; | 3716 | int r = X86EMUL_CONTINUE; |
@@ -3662,15 +3718,13 @@ static int kvm_write_guest_virt_system(gva_t addr, void *val, | |||
3662 | while (bytes) { | 3718 | while (bytes) { |
3663 | gpa_t gpa = vcpu->arch.walk_mmu->gva_to_gpa(vcpu, addr, | 3719 | gpa_t gpa = vcpu->arch.walk_mmu->gva_to_gpa(vcpu, addr, |
3664 | PFERR_WRITE_MASK, | 3720 | PFERR_WRITE_MASK, |
3665 | error); | 3721 | exception); |
3666 | unsigned offset = addr & (PAGE_SIZE-1); | 3722 | unsigned offset = addr & (PAGE_SIZE-1); |
3667 | unsigned towrite = min(bytes, (unsigned)PAGE_SIZE - offset); | 3723 | unsigned towrite = min(bytes, (unsigned)PAGE_SIZE - offset); |
3668 | int ret; | 3724 | int ret; |
3669 | 3725 | ||
3670 | if (gpa == UNMAPPED_GVA) { | 3726 | if (gpa == UNMAPPED_GVA) |
3671 | r = X86EMUL_PROPAGATE_FAULT; | 3727 | return X86EMUL_PROPAGATE_FAULT; |
3672 | goto out; | ||
3673 | } | ||
3674 | ret = kvm_write_guest(vcpu->kvm, gpa, data, towrite); | 3728 | ret = kvm_write_guest(vcpu->kvm, gpa, data, towrite); |
3675 | if (ret < 0) { | 3729 | if (ret < 0) { |
3676 | r = X86EMUL_IO_NEEDED; | 3730 | r = X86EMUL_IO_NEEDED; |
@@ -3688,7 +3742,7 @@ out: | |||
3688 | static int emulator_read_emulated(unsigned long addr, | 3742 | static int emulator_read_emulated(unsigned long addr, |
3689 | void *val, | 3743 | void *val, |
3690 | unsigned int bytes, | 3744 | unsigned int bytes, |
3691 | unsigned int *error_code, | 3745 | struct x86_exception *exception, |
3692 | struct kvm_vcpu *vcpu) | 3746 | struct kvm_vcpu *vcpu) |
3693 | { | 3747 | { |
3694 | gpa_t gpa; | 3748 | gpa_t gpa; |
@@ -3701,7 +3755,7 @@ static int emulator_read_emulated(unsigned long addr, | |||
3701 | return X86EMUL_CONTINUE; | 3755 | return X86EMUL_CONTINUE; |
3702 | } | 3756 | } |
3703 | 3757 | ||
3704 | gpa = kvm_mmu_gva_to_gpa_read(vcpu, addr, error_code); | 3758 | gpa = kvm_mmu_gva_to_gpa_read(vcpu, addr, exception); |
3705 | 3759 | ||
3706 | if (gpa == UNMAPPED_GVA) | 3760 | if (gpa == UNMAPPED_GVA) |
3707 | return X86EMUL_PROPAGATE_FAULT; | 3761 | return X86EMUL_PROPAGATE_FAULT; |
@@ -3710,8 +3764,8 @@ static int emulator_read_emulated(unsigned long addr, | |||
3710 | if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE) | 3764 | if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE) |
3711 | goto mmio; | 3765 | goto mmio; |
3712 | 3766 | ||
3713 | if (kvm_read_guest_virt(addr, val, bytes, vcpu, NULL) | 3767 | if (kvm_read_guest_virt(addr, val, bytes, vcpu, exception) |
3714 | == X86EMUL_CONTINUE) | 3768 | == X86EMUL_CONTINUE) |
3715 | return X86EMUL_CONTINUE; | 3769 | return X86EMUL_CONTINUE; |
3716 | 3770 | ||
3717 | mmio: | 3771 | mmio: |
@@ -3735,7 +3789,7 @@ mmio: | |||
3735 | } | 3789 | } |
3736 | 3790 | ||
3737 | int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa, | 3791 | int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa, |
3738 | const void *val, int bytes) | 3792 | const void *val, int bytes) |
3739 | { | 3793 | { |
3740 | int ret; | 3794 | int ret; |
3741 | 3795 | ||
@@ -3749,12 +3803,12 @@ int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa, | |||
3749 | static int emulator_write_emulated_onepage(unsigned long addr, | 3803 | static int emulator_write_emulated_onepage(unsigned long addr, |
3750 | const void *val, | 3804 | const void *val, |
3751 | unsigned int bytes, | 3805 | unsigned int bytes, |
3752 | unsigned int *error_code, | 3806 | struct x86_exception *exception, |
3753 | struct kvm_vcpu *vcpu) | 3807 | struct kvm_vcpu *vcpu) |
3754 | { | 3808 | { |
3755 | gpa_t gpa; | 3809 | gpa_t gpa; |
3756 | 3810 | ||
3757 | gpa = kvm_mmu_gva_to_gpa_write(vcpu, addr, error_code); | 3811 | gpa = kvm_mmu_gva_to_gpa_write(vcpu, addr, exception); |
3758 | 3812 | ||
3759 | if (gpa == UNMAPPED_GVA) | 3813 | if (gpa == UNMAPPED_GVA) |
3760 | return X86EMUL_PROPAGATE_FAULT; | 3814 | return X86EMUL_PROPAGATE_FAULT; |
@@ -3787,7 +3841,7 @@ mmio: | |||
3787 | int emulator_write_emulated(unsigned long addr, | 3841 | int emulator_write_emulated(unsigned long addr, |
3788 | const void *val, | 3842 | const void *val, |
3789 | unsigned int bytes, | 3843 | unsigned int bytes, |
3790 | unsigned int *error_code, | 3844 | struct x86_exception *exception, |
3791 | struct kvm_vcpu *vcpu) | 3845 | struct kvm_vcpu *vcpu) |
3792 | { | 3846 | { |
3793 | /* Crossing a page boundary? */ | 3847 | /* Crossing a page boundary? */ |
@@ -3795,7 +3849,7 @@ int emulator_write_emulated(unsigned long addr, | |||
3795 | int rc, now; | 3849 | int rc, now; |
3796 | 3850 | ||
3797 | now = -addr & ~PAGE_MASK; | 3851 | now = -addr & ~PAGE_MASK; |
3798 | rc = emulator_write_emulated_onepage(addr, val, now, error_code, | 3852 | rc = emulator_write_emulated_onepage(addr, val, now, exception, |
3799 | vcpu); | 3853 | vcpu); |
3800 | if (rc != X86EMUL_CONTINUE) | 3854 | if (rc != X86EMUL_CONTINUE) |
3801 | return rc; | 3855 | return rc; |
@@ -3803,7 +3857,7 @@ int emulator_write_emulated(unsigned long addr, | |||
3803 | val += now; | 3857 | val += now; |
3804 | bytes -= now; | 3858 | bytes -= now; |
3805 | } | 3859 | } |
3806 | return emulator_write_emulated_onepage(addr, val, bytes, error_code, | 3860 | return emulator_write_emulated_onepage(addr, val, bytes, exception, |
3807 | vcpu); | 3861 | vcpu); |
3808 | } | 3862 | } |
3809 | 3863 | ||
@@ -3821,7 +3875,7 @@ static int emulator_cmpxchg_emulated(unsigned long addr, | |||
3821 | const void *old, | 3875 | const void *old, |
3822 | const void *new, | 3876 | const void *new, |
3823 | unsigned int bytes, | 3877 | unsigned int bytes, |
3824 | unsigned int *error_code, | 3878 | struct x86_exception *exception, |
3825 | struct kvm_vcpu *vcpu) | 3879 | struct kvm_vcpu *vcpu) |
3826 | { | 3880 | { |
3827 | gpa_t gpa; | 3881 | gpa_t gpa; |
@@ -3879,7 +3933,7 @@ static int emulator_cmpxchg_emulated(unsigned long addr, | |||
3879 | emul_write: | 3933 | emul_write: |
3880 | printk_once(KERN_WARNING "kvm: emulating exchange as write\n"); | 3934 | printk_once(KERN_WARNING "kvm: emulating exchange as write\n"); |
3881 | 3935 | ||
3882 | return emulator_write_emulated(addr, new, bytes, error_code, vcpu); | 3936 | return emulator_write_emulated(addr, new, bytes, exception, vcpu); |
3883 | } | 3937 | } |
3884 | 3938 | ||
3885 | static int kernel_pio(struct kvm_vcpu *vcpu, void *pd) | 3939 | static int kernel_pio(struct kvm_vcpu *vcpu, void *pd) |
@@ -3904,7 +3958,7 @@ static int emulator_pio_in_emulated(int size, unsigned short port, void *val, | |||
3904 | if (vcpu->arch.pio.count) | 3958 | if (vcpu->arch.pio.count) |
3905 | goto data_avail; | 3959 | goto data_avail; |
3906 | 3960 | ||
3907 | trace_kvm_pio(0, port, size, 1); | 3961 | trace_kvm_pio(0, port, size, count); |
3908 | 3962 | ||
3909 | vcpu->arch.pio.port = port; | 3963 | vcpu->arch.pio.port = port; |
3910 | vcpu->arch.pio.in = 1; | 3964 | vcpu->arch.pio.in = 1; |
@@ -3932,7 +3986,7 @@ static int emulator_pio_out_emulated(int size, unsigned short port, | |||
3932 | const void *val, unsigned int count, | 3986 | const void *val, unsigned int count, |
3933 | struct kvm_vcpu *vcpu) | 3987 | struct kvm_vcpu *vcpu) |
3934 | { | 3988 | { |
3935 | trace_kvm_pio(1, port, size, 1); | 3989 | trace_kvm_pio(1, port, size, count); |
3936 | 3990 | ||
3937 | vcpu->arch.pio.port = port; | 3991 | vcpu->arch.pio.port = port; |
3938 | vcpu->arch.pio.in = 0; | 3992 | vcpu->arch.pio.in = 0; |
@@ -3973,13 +4027,15 @@ int kvm_emulate_wbinvd(struct kvm_vcpu *vcpu) | |||
3973 | return X86EMUL_CONTINUE; | 4027 | return X86EMUL_CONTINUE; |
3974 | 4028 | ||
3975 | if (kvm_x86_ops->has_wbinvd_exit()) { | 4029 | if (kvm_x86_ops->has_wbinvd_exit()) { |
3976 | preempt_disable(); | 4030 | int cpu = get_cpu(); |
4031 | |||
4032 | cpumask_set_cpu(cpu, vcpu->arch.wbinvd_dirty_mask); | ||
3977 | smp_call_function_many(vcpu->arch.wbinvd_dirty_mask, | 4033 | smp_call_function_many(vcpu->arch.wbinvd_dirty_mask, |
3978 | wbinvd_ipi, NULL, 1); | 4034 | wbinvd_ipi, NULL, 1); |
3979 | preempt_enable(); | 4035 | put_cpu(); |
3980 | cpumask_clear(vcpu->arch.wbinvd_dirty_mask); | 4036 | cpumask_clear(vcpu->arch.wbinvd_dirty_mask); |
3981 | } | 4037 | } else |
3982 | wbinvd(); | 4038 | wbinvd(); |
3983 | return X86EMUL_CONTINUE; | 4039 | return X86EMUL_CONTINUE; |
3984 | } | 4040 | } |
3985 | EXPORT_SYMBOL_GPL(kvm_emulate_wbinvd); | 4041 | EXPORT_SYMBOL_GPL(kvm_emulate_wbinvd); |
@@ -4019,7 +4075,7 @@ static unsigned long emulator_get_cr(int cr, struct kvm_vcpu *vcpu) | |||
4019 | value = vcpu->arch.cr2; | 4075 | value = vcpu->arch.cr2; |
4020 | break; | 4076 | break; |
4021 | case 3: | 4077 | case 3: |
4022 | value = vcpu->arch.cr3; | 4078 | value = kvm_read_cr3(vcpu); |
4023 | break; | 4079 | break; |
4024 | case 4: | 4080 | case 4: |
4025 | value = kvm_read_cr4(vcpu); | 4081 | value = kvm_read_cr4(vcpu); |
@@ -4053,7 +4109,7 @@ static int emulator_set_cr(int cr, unsigned long val, struct kvm_vcpu *vcpu) | |||
4053 | res = kvm_set_cr4(vcpu, mk_cr_64(kvm_read_cr4(vcpu), val)); | 4109 | res = kvm_set_cr4(vcpu, mk_cr_64(kvm_read_cr4(vcpu), val)); |
4054 | break; | 4110 | break; |
4055 | case 8: | 4111 | case 8: |
4056 | res = __kvm_set_cr8(vcpu, val & 0xfUL); | 4112 | res = kvm_set_cr8(vcpu, val); |
4057 | break; | 4113 | break; |
4058 | default: | 4114 | default: |
4059 | vcpu_printf(vcpu, "%s: unexpected cr %u\n", __func__, cr); | 4115 | vcpu_printf(vcpu, "%s: unexpected cr %u\n", __func__, cr); |
@@ -4206,12 +4262,13 @@ static void toggle_interruptibility(struct kvm_vcpu *vcpu, u32 mask) | |||
4206 | static void inject_emulated_exception(struct kvm_vcpu *vcpu) | 4262 | static void inject_emulated_exception(struct kvm_vcpu *vcpu) |
4207 | { | 4263 | { |
4208 | struct x86_emulate_ctxt *ctxt = &vcpu->arch.emulate_ctxt; | 4264 | struct x86_emulate_ctxt *ctxt = &vcpu->arch.emulate_ctxt; |
4209 | if (ctxt->exception == PF_VECTOR) | 4265 | if (ctxt->exception.vector == PF_VECTOR) |
4210 | kvm_propagate_fault(vcpu); | 4266 | kvm_propagate_fault(vcpu, &ctxt->exception); |
4211 | else if (ctxt->error_code_valid) | 4267 | else if (ctxt->exception.error_code_valid) |
4212 | kvm_queue_exception_e(vcpu, ctxt->exception, ctxt->error_code); | 4268 | kvm_queue_exception_e(vcpu, ctxt->exception.vector, |
4269 | ctxt->exception.error_code); | ||
4213 | else | 4270 | else |
4214 | kvm_queue_exception(vcpu, ctxt->exception); | 4271 | kvm_queue_exception(vcpu, ctxt->exception.vector); |
4215 | } | 4272 | } |
4216 | 4273 | ||
4217 | static void init_emulate_ctxt(struct kvm_vcpu *vcpu) | 4274 | static void init_emulate_ctxt(struct kvm_vcpu *vcpu) |
@@ -4267,13 +4324,19 @@ EXPORT_SYMBOL_GPL(kvm_inject_realmode_interrupt); | |||
4267 | 4324 | ||
4268 | static int handle_emulation_failure(struct kvm_vcpu *vcpu) | 4325 | static int handle_emulation_failure(struct kvm_vcpu *vcpu) |
4269 | { | 4326 | { |
4327 | int r = EMULATE_DONE; | ||
4328 | |||
4270 | ++vcpu->stat.insn_emulation_fail; | 4329 | ++vcpu->stat.insn_emulation_fail; |
4271 | trace_kvm_emulate_insn_failed(vcpu); | 4330 | trace_kvm_emulate_insn_failed(vcpu); |
4272 | vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; | 4331 | if (!is_guest_mode(vcpu)) { |
4273 | vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION; | 4332 | vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; |
4274 | vcpu->run->internal.ndata = 0; | 4333 | vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION; |
4334 | vcpu->run->internal.ndata = 0; | ||
4335 | r = EMULATE_FAIL; | ||
4336 | } | ||
4275 | kvm_queue_exception(vcpu, UD_VECTOR); | 4337 | kvm_queue_exception(vcpu, UD_VECTOR); |
4276 | return EMULATE_FAIL; | 4338 | |
4339 | return r; | ||
4277 | } | 4340 | } |
4278 | 4341 | ||
4279 | static bool reexecute_instruction(struct kvm_vcpu *vcpu, gva_t gva) | 4342 | static bool reexecute_instruction(struct kvm_vcpu *vcpu, gva_t gva) |
@@ -4302,10 +4365,11 @@ static bool reexecute_instruction(struct kvm_vcpu *vcpu, gva_t gva) | |||
4302 | return false; | 4365 | return false; |
4303 | } | 4366 | } |
4304 | 4367 | ||
4305 | int emulate_instruction(struct kvm_vcpu *vcpu, | 4368 | int x86_emulate_instruction(struct kvm_vcpu *vcpu, |
4306 | unsigned long cr2, | 4369 | unsigned long cr2, |
4307 | u16 error_code, | 4370 | int emulation_type, |
4308 | int emulation_type) | 4371 | void *insn, |
4372 | int insn_len) | ||
4309 | { | 4373 | { |
4310 | int r; | 4374 | int r; |
4311 | struct decode_cache *c = &vcpu->arch.emulate_ctxt.decode; | 4375 | struct decode_cache *c = &vcpu->arch.emulate_ctxt.decode; |
@@ -4323,10 +4387,10 @@ int emulate_instruction(struct kvm_vcpu *vcpu, | |||
4323 | if (!(emulation_type & EMULTYPE_NO_DECODE)) { | 4387 | if (!(emulation_type & EMULTYPE_NO_DECODE)) { |
4324 | init_emulate_ctxt(vcpu); | 4388 | init_emulate_ctxt(vcpu); |
4325 | vcpu->arch.emulate_ctxt.interruptibility = 0; | 4389 | vcpu->arch.emulate_ctxt.interruptibility = 0; |
4326 | vcpu->arch.emulate_ctxt.exception = -1; | 4390 | vcpu->arch.emulate_ctxt.have_exception = false; |
4327 | vcpu->arch.emulate_ctxt.perm_ok = false; | 4391 | vcpu->arch.emulate_ctxt.perm_ok = false; |
4328 | 4392 | ||
4329 | r = x86_decode_insn(&vcpu->arch.emulate_ctxt); | 4393 | r = x86_decode_insn(&vcpu->arch.emulate_ctxt, insn, insn_len); |
4330 | if (r == X86EMUL_PROPAGATE_FAULT) | 4394 | if (r == X86EMUL_PROPAGATE_FAULT) |
4331 | goto done; | 4395 | goto done; |
4332 | 4396 | ||
@@ -4389,7 +4453,7 @@ restart: | |||
4389 | } | 4453 | } |
4390 | 4454 | ||
4391 | done: | 4455 | done: |
4392 | if (vcpu->arch.emulate_ctxt.exception >= 0) { | 4456 | if (vcpu->arch.emulate_ctxt.have_exception) { |
4393 | inject_emulated_exception(vcpu); | 4457 | inject_emulated_exception(vcpu); |
4394 | r = EMULATE_DONE; | 4458 | r = EMULATE_DONE; |
4395 | } else if (vcpu->arch.pio.count) { | 4459 | } else if (vcpu->arch.pio.count) { |
@@ -4413,7 +4477,7 @@ done: | |||
4413 | 4477 | ||
4414 | return r; | 4478 | return r; |
4415 | } | 4479 | } |
4416 | EXPORT_SYMBOL_GPL(emulate_instruction); | 4480 | EXPORT_SYMBOL_GPL(x86_emulate_instruction); |
4417 | 4481 | ||
4418 | int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, unsigned short port) | 4482 | int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, unsigned short port) |
4419 | { | 4483 | { |
@@ -4653,7 +4717,6 @@ int kvm_arch_init(void *opaque) | |||
4653 | 4717 | ||
4654 | kvm_x86_ops = ops; | 4718 | kvm_x86_ops = ops; |
4655 | kvm_mmu_set_nonpresent_ptes(0ull, 0ull); | 4719 | kvm_mmu_set_nonpresent_ptes(0ull, 0ull); |
4656 | kvm_mmu_set_base_ptes(PT_PRESENT_MASK); | ||
4657 | kvm_mmu_set_mask_ptes(PT_USER_MASK, PT_ACCESSED_MASK, | 4720 | kvm_mmu_set_mask_ptes(PT_USER_MASK, PT_ACCESSED_MASK, |
4658 | PT_DIRTY_MASK, PT64_NX_MASK, 0); | 4721 | PT_DIRTY_MASK, PT64_NX_MASK, 0); |
4659 | 4722 | ||
@@ -5116,6 +5179,12 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) | |||
5116 | vcpu->fpu_active = 0; | 5179 | vcpu->fpu_active = 0; |
5117 | kvm_x86_ops->fpu_deactivate(vcpu); | 5180 | kvm_x86_ops->fpu_deactivate(vcpu); |
5118 | } | 5181 | } |
5182 | if (kvm_check_request(KVM_REQ_APF_HALT, vcpu)) { | ||
5183 | /* Page is swapped out. Do synthetic halt */ | ||
5184 | vcpu->arch.apf.halted = true; | ||
5185 | r = 1; | ||
5186 | goto out; | ||
5187 | } | ||
5119 | } | 5188 | } |
5120 | 5189 | ||
5121 | r = kvm_mmu_reload(vcpu); | 5190 | r = kvm_mmu_reload(vcpu); |
@@ -5244,7 +5313,8 @@ static int __vcpu_run(struct kvm_vcpu *vcpu) | |||
5244 | 5313 | ||
5245 | r = 1; | 5314 | r = 1; |
5246 | while (r > 0) { | 5315 | while (r > 0) { |
5247 | if (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE) | 5316 | if (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE && |
5317 | !vcpu->arch.apf.halted) | ||
5248 | r = vcpu_enter_guest(vcpu); | 5318 | r = vcpu_enter_guest(vcpu); |
5249 | else { | 5319 | else { |
5250 | srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx); | 5320 | srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx); |
@@ -5257,6 +5327,7 @@ static int __vcpu_run(struct kvm_vcpu *vcpu) | |||
5257 | vcpu->arch.mp_state = | 5327 | vcpu->arch.mp_state = |
5258 | KVM_MP_STATE_RUNNABLE; | 5328 | KVM_MP_STATE_RUNNABLE; |
5259 | case KVM_MP_STATE_RUNNABLE: | 5329 | case KVM_MP_STATE_RUNNABLE: |
5330 | vcpu->arch.apf.halted = false; | ||
5260 | break; | 5331 | break; |
5261 | case KVM_MP_STATE_SIPI_RECEIVED: | 5332 | case KVM_MP_STATE_SIPI_RECEIVED: |
5262 | default: | 5333 | default: |
@@ -5278,6 +5349,9 @@ static int __vcpu_run(struct kvm_vcpu *vcpu) | |||
5278 | vcpu->run->exit_reason = KVM_EXIT_INTR; | 5349 | vcpu->run->exit_reason = KVM_EXIT_INTR; |
5279 | ++vcpu->stat.request_irq_exits; | 5350 | ++vcpu->stat.request_irq_exits; |
5280 | } | 5351 | } |
5352 | |||
5353 | kvm_check_async_pf_completion(vcpu); | ||
5354 | |||
5281 | if (signal_pending(current)) { | 5355 | if (signal_pending(current)) { |
5282 | r = -EINTR; | 5356 | r = -EINTR; |
5283 | vcpu->run->exit_reason = KVM_EXIT_INTR; | 5357 | vcpu->run->exit_reason = KVM_EXIT_INTR; |
@@ -5302,6 +5376,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
5302 | int r; | 5376 | int r; |
5303 | sigset_t sigsaved; | 5377 | sigset_t sigsaved; |
5304 | 5378 | ||
5379 | if (!tsk_used_math(current) && init_fpu(current)) | ||
5380 | return -ENOMEM; | ||
5381 | |||
5305 | if (vcpu->sigset_active) | 5382 | if (vcpu->sigset_active) |
5306 | sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved); | 5383 | sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved); |
5307 | 5384 | ||
@@ -5313,8 +5390,12 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
5313 | } | 5390 | } |
5314 | 5391 | ||
5315 | /* re-sync apic's tpr */ | 5392 | /* re-sync apic's tpr */ |
5316 | if (!irqchip_in_kernel(vcpu->kvm)) | 5393 | if (!irqchip_in_kernel(vcpu->kvm)) { |
5317 | kvm_set_cr8(vcpu, kvm_run->cr8); | 5394 | if (kvm_set_cr8(vcpu, kvm_run->cr8) != 0) { |
5395 | r = -EINVAL; | ||
5396 | goto out; | ||
5397 | } | ||
5398 | } | ||
5318 | 5399 | ||
5319 | if (vcpu->arch.pio.count || vcpu->mmio_needed) { | 5400 | if (vcpu->arch.pio.count || vcpu->mmio_needed) { |
5320 | if (vcpu->mmio_needed) { | 5401 | if (vcpu->mmio_needed) { |
@@ -5323,7 +5404,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
5323 | vcpu->mmio_needed = 0; | 5404 | vcpu->mmio_needed = 0; |
5324 | } | 5405 | } |
5325 | vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); | 5406 | vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); |
5326 | r = emulate_instruction(vcpu, 0, 0, EMULTYPE_NO_DECODE); | 5407 | r = emulate_instruction(vcpu, EMULTYPE_NO_DECODE); |
5327 | srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx); | 5408 | srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx); |
5328 | if (r != EMULATE_DONE) { | 5409 | if (r != EMULATE_DONE) { |
5329 | r = 0; | 5410 | r = 0; |
@@ -5436,7 +5517,7 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, | |||
5436 | 5517 | ||
5437 | sregs->cr0 = kvm_read_cr0(vcpu); | 5518 | sregs->cr0 = kvm_read_cr0(vcpu); |
5438 | sregs->cr2 = vcpu->arch.cr2; | 5519 | sregs->cr2 = vcpu->arch.cr2; |
5439 | sregs->cr3 = vcpu->arch.cr3; | 5520 | sregs->cr3 = kvm_read_cr3(vcpu); |
5440 | sregs->cr4 = kvm_read_cr4(vcpu); | 5521 | sregs->cr4 = kvm_read_cr4(vcpu); |
5441 | sregs->cr8 = kvm_get_cr8(vcpu); | 5522 | sregs->cr8 = kvm_get_cr8(vcpu); |
5442 | sregs->efer = vcpu->arch.efer; | 5523 | sregs->efer = vcpu->arch.efer; |
@@ -5504,8 +5585,9 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, | |||
5504 | kvm_x86_ops->set_gdt(vcpu, &dt); | 5585 | kvm_x86_ops->set_gdt(vcpu, &dt); |
5505 | 5586 | ||
5506 | vcpu->arch.cr2 = sregs->cr2; | 5587 | vcpu->arch.cr2 = sregs->cr2; |
5507 | mmu_reset_needed |= vcpu->arch.cr3 != sregs->cr3; | 5588 | mmu_reset_needed |= kvm_read_cr3(vcpu) != sregs->cr3; |
5508 | vcpu->arch.cr3 = sregs->cr3; | 5589 | vcpu->arch.cr3 = sregs->cr3; |
5590 | __set_bit(VCPU_EXREG_CR3, (ulong *)&vcpu->arch.regs_avail); | ||
5509 | 5591 | ||
5510 | kvm_set_cr8(vcpu, sregs->cr8); | 5592 | kvm_set_cr8(vcpu, sregs->cr8); |
5511 | 5593 | ||
@@ -5522,7 +5604,7 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, | |||
5522 | if (sregs->cr4 & X86_CR4_OSXSAVE) | 5604 | if (sregs->cr4 & X86_CR4_OSXSAVE) |
5523 | update_cpuid(vcpu); | 5605 | update_cpuid(vcpu); |
5524 | if (!is_long_mode(vcpu) && is_pae(vcpu)) { | 5606 | if (!is_long_mode(vcpu) && is_pae(vcpu)) { |
5525 | load_pdptrs(vcpu, vcpu->arch.walk_mmu, vcpu->arch.cr3); | 5607 | load_pdptrs(vcpu, vcpu->arch.walk_mmu, kvm_read_cr3(vcpu)); |
5526 | mmu_reset_needed = 1; | 5608 | mmu_reset_needed = 1; |
5527 | } | 5609 | } |
5528 | 5610 | ||
@@ -5773,6 +5855,8 @@ free_vcpu: | |||
5773 | 5855 | ||
5774 | void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) | 5856 | void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) |
5775 | { | 5857 | { |
5858 | vcpu->arch.apf.msr_val = 0; | ||
5859 | |||
5776 | vcpu_load(vcpu); | 5860 | vcpu_load(vcpu); |
5777 | kvm_mmu_unload(vcpu); | 5861 | kvm_mmu_unload(vcpu); |
5778 | vcpu_put(vcpu); | 5862 | vcpu_put(vcpu); |
@@ -5792,6 +5876,11 @@ int kvm_arch_vcpu_reset(struct kvm_vcpu *vcpu) | |||
5792 | vcpu->arch.dr7 = DR7_FIXED_1; | 5876 | vcpu->arch.dr7 = DR7_FIXED_1; |
5793 | 5877 | ||
5794 | kvm_make_request(KVM_REQ_EVENT, vcpu); | 5878 | kvm_make_request(KVM_REQ_EVENT, vcpu); |
5879 | vcpu->arch.apf.msr_val = 0; | ||
5880 | |||
5881 | kvm_clear_async_pf_completion_queue(vcpu); | ||
5882 | kvm_async_pf_hash_reset(vcpu); | ||
5883 | vcpu->arch.apf.halted = false; | ||
5795 | 5884 | ||
5796 | return kvm_x86_ops->vcpu_reset(vcpu); | 5885 | return kvm_x86_ops->vcpu_reset(vcpu); |
5797 | } | 5886 | } |
@@ -5881,6 +5970,8 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) | |||
5881 | if (!zalloc_cpumask_var(&vcpu->arch.wbinvd_dirty_mask, GFP_KERNEL)) | 5970 | if (!zalloc_cpumask_var(&vcpu->arch.wbinvd_dirty_mask, GFP_KERNEL)) |
5882 | goto fail_free_mce_banks; | 5971 | goto fail_free_mce_banks; |
5883 | 5972 | ||
5973 | kvm_async_pf_hash_reset(vcpu); | ||
5974 | |||
5884 | return 0; | 5975 | return 0; |
5885 | fail_free_mce_banks: | 5976 | fail_free_mce_banks: |
5886 | kfree(vcpu->arch.mce_banks); | 5977 | kfree(vcpu->arch.mce_banks); |
@@ -5906,13 +5997,8 @@ void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) | |||
5906 | free_page((unsigned long)vcpu->arch.pio_data); | 5997 | free_page((unsigned long)vcpu->arch.pio_data); |
5907 | } | 5998 | } |
5908 | 5999 | ||
5909 | struct kvm *kvm_arch_create_vm(void) | 6000 | int kvm_arch_init_vm(struct kvm *kvm) |
5910 | { | 6001 | { |
5911 | struct kvm *kvm = kzalloc(sizeof(struct kvm), GFP_KERNEL); | ||
5912 | |||
5913 | if (!kvm) | ||
5914 | return ERR_PTR(-ENOMEM); | ||
5915 | |||
5916 | INIT_LIST_HEAD(&kvm->arch.active_mmu_pages); | 6002 | INIT_LIST_HEAD(&kvm->arch.active_mmu_pages); |
5917 | INIT_LIST_HEAD(&kvm->arch.assigned_dev_head); | 6003 | INIT_LIST_HEAD(&kvm->arch.assigned_dev_head); |
5918 | 6004 | ||
@@ -5921,7 +6007,7 @@ struct kvm *kvm_arch_create_vm(void) | |||
5921 | 6007 | ||
5922 | spin_lock_init(&kvm->arch.tsc_write_lock); | 6008 | spin_lock_init(&kvm->arch.tsc_write_lock); |
5923 | 6009 | ||
5924 | return kvm; | 6010 | return 0; |
5925 | } | 6011 | } |
5926 | 6012 | ||
5927 | static void kvm_unload_vcpu_mmu(struct kvm_vcpu *vcpu) | 6013 | static void kvm_unload_vcpu_mmu(struct kvm_vcpu *vcpu) |
@@ -5939,8 +6025,10 @@ static void kvm_free_vcpus(struct kvm *kvm) | |||
5939 | /* | 6025 | /* |
5940 | * Unpin any mmu pages first. | 6026 | * Unpin any mmu pages first. |
5941 | */ | 6027 | */ |
5942 | kvm_for_each_vcpu(i, vcpu, kvm) | 6028 | kvm_for_each_vcpu(i, vcpu, kvm) { |
6029 | kvm_clear_async_pf_completion_queue(vcpu); | ||
5943 | kvm_unload_vcpu_mmu(vcpu); | 6030 | kvm_unload_vcpu_mmu(vcpu); |
6031 | } | ||
5944 | kvm_for_each_vcpu(i, vcpu, kvm) | 6032 | kvm_for_each_vcpu(i, vcpu, kvm) |
5945 | kvm_arch_vcpu_free(vcpu); | 6033 | kvm_arch_vcpu_free(vcpu); |
5946 | 6034 | ||
@@ -5964,13 +6052,10 @@ void kvm_arch_destroy_vm(struct kvm *kvm) | |||
5964 | kfree(kvm->arch.vpic); | 6052 | kfree(kvm->arch.vpic); |
5965 | kfree(kvm->arch.vioapic); | 6053 | kfree(kvm->arch.vioapic); |
5966 | kvm_free_vcpus(kvm); | 6054 | kvm_free_vcpus(kvm); |
5967 | kvm_free_physmem(kvm); | ||
5968 | if (kvm->arch.apic_access_page) | 6055 | if (kvm->arch.apic_access_page) |
5969 | put_page(kvm->arch.apic_access_page); | 6056 | put_page(kvm->arch.apic_access_page); |
5970 | if (kvm->arch.ept_identity_pagetable) | 6057 | if (kvm->arch.ept_identity_pagetable) |
5971 | put_page(kvm->arch.ept_identity_pagetable); | 6058 | put_page(kvm->arch.ept_identity_pagetable); |
5972 | cleanup_srcu_struct(&kvm->srcu); | ||
5973 | kfree(kvm); | ||
5974 | } | 6059 | } |
5975 | 6060 | ||
5976 | int kvm_arch_prepare_memory_region(struct kvm *kvm, | 6061 | int kvm_arch_prepare_memory_region(struct kvm *kvm, |
@@ -6051,7 +6136,9 @@ void kvm_arch_flush_shadow(struct kvm *kvm) | |||
6051 | 6136 | ||
6052 | int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) | 6137 | int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) |
6053 | { | 6138 | { |
6054 | return vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE | 6139 | return (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE && |
6140 | !vcpu->arch.apf.halted) | ||
6141 | || !list_empty_careful(&vcpu->async_pf.done) | ||
6055 | || vcpu->arch.mp_state == KVM_MP_STATE_SIPI_RECEIVED | 6142 | || vcpu->arch.mp_state == KVM_MP_STATE_SIPI_RECEIVED |
6056 | || vcpu->arch.nmi_pending || | 6143 | || vcpu->arch.nmi_pending || |
6057 | (kvm_arch_interrupt_allowed(vcpu) && | 6144 | (kvm_arch_interrupt_allowed(vcpu) && |
@@ -6110,6 +6197,147 @@ void kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) | |||
6110 | } | 6197 | } |
6111 | EXPORT_SYMBOL_GPL(kvm_set_rflags); | 6198 | EXPORT_SYMBOL_GPL(kvm_set_rflags); |
6112 | 6199 | ||
6200 | void kvm_arch_async_page_ready(struct kvm_vcpu *vcpu, struct kvm_async_pf *work) | ||
6201 | { | ||
6202 | int r; | ||
6203 | |||
6204 | if ((vcpu->arch.mmu.direct_map != work->arch.direct_map) || | ||
6205 | is_error_page(work->page)) | ||
6206 | return; | ||
6207 | |||
6208 | r = kvm_mmu_reload(vcpu); | ||
6209 | if (unlikely(r)) | ||
6210 | return; | ||
6211 | |||
6212 | if (!vcpu->arch.mmu.direct_map && | ||
6213 | work->arch.cr3 != vcpu->arch.mmu.get_cr3(vcpu)) | ||
6214 | return; | ||
6215 | |||
6216 | vcpu->arch.mmu.page_fault(vcpu, work->gva, 0, true); | ||
6217 | } | ||
6218 | |||
6219 | static inline u32 kvm_async_pf_hash_fn(gfn_t gfn) | ||
6220 | { | ||
6221 | return hash_32(gfn & 0xffffffff, order_base_2(ASYNC_PF_PER_VCPU)); | ||
6222 | } | ||
6223 | |||
6224 | static inline u32 kvm_async_pf_next_probe(u32 key) | ||
6225 | { | ||
6226 | return (key + 1) & (roundup_pow_of_two(ASYNC_PF_PER_VCPU) - 1); | ||
6227 | } | ||
6228 | |||
6229 | static void kvm_add_async_pf_gfn(struct kvm_vcpu *vcpu, gfn_t gfn) | ||
6230 | { | ||
6231 | u32 key = kvm_async_pf_hash_fn(gfn); | ||
6232 | |||
6233 | while (vcpu->arch.apf.gfns[key] != ~0) | ||
6234 | key = kvm_async_pf_next_probe(key); | ||
6235 | |||
6236 | vcpu->arch.apf.gfns[key] = gfn; | ||
6237 | } | ||
6238 | |||
6239 | static u32 kvm_async_pf_gfn_slot(struct kvm_vcpu *vcpu, gfn_t gfn) | ||
6240 | { | ||
6241 | int i; | ||
6242 | u32 key = kvm_async_pf_hash_fn(gfn); | ||
6243 | |||
6244 | for (i = 0; i < roundup_pow_of_two(ASYNC_PF_PER_VCPU) && | ||
6245 | (vcpu->arch.apf.gfns[key] != gfn && | ||
6246 | vcpu->arch.apf.gfns[key] != ~0); i++) | ||
6247 | key = kvm_async_pf_next_probe(key); | ||
6248 | |||
6249 | return key; | ||
6250 | } | ||
6251 | |||
6252 | bool kvm_find_async_pf_gfn(struct kvm_vcpu *vcpu, gfn_t gfn) | ||
6253 | { | ||
6254 | return vcpu->arch.apf.gfns[kvm_async_pf_gfn_slot(vcpu, gfn)] == gfn; | ||
6255 | } | ||
6256 | |||
6257 | static void kvm_del_async_pf_gfn(struct kvm_vcpu *vcpu, gfn_t gfn) | ||
6258 | { | ||
6259 | u32 i, j, k; | ||
6260 | |||
6261 | i = j = kvm_async_pf_gfn_slot(vcpu, gfn); | ||
6262 | while (true) { | ||
6263 | vcpu->arch.apf.gfns[i] = ~0; | ||
6264 | do { | ||
6265 | j = kvm_async_pf_next_probe(j); | ||
6266 | if (vcpu->arch.apf.gfns[j] == ~0) | ||
6267 | return; | ||
6268 | k = kvm_async_pf_hash_fn(vcpu->arch.apf.gfns[j]); | ||
6269 | /* | ||
6270 | * k lies cyclically in ]i,j] | ||
6271 | * | i.k.j | | ||
6272 | * |....j i.k.| or |.k..j i...| | ||
6273 | */ | ||
6274 | } while ((i <= j) ? (i < k && k <= j) : (i < k || k <= j)); | ||
6275 | vcpu->arch.apf.gfns[i] = vcpu->arch.apf.gfns[j]; | ||
6276 | i = j; | ||
6277 | } | ||
6278 | } | ||
6279 | |||
6280 | static int apf_put_user(struct kvm_vcpu *vcpu, u32 val) | ||
6281 | { | ||
6282 | |||
6283 | return kvm_write_guest_cached(vcpu->kvm, &vcpu->arch.apf.data, &val, | ||
6284 | sizeof(val)); | ||
6285 | } | ||
6286 | |||
6287 | void kvm_arch_async_page_not_present(struct kvm_vcpu *vcpu, | ||
6288 | struct kvm_async_pf *work) | ||
6289 | { | ||
6290 | struct x86_exception fault; | ||
6291 | |||
6292 | trace_kvm_async_pf_not_present(work->arch.token, work->gva); | ||
6293 | kvm_add_async_pf_gfn(vcpu, work->arch.gfn); | ||
6294 | |||
6295 | if (!(vcpu->arch.apf.msr_val & KVM_ASYNC_PF_ENABLED) || | ||
6296 | (vcpu->arch.apf.send_user_only && | ||
6297 | kvm_x86_ops->get_cpl(vcpu) == 0)) | ||
6298 | kvm_make_request(KVM_REQ_APF_HALT, vcpu); | ||
6299 | else if (!apf_put_user(vcpu, KVM_PV_REASON_PAGE_NOT_PRESENT)) { | ||
6300 | fault.vector = PF_VECTOR; | ||
6301 | fault.error_code_valid = true; | ||
6302 | fault.error_code = 0; | ||
6303 | fault.nested_page_fault = false; | ||
6304 | fault.address = work->arch.token; | ||
6305 | kvm_inject_page_fault(vcpu, &fault); | ||
6306 | } | ||
6307 | } | ||
6308 | |||
6309 | void kvm_arch_async_page_present(struct kvm_vcpu *vcpu, | ||
6310 | struct kvm_async_pf *work) | ||
6311 | { | ||
6312 | struct x86_exception fault; | ||
6313 | |||
6314 | trace_kvm_async_pf_ready(work->arch.token, work->gva); | ||
6315 | if (is_error_page(work->page)) | ||
6316 | work->arch.token = ~0; /* broadcast wakeup */ | ||
6317 | else | ||
6318 | kvm_del_async_pf_gfn(vcpu, work->arch.gfn); | ||
6319 | |||
6320 | if ((vcpu->arch.apf.msr_val & KVM_ASYNC_PF_ENABLED) && | ||
6321 | !apf_put_user(vcpu, KVM_PV_REASON_PAGE_READY)) { | ||
6322 | fault.vector = PF_VECTOR; | ||
6323 | fault.error_code_valid = true; | ||
6324 | fault.error_code = 0; | ||
6325 | fault.nested_page_fault = false; | ||
6326 | fault.address = work->arch.token; | ||
6327 | kvm_inject_page_fault(vcpu, &fault); | ||
6328 | } | ||
6329 | vcpu->arch.apf.halted = false; | ||
6330 | } | ||
6331 | |||
6332 | bool kvm_arch_can_inject_async_page_present(struct kvm_vcpu *vcpu) | ||
6333 | { | ||
6334 | if (!(vcpu->arch.apf.msr_val & KVM_ASYNC_PF_ENABLED)) | ||
6335 | return true; | ||
6336 | else | ||
6337 | return !kvm_event_needs_reinjection(vcpu) && | ||
6338 | kvm_x86_ops->interrupt_allowed(vcpu); | ||
6339 | } | ||
6340 | |||
6113 | EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_exit); | 6341 | EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_exit); |
6114 | EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_inj_virq); | 6342 | EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_inj_virq); |
6115 | EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_page_fault); | 6343 | EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_page_fault); |
diff --git a/arch/x86/mm/gup.c b/arch/x86/mm/gup.c index 738e6593799d..dbe34b931374 100644 --- a/arch/x86/mm/gup.c +++ b/arch/x86/mm/gup.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/mm.h> | 8 | #include <linux/mm.h> |
9 | #include <linux/vmstat.h> | 9 | #include <linux/vmstat.h> |
10 | #include <linux/highmem.h> | 10 | #include <linux/highmem.h> |
11 | #include <linux/swap.h> | ||
11 | 12 | ||
12 | #include <asm/pgtable.h> | 13 | #include <asm/pgtable.h> |
13 | 14 | ||
@@ -89,6 +90,7 @@ static noinline int gup_pte_range(pmd_t pmd, unsigned long addr, | |||
89 | VM_BUG_ON(!pfn_valid(pte_pfn(pte))); | 90 | VM_BUG_ON(!pfn_valid(pte_pfn(pte))); |
90 | page = pte_page(pte); | 91 | page = pte_page(pte); |
91 | get_page(page); | 92 | get_page(page); |
93 | SetPageReferenced(page); | ||
92 | pages[*nr] = page; | 94 | pages[*nr] = page; |
93 | (*nr)++; | 95 | (*nr)++; |
94 | 96 | ||
@@ -103,6 +105,17 @@ static inline void get_head_page_multiple(struct page *page, int nr) | |||
103 | VM_BUG_ON(page != compound_head(page)); | 105 | VM_BUG_ON(page != compound_head(page)); |
104 | VM_BUG_ON(page_count(page) == 0); | 106 | VM_BUG_ON(page_count(page) == 0); |
105 | atomic_add(nr, &page->_count); | 107 | atomic_add(nr, &page->_count); |
108 | SetPageReferenced(page); | ||
109 | } | ||
110 | |||
111 | static inline void get_huge_page_tail(struct page *page) | ||
112 | { | ||
113 | /* | ||
114 | * __split_huge_page_refcount() cannot run | ||
115 | * from under us. | ||
116 | */ | ||
117 | VM_BUG_ON(atomic_read(&page->_count) < 0); | ||
118 | atomic_inc(&page->_count); | ||
106 | } | 119 | } |
107 | 120 | ||
108 | static noinline int gup_huge_pmd(pmd_t pmd, unsigned long addr, | 121 | static noinline int gup_huge_pmd(pmd_t pmd, unsigned long addr, |
@@ -128,6 +141,8 @@ static noinline int gup_huge_pmd(pmd_t pmd, unsigned long addr, | |||
128 | do { | 141 | do { |
129 | VM_BUG_ON(compound_head(page) != head); | 142 | VM_BUG_ON(compound_head(page) != head); |
130 | pages[*nr] = page; | 143 | pages[*nr] = page; |
144 | if (PageTail(page)) | ||
145 | get_huge_page_tail(page); | ||
131 | (*nr)++; | 146 | (*nr)++; |
132 | page++; | 147 | page++; |
133 | refs++; | 148 | refs++; |
@@ -148,7 +163,18 @@ static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end, | |||
148 | pmd_t pmd = *pmdp; | 163 | pmd_t pmd = *pmdp; |
149 | 164 | ||
150 | next = pmd_addr_end(addr, end); | 165 | next = pmd_addr_end(addr, end); |
151 | if (pmd_none(pmd)) | 166 | /* |
167 | * The pmd_trans_splitting() check below explains why | ||
168 | * pmdp_splitting_flush has to flush the tlb, to stop | ||
169 | * this gup-fast code from running while we set the | ||
170 | * splitting bit in the pmd. Returning zero will take | ||
171 | * the slow path that will call wait_split_huge_page() | ||
172 | * if the pmd is still in splitting state. gup-fast | ||
173 | * can't because it has irq disabled and | ||
174 | * wait_split_huge_page() would never return as the | ||
175 | * tlb flush IPI wouldn't run. | ||
176 | */ | ||
177 | if (pmd_none(pmd) || pmd_trans_splitting(pmd)) | ||
152 | return 0; | 178 | return 0; |
153 | if (unlikely(pmd_large(pmd))) { | 179 | if (unlikely(pmd_large(pmd))) { |
154 | if (!gup_huge_pmd(pmd, addr, next, write, pages, nr)) | 180 | if (!gup_huge_pmd(pmd, addr, next, write, pages, nr)) |
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index f89b5bb4e93f..c821074b7f0b 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <asm/bugs.h> | 45 | #include <asm/bugs.h> |
46 | #include <asm/tlb.h> | 46 | #include <asm/tlb.h> |
47 | #include <asm/tlbflush.h> | 47 | #include <asm/tlbflush.h> |
48 | #include <asm/olpc_ofw.h> | ||
48 | #include <asm/pgalloc.h> | 49 | #include <asm/pgalloc.h> |
49 | #include <asm/sections.h> | 50 | #include <asm/sections.h> |
50 | #include <asm/paravirt.h> | 51 | #include <asm/paravirt.h> |
@@ -715,6 +716,7 @@ void __init paging_init(void) | |||
715 | /* | 716 | /* |
716 | * NOTE: at this point the bootmem allocator is fully available. | 717 | * NOTE: at this point the bootmem allocator is fully available. |
717 | */ | 718 | */ |
719 | olpc_dt_build_devicetree(); | ||
718 | sparse_init(); | 720 | sparse_init(); |
719 | zone_sizes_init(); | 721 | zone_sizes_init(); |
720 | } | 722 | } |
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c index 8be8c7d7bc89..500242d3c96d 100644 --- a/arch/x86/mm/pgtable.c +++ b/arch/x86/mm/pgtable.c | |||
@@ -320,6 +320,25 @@ int ptep_set_access_flags(struct vm_area_struct *vma, | |||
320 | return changed; | 320 | return changed; |
321 | } | 321 | } |
322 | 322 | ||
323 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | ||
324 | int pmdp_set_access_flags(struct vm_area_struct *vma, | ||
325 | unsigned long address, pmd_t *pmdp, | ||
326 | pmd_t entry, int dirty) | ||
327 | { | ||
328 | int changed = !pmd_same(*pmdp, entry); | ||
329 | |||
330 | VM_BUG_ON(address & ~HPAGE_PMD_MASK); | ||
331 | |||
332 | if (changed && dirty) { | ||
333 | *pmdp = entry; | ||
334 | pmd_update_defer(vma->vm_mm, address, pmdp); | ||
335 | flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE); | ||
336 | } | ||
337 | |||
338 | return changed; | ||
339 | } | ||
340 | #endif | ||
341 | |||
323 | int ptep_test_and_clear_young(struct vm_area_struct *vma, | 342 | int ptep_test_and_clear_young(struct vm_area_struct *vma, |
324 | unsigned long addr, pte_t *ptep) | 343 | unsigned long addr, pte_t *ptep) |
325 | { | 344 | { |
@@ -335,6 +354,23 @@ int ptep_test_and_clear_young(struct vm_area_struct *vma, | |||
335 | return ret; | 354 | return ret; |
336 | } | 355 | } |
337 | 356 | ||
357 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | ||
358 | int pmdp_test_and_clear_young(struct vm_area_struct *vma, | ||
359 | unsigned long addr, pmd_t *pmdp) | ||
360 | { | ||
361 | int ret = 0; | ||
362 | |||
363 | if (pmd_young(*pmdp)) | ||
364 | ret = test_and_clear_bit(_PAGE_BIT_ACCESSED, | ||
365 | (unsigned long *)pmdp); | ||
366 | |||
367 | if (ret) | ||
368 | pmd_update(vma->vm_mm, addr, pmdp); | ||
369 | |||
370 | return ret; | ||
371 | } | ||
372 | #endif | ||
373 | |||
338 | int ptep_clear_flush_young(struct vm_area_struct *vma, | 374 | int ptep_clear_flush_young(struct vm_area_struct *vma, |
339 | unsigned long address, pte_t *ptep) | 375 | unsigned long address, pte_t *ptep) |
340 | { | 376 | { |
@@ -347,6 +383,36 @@ int ptep_clear_flush_young(struct vm_area_struct *vma, | |||
347 | return young; | 383 | return young; |
348 | } | 384 | } |
349 | 385 | ||
386 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | ||
387 | int pmdp_clear_flush_young(struct vm_area_struct *vma, | ||
388 | unsigned long address, pmd_t *pmdp) | ||
389 | { | ||
390 | int young; | ||
391 | |||
392 | VM_BUG_ON(address & ~HPAGE_PMD_MASK); | ||
393 | |||
394 | young = pmdp_test_and_clear_young(vma, address, pmdp); | ||
395 | if (young) | ||
396 | flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE); | ||
397 | |||
398 | return young; | ||
399 | } | ||
400 | |||
401 | void pmdp_splitting_flush(struct vm_area_struct *vma, | ||
402 | unsigned long address, pmd_t *pmdp) | ||
403 | { | ||
404 | int set; | ||
405 | VM_BUG_ON(address & ~HPAGE_PMD_MASK); | ||
406 | set = !test_and_set_bit(_PAGE_BIT_SPLITTING, | ||
407 | (unsigned long *)pmdp); | ||
408 | if (set) { | ||
409 | pmd_update(vma->vm_mm, address, pmdp); | ||
410 | /* need tlb flush only to serialize against gup-fast */ | ||
411 | flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE); | ||
412 | } | ||
413 | } | ||
414 | #endif | ||
415 | |||
350 | /** | 416 | /** |
351 | * reserve_top_address - reserves a hole in the top of kernel address space | 417 | * reserve_top_address - reserves a hole in the top of kernel address space |
352 | * @reserve - size of hole to reserve | 418 | * @reserve - size of hole to reserve |
diff --git a/arch/x86/platform/mrst/early_printk_mrst.c b/arch/x86/platform/mrst/early_printk_mrst.c index 65df603622b2..25bfdbb5b130 100644 --- a/arch/x86/platform/mrst/early_printk_mrst.c +++ b/arch/x86/platform/mrst/early_printk_mrst.c | |||
@@ -103,7 +103,7 @@ struct dw_spi_reg { | |||
103 | static unsigned long mrst_spi_paddr = MRST_REGBASE_SPI0; | 103 | static unsigned long mrst_spi_paddr = MRST_REGBASE_SPI0; |
104 | 104 | ||
105 | static u32 *pclk_spi0; | 105 | static u32 *pclk_spi0; |
106 | /* Always contains an accessable address, start with 0 */ | 106 | /* Always contains an accessible address, start with 0 */ |
107 | static struct dw_spi_reg *pspi; | 107 | static struct dw_spi_reg *pspi; |
108 | 108 | ||
109 | static struct kmsg_dumper dw_dumper; | 109 | static struct kmsg_dumper dw_dumper; |
diff --git a/arch/x86/platform/olpc/Makefile b/arch/x86/platform/olpc/Makefile index c31b8fcb5a86..e797428b163b 100644 --- a/arch/x86/platform/olpc/Makefile +++ b/arch/x86/platform/olpc/Makefile | |||
@@ -1,3 +1,4 @@ | |||
1 | obj-$(CONFIG_OLPC) += olpc.o | 1 | obj-$(CONFIG_OLPC) += olpc.o |
2 | obj-$(CONFIG_OLPC_XO1) += olpc-xo1.o | 2 | obj-$(CONFIG_OLPC_XO1) += olpc-xo1.o |
3 | obj-$(CONFIG_OLPC_OPENFIRMWARE) += olpc_ofw.o | 3 | obj-$(CONFIG_OLPC_OPENFIRMWARE) += olpc_ofw.o |
4 | obj-$(CONFIG_OLPC_OPENFIRMWARE_DT) += olpc_dt.o | ||
diff --git a/arch/x86/platform/olpc/olpc_dt.c b/arch/x86/platform/olpc/olpc_dt.c new file mode 100644 index 000000000000..dab874647530 --- /dev/null +++ b/arch/x86/platform/olpc/olpc_dt.c | |||
@@ -0,0 +1,183 @@ | |||
1 | /* | ||
2 | * OLPC-specific OFW device tree support code. | ||
3 | * | ||
4 | * Paul Mackerras August 1996. | ||
5 | * Copyright (C) 1996-2005 Paul Mackerras. | ||
6 | * | ||
7 | * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner. | ||
8 | * {engebret|bergner}@us.ibm.com | ||
9 | * | ||
10 | * Adapted for sparc by David S. Miller davem@davemloft.net | ||
11 | * Adapted for x86/OLPC by Andres Salomon <dilinger@queued.net> | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version | ||
16 | * 2 of the License, or (at your option) any later version. | ||
17 | */ | ||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/bootmem.h> | ||
21 | #include <linux/of.h> | ||
22 | #include <linux/of_pdt.h> | ||
23 | #include <asm/olpc_ofw.h> | ||
24 | |||
25 | static phandle __init olpc_dt_getsibling(phandle node) | ||
26 | { | ||
27 | const void *args[] = { (void *)node }; | ||
28 | void *res[] = { &node }; | ||
29 | |||
30 | if ((s32)node == -1) | ||
31 | return 0; | ||
32 | |||
33 | if (olpc_ofw("peer", args, res) || (s32)node == -1) | ||
34 | return 0; | ||
35 | |||
36 | return node; | ||
37 | } | ||
38 | |||
39 | static phandle __init olpc_dt_getchild(phandle node) | ||
40 | { | ||
41 | const void *args[] = { (void *)node }; | ||
42 | void *res[] = { &node }; | ||
43 | |||
44 | if ((s32)node == -1) | ||
45 | return 0; | ||
46 | |||
47 | if (olpc_ofw("child", args, res) || (s32)node == -1) { | ||
48 | pr_err("PROM: %s: fetching child failed!\n", __func__); | ||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | return node; | ||
53 | } | ||
54 | |||
55 | static int __init olpc_dt_getproplen(phandle node, const char *prop) | ||
56 | { | ||
57 | const void *args[] = { (void *)node, prop }; | ||
58 | int len; | ||
59 | void *res[] = { &len }; | ||
60 | |||
61 | if ((s32)node == -1) | ||
62 | return -1; | ||
63 | |||
64 | if (olpc_ofw("getproplen", args, res)) { | ||
65 | pr_err("PROM: %s: getproplen failed!\n", __func__); | ||
66 | return -1; | ||
67 | } | ||
68 | |||
69 | return len; | ||
70 | } | ||
71 | |||
72 | static int __init olpc_dt_getproperty(phandle node, const char *prop, | ||
73 | char *buf, int bufsize) | ||
74 | { | ||
75 | int plen; | ||
76 | |||
77 | plen = olpc_dt_getproplen(node, prop); | ||
78 | if (plen > bufsize || plen < 1) { | ||
79 | return -1; | ||
80 | } else { | ||
81 | const void *args[] = { (void *)node, prop, buf, (void *)plen }; | ||
82 | void *res[] = { &plen }; | ||
83 | |||
84 | if (olpc_ofw("getprop", args, res)) { | ||
85 | pr_err("PROM: %s: getprop failed!\n", __func__); | ||
86 | return -1; | ||
87 | } | ||
88 | } | ||
89 | |||
90 | return plen; | ||
91 | } | ||
92 | |||
93 | static int __init olpc_dt_nextprop(phandle node, char *prev, char *buf) | ||
94 | { | ||
95 | const void *args[] = { (void *)node, prev, buf }; | ||
96 | int success; | ||
97 | void *res[] = { &success }; | ||
98 | |||
99 | buf[0] = '\0'; | ||
100 | |||
101 | if ((s32)node == -1) | ||
102 | return -1; | ||
103 | |||
104 | if (olpc_ofw("nextprop", args, res) || success != 1) | ||
105 | return -1; | ||
106 | |||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | static int __init olpc_dt_pkg2path(phandle node, char *buf, | ||
111 | const int buflen, int *len) | ||
112 | { | ||
113 | const void *args[] = { (void *)node, buf, (void *)buflen }; | ||
114 | void *res[] = { len }; | ||
115 | |||
116 | if ((s32)node == -1) | ||
117 | return -1; | ||
118 | |||
119 | if (olpc_ofw("package-to-path", args, res) || *len < 1) | ||
120 | return -1; | ||
121 | |||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | static unsigned int prom_early_allocated __initdata; | ||
126 | |||
127 | void * __init prom_early_alloc(unsigned long size) | ||
128 | { | ||
129 | static u8 *mem; | ||
130 | static size_t free_mem; | ||
131 | void *res; | ||
132 | |||
133 | if (free_mem < size) { | ||
134 | const size_t chunk_size = max(PAGE_SIZE, size); | ||
135 | |||
136 | /* | ||
137 | * To mimimize the number of allocations, grab at least | ||
138 | * PAGE_SIZE of memory (that's an arbitrary choice that's | ||
139 | * fast enough on the platforms we care about while minimizing | ||
140 | * wasted bootmem) and hand off chunks of it to callers. | ||
141 | */ | ||
142 | res = alloc_bootmem(chunk_size); | ||
143 | if (!res) | ||
144 | return NULL; | ||
145 | prom_early_allocated += chunk_size; | ||
146 | memset(res, 0, chunk_size); | ||
147 | free_mem = chunk_size; | ||
148 | mem = res; | ||
149 | } | ||
150 | |||
151 | /* allocate from the local cache */ | ||
152 | free_mem -= size; | ||
153 | res = mem; | ||
154 | mem += size; | ||
155 | return res; | ||
156 | } | ||
157 | |||
158 | static struct of_pdt_ops prom_olpc_ops __initdata = { | ||
159 | .nextprop = olpc_dt_nextprop, | ||
160 | .getproplen = olpc_dt_getproplen, | ||
161 | .getproperty = olpc_dt_getproperty, | ||
162 | .getchild = olpc_dt_getchild, | ||
163 | .getsibling = olpc_dt_getsibling, | ||
164 | .pkg2path = olpc_dt_pkg2path, | ||
165 | }; | ||
166 | |||
167 | void __init olpc_dt_build_devicetree(void) | ||
168 | { | ||
169 | phandle root; | ||
170 | |||
171 | if (!olpc_ofw_is_installed()) | ||
172 | return; | ||
173 | |||
174 | root = olpc_dt_getsibling(0); | ||
175 | if (!root) { | ||
176 | pr_err("PROM: unable to get root node from OFW!\n"); | ||
177 | return; | ||
178 | } | ||
179 | of_pdt_build_devicetree(root, &prom_olpc_ops); | ||
180 | |||
181 | pr_info("PROM DT: Built device tree with %u bytes of memory.\n", | ||
182 | prom_early_allocated); | ||
183 | } | ||
diff --git a/arch/x86/platform/olpc/olpc_ofw.c b/arch/x86/platform/olpc/olpc_ofw.c index 787320464379..e7604f62870d 100644 --- a/arch/x86/platform/olpc/olpc_ofw.c +++ b/arch/x86/platform/olpc/olpc_ofw.c | |||
@@ -110,3 +110,8 @@ void __init olpc_ofw_detect(void) | |||
110 | (unsigned long)olpc_ofw_cif, (-start) >> 20); | 110 | (unsigned long)olpc_ofw_cif, (-start) >> 20); |
111 | reserve_top_address(-start); | 111 | reserve_top_address(-start); |
112 | } | 112 | } |
113 | |||
114 | bool __init olpc_ofw_is_installed(void) | ||
115 | { | ||
116 | return olpc_ofw_cif != NULL; | ||
117 | } | ||
diff --git a/arch/x86/xen/Makefile b/arch/x86/xen/Makefile index 779385158915..17c565de3d64 100644 --- a/arch/x86/xen/Makefile +++ b/arch/x86/xen/Makefile | |||
@@ -12,7 +12,8 @@ CFLAGS_mmu.o := $(nostackp) | |||
12 | 12 | ||
13 | obj-y := enlighten.o setup.o multicalls.o mmu.o irq.o \ | 13 | obj-y := enlighten.o setup.o multicalls.o mmu.o irq.o \ |
14 | time.o xen-asm.o xen-asm_$(BITS).o \ | 14 | time.o xen-asm.o xen-asm_$(BITS).o \ |
15 | grant-table.o suspend.o platform-pci-unplug.o | 15 | grant-table.o suspend.o platform-pci-unplug.o \ |
16 | p2m.o | ||
16 | 17 | ||
17 | obj-$(CONFIG_SMP) += smp.o | 18 | obj-$(CONFIG_SMP) += smp.o |
18 | obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o | 19 | obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o |
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 44924e551fde..7575e55cd52e 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
@@ -173,371 +173,6 @@ DEFINE_PER_CPU(unsigned long, xen_current_cr3); /* actual vcpu cr3 */ | |||
173 | */ | 173 | */ |
174 | #define USER_LIMIT ((STACK_TOP_MAX + PGDIR_SIZE - 1) & PGDIR_MASK) | 174 | #define USER_LIMIT ((STACK_TOP_MAX + PGDIR_SIZE - 1) & PGDIR_MASK) |
175 | 175 | ||
176 | /* | ||
177 | * Xen leaves the responsibility for maintaining p2m mappings to the | ||
178 | * guests themselves, but it must also access and update the p2m array | ||
179 | * during suspend/resume when all the pages are reallocated. | ||
180 | * | ||
181 | * The p2m table is logically a flat array, but we implement it as a | ||
182 | * three-level tree to allow the address space to be sparse. | ||
183 | * | ||
184 | * Xen | ||
185 | * | | ||
186 | * p2m_top p2m_top_mfn | ||
187 | * / \ / \ | ||
188 | * p2m_mid p2m_mid p2m_mid_mfn p2m_mid_mfn | ||
189 | * / \ / \ / / | ||
190 | * p2m p2m p2m p2m p2m p2m p2m ... | ||
191 | * | ||
192 | * The p2m_mid_mfn pages are mapped by p2m_top_mfn_p. | ||
193 | * | ||
194 | * The p2m_top and p2m_top_mfn levels are limited to 1 page, so the | ||
195 | * maximum representable pseudo-physical address space is: | ||
196 | * P2M_TOP_PER_PAGE * P2M_MID_PER_PAGE * P2M_PER_PAGE pages | ||
197 | * | ||
198 | * P2M_PER_PAGE depends on the architecture, as a mfn is always | ||
199 | * unsigned long (8 bytes on 64-bit, 4 bytes on 32), leading to | ||
200 | * 512 and 1024 entries respectively. | ||
201 | */ | ||
202 | |||
203 | unsigned long xen_max_p2m_pfn __read_mostly; | ||
204 | |||
205 | #define P2M_PER_PAGE (PAGE_SIZE / sizeof(unsigned long)) | ||
206 | #define P2M_MID_PER_PAGE (PAGE_SIZE / sizeof(unsigned long *)) | ||
207 | #define P2M_TOP_PER_PAGE (PAGE_SIZE / sizeof(unsigned long **)) | ||
208 | |||
209 | #define MAX_P2M_PFN (P2M_TOP_PER_PAGE * P2M_MID_PER_PAGE * P2M_PER_PAGE) | ||
210 | |||
211 | /* Placeholders for holes in the address space */ | ||
212 | static RESERVE_BRK_ARRAY(unsigned long, p2m_missing, P2M_PER_PAGE); | ||
213 | static RESERVE_BRK_ARRAY(unsigned long *, p2m_mid_missing, P2M_MID_PER_PAGE); | ||
214 | static RESERVE_BRK_ARRAY(unsigned long, p2m_mid_missing_mfn, P2M_MID_PER_PAGE); | ||
215 | |||
216 | static RESERVE_BRK_ARRAY(unsigned long **, p2m_top, P2M_TOP_PER_PAGE); | ||
217 | static RESERVE_BRK_ARRAY(unsigned long, p2m_top_mfn, P2M_TOP_PER_PAGE); | ||
218 | static RESERVE_BRK_ARRAY(unsigned long *, p2m_top_mfn_p, P2M_TOP_PER_PAGE); | ||
219 | |||
220 | RESERVE_BRK(p2m_mid, PAGE_SIZE * (MAX_DOMAIN_PAGES / (P2M_PER_PAGE * P2M_MID_PER_PAGE))); | ||
221 | RESERVE_BRK(p2m_mid_mfn, PAGE_SIZE * (MAX_DOMAIN_PAGES / (P2M_PER_PAGE * P2M_MID_PER_PAGE))); | ||
222 | |||
223 | static inline unsigned p2m_top_index(unsigned long pfn) | ||
224 | { | ||
225 | BUG_ON(pfn >= MAX_P2M_PFN); | ||
226 | return pfn / (P2M_MID_PER_PAGE * P2M_PER_PAGE); | ||
227 | } | ||
228 | |||
229 | static inline unsigned p2m_mid_index(unsigned long pfn) | ||
230 | { | ||
231 | return (pfn / P2M_PER_PAGE) % P2M_MID_PER_PAGE; | ||
232 | } | ||
233 | |||
234 | static inline unsigned p2m_index(unsigned long pfn) | ||
235 | { | ||
236 | return pfn % P2M_PER_PAGE; | ||
237 | } | ||
238 | |||
239 | static void p2m_top_init(unsigned long ***top) | ||
240 | { | ||
241 | unsigned i; | ||
242 | |||
243 | for (i = 0; i < P2M_TOP_PER_PAGE; i++) | ||
244 | top[i] = p2m_mid_missing; | ||
245 | } | ||
246 | |||
247 | static void p2m_top_mfn_init(unsigned long *top) | ||
248 | { | ||
249 | unsigned i; | ||
250 | |||
251 | for (i = 0; i < P2M_TOP_PER_PAGE; i++) | ||
252 | top[i] = virt_to_mfn(p2m_mid_missing_mfn); | ||
253 | } | ||
254 | |||
255 | static void p2m_top_mfn_p_init(unsigned long **top) | ||
256 | { | ||
257 | unsigned i; | ||
258 | |||
259 | for (i = 0; i < P2M_TOP_PER_PAGE; i++) | ||
260 | top[i] = p2m_mid_missing_mfn; | ||
261 | } | ||
262 | |||
263 | static void p2m_mid_init(unsigned long **mid) | ||
264 | { | ||
265 | unsigned i; | ||
266 | |||
267 | for (i = 0; i < P2M_MID_PER_PAGE; i++) | ||
268 | mid[i] = p2m_missing; | ||
269 | } | ||
270 | |||
271 | static void p2m_mid_mfn_init(unsigned long *mid) | ||
272 | { | ||
273 | unsigned i; | ||
274 | |||
275 | for (i = 0; i < P2M_MID_PER_PAGE; i++) | ||
276 | mid[i] = virt_to_mfn(p2m_missing); | ||
277 | } | ||
278 | |||
279 | static void p2m_init(unsigned long *p2m) | ||
280 | { | ||
281 | unsigned i; | ||
282 | |||
283 | for (i = 0; i < P2M_MID_PER_PAGE; i++) | ||
284 | p2m[i] = INVALID_P2M_ENTRY; | ||
285 | } | ||
286 | |||
287 | /* | ||
288 | * Build the parallel p2m_top_mfn and p2m_mid_mfn structures | ||
289 | * | ||
290 | * This is called both at boot time, and after resuming from suspend: | ||
291 | * - At boot time we're called very early, and must use extend_brk() | ||
292 | * to allocate memory. | ||
293 | * | ||
294 | * - After resume we're called from within stop_machine, but the mfn | ||
295 | * tree should alreay be completely allocated. | ||
296 | */ | ||
297 | void xen_build_mfn_list_list(void) | ||
298 | { | ||
299 | unsigned long pfn; | ||
300 | |||
301 | /* Pre-initialize p2m_top_mfn to be completely missing */ | ||
302 | if (p2m_top_mfn == NULL) { | ||
303 | p2m_mid_missing_mfn = extend_brk(PAGE_SIZE, PAGE_SIZE); | ||
304 | p2m_mid_mfn_init(p2m_mid_missing_mfn); | ||
305 | |||
306 | p2m_top_mfn_p = extend_brk(PAGE_SIZE, PAGE_SIZE); | ||
307 | p2m_top_mfn_p_init(p2m_top_mfn_p); | ||
308 | |||
309 | p2m_top_mfn = extend_brk(PAGE_SIZE, PAGE_SIZE); | ||
310 | p2m_top_mfn_init(p2m_top_mfn); | ||
311 | } else { | ||
312 | /* Reinitialise, mfn's all change after migration */ | ||
313 | p2m_mid_mfn_init(p2m_mid_missing_mfn); | ||
314 | } | ||
315 | |||
316 | for (pfn = 0; pfn < xen_max_p2m_pfn; pfn += P2M_PER_PAGE) { | ||
317 | unsigned topidx = p2m_top_index(pfn); | ||
318 | unsigned mididx = p2m_mid_index(pfn); | ||
319 | unsigned long **mid; | ||
320 | unsigned long *mid_mfn_p; | ||
321 | |||
322 | mid = p2m_top[topidx]; | ||
323 | mid_mfn_p = p2m_top_mfn_p[topidx]; | ||
324 | |||
325 | /* Don't bother allocating any mfn mid levels if | ||
326 | * they're just missing, just update the stored mfn, | ||
327 | * since all could have changed over a migrate. | ||
328 | */ | ||
329 | if (mid == p2m_mid_missing) { | ||
330 | BUG_ON(mididx); | ||
331 | BUG_ON(mid_mfn_p != p2m_mid_missing_mfn); | ||
332 | p2m_top_mfn[topidx] = virt_to_mfn(p2m_mid_missing_mfn); | ||
333 | pfn += (P2M_MID_PER_PAGE - 1) * P2M_PER_PAGE; | ||
334 | continue; | ||
335 | } | ||
336 | |||
337 | if (mid_mfn_p == p2m_mid_missing_mfn) { | ||
338 | /* | ||
339 | * XXX boot-time only! We should never find | ||
340 | * missing parts of the mfn tree after | ||
341 | * runtime. extend_brk() will BUG if we call | ||
342 | * it too late. | ||
343 | */ | ||
344 | mid_mfn_p = extend_brk(PAGE_SIZE, PAGE_SIZE); | ||
345 | p2m_mid_mfn_init(mid_mfn_p); | ||
346 | |||
347 | p2m_top_mfn_p[topidx] = mid_mfn_p; | ||
348 | } | ||
349 | |||
350 | p2m_top_mfn[topidx] = virt_to_mfn(mid_mfn_p); | ||
351 | mid_mfn_p[mididx] = virt_to_mfn(mid[mididx]); | ||
352 | } | ||
353 | } | ||
354 | |||
355 | void xen_setup_mfn_list_list(void) | ||
356 | { | ||
357 | BUG_ON(HYPERVISOR_shared_info == &xen_dummy_shared_info); | ||
358 | |||
359 | HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list = | ||
360 | virt_to_mfn(p2m_top_mfn); | ||
361 | HYPERVISOR_shared_info->arch.max_pfn = xen_max_p2m_pfn; | ||
362 | } | ||
363 | |||
364 | /* Set up p2m_top to point to the domain-builder provided p2m pages */ | ||
365 | void __init xen_build_dynamic_phys_to_machine(void) | ||
366 | { | ||
367 | unsigned long *mfn_list = (unsigned long *)xen_start_info->mfn_list; | ||
368 | unsigned long max_pfn = min(MAX_DOMAIN_PAGES, xen_start_info->nr_pages); | ||
369 | unsigned long pfn; | ||
370 | |||
371 | xen_max_p2m_pfn = max_pfn; | ||
372 | |||
373 | p2m_missing = extend_brk(PAGE_SIZE, PAGE_SIZE); | ||
374 | p2m_init(p2m_missing); | ||
375 | |||
376 | p2m_mid_missing = extend_brk(PAGE_SIZE, PAGE_SIZE); | ||
377 | p2m_mid_init(p2m_mid_missing); | ||
378 | |||
379 | p2m_top = extend_brk(PAGE_SIZE, PAGE_SIZE); | ||
380 | p2m_top_init(p2m_top); | ||
381 | |||
382 | /* | ||
383 | * The domain builder gives us a pre-constructed p2m array in | ||
384 | * mfn_list for all the pages initially given to us, so we just | ||
385 | * need to graft that into our tree structure. | ||
386 | */ | ||
387 | for (pfn = 0; pfn < max_pfn; pfn += P2M_PER_PAGE) { | ||
388 | unsigned topidx = p2m_top_index(pfn); | ||
389 | unsigned mididx = p2m_mid_index(pfn); | ||
390 | |||
391 | if (p2m_top[topidx] == p2m_mid_missing) { | ||
392 | unsigned long **mid = extend_brk(PAGE_SIZE, PAGE_SIZE); | ||
393 | p2m_mid_init(mid); | ||
394 | |||
395 | p2m_top[topidx] = mid; | ||
396 | } | ||
397 | |||
398 | p2m_top[topidx][mididx] = &mfn_list[pfn]; | ||
399 | } | ||
400 | } | ||
401 | |||
402 | unsigned long get_phys_to_machine(unsigned long pfn) | ||
403 | { | ||
404 | unsigned topidx, mididx, idx; | ||
405 | |||
406 | if (unlikely(pfn >= MAX_P2M_PFN)) | ||
407 | return INVALID_P2M_ENTRY; | ||
408 | |||
409 | topidx = p2m_top_index(pfn); | ||
410 | mididx = p2m_mid_index(pfn); | ||
411 | idx = p2m_index(pfn); | ||
412 | |||
413 | return p2m_top[topidx][mididx][idx]; | ||
414 | } | ||
415 | EXPORT_SYMBOL_GPL(get_phys_to_machine); | ||
416 | |||
417 | static void *alloc_p2m_page(void) | ||
418 | { | ||
419 | return (void *)__get_free_page(GFP_KERNEL | __GFP_REPEAT); | ||
420 | } | ||
421 | |||
422 | static void free_p2m_page(void *p) | ||
423 | { | ||
424 | free_page((unsigned long)p); | ||
425 | } | ||
426 | |||
427 | /* | ||
428 | * Fully allocate the p2m structure for a given pfn. We need to check | ||
429 | * that both the top and mid levels are allocated, and make sure the | ||
430 | * parallel mfn tree is kept in sync. We may race with other cpus, so | ||
431 | * the new pages are installed with cmpxchg; if we lose the race then | ||
432 | * simply free the page we allocated and use the one that's there. | ||
433 | */ | ||
434 | static bool alloc_p2m(unsigned long pfn) | ||
435 | { | ||
436 | unsigned topidx, mididx; | ||
437 | unsigned long ***top_p, **mid; | ||
438 | unsigned long *top_mfn_p, *mid_mfn; | ||
439 | |||
440 | topidx = p2m_top_index(pfn); | ||
441 | mididx = p2m_mid_index(pfn); | ||
442 | |||
443 | top_p = &p2m_top[topidx]; | ||
444 | mid = *top_p; | ||
445 | |||
446 | if (mid == p2m_mid_missing) { | ||
447 | /* Mid level is missing, allocate a new one */ | ||
448 | mid = alloc_p2m_page(); | ||
449 | if (!mid) | ||
450 | return false; | ||
451 | |||
452 | p2m_mid_init(mid); | ||
453 | |||
454 | if (cmpxchg(top_p, p2m_mid_missing, mid) != p2m_mid_missing) | ||
455 | free_p2m_page(mid); | ||
456 | } | ||
457 | |||
458 | top_mfn_p = &p2m_top_mfn[topidx]; | ||
459 | mid_mfn = p2m_top_mfn_p[topidx]; | ||
460 | |||
461 | BUG_ON(virt_to_mfn(mid_mfn) != *top_mfn_p); | ||
462 | |||
463 | if (mid_mfn == p2m_mid_missing_mfn) { | ||
464 | /* Separately check the mid mfn level */ | ||
465 | unsigned long missing_mfn; | ||
466 | unsigned long mid_mfn_mfn; | ||
467 | |||
468 | mid_mfn = alloc_p2m_page(); | ||
469 | if (!mid_mfn) | ||
470 | return false; | ||
471 | |||
472 | p2m_mid_mfn_init(mid_mfn); | ||
473 | |||
474 | missing_mfn = virt_to_mfn(p2m_mid_missing_mfn); | ||
475 | mid_mfn_mfn = virt_to_mfn(mid_mfn); | ||
476 | if (cmpxchg(top_mfn_p, missing_mfn, mid_mfn_mfn) != missing_mfn) | ||
477 | free_p2m_page(mid_mfn); | ||
478 | else | ||
479 | p2m_top_mfn_p[topidx] = mid_mfn; | ||
480 | } | ||
481 | |||
482 | if (p2m_top[topidx][mididx] == p2m_missing) { | ||
483 | /* p2m leaf page is missing */ | ||
484 | unsigned long *p2m; | ||
485 | |||
486 | p2m = alloc_p2m_page(); | ||
487 | if (!p2m) | ||
488 | return false; | ||
489 | |||
490 | p2m_init(p2m); | ||
491 | |||
492 | if (cmpxchg(&mid[mididx], p2m_missing, p2m) != p2m_missing) | ||
493 | free_p2m_page(p2m); | ||
494 | else | ||
495 | mid_mfn[mididx] = virt_to_mfn(p2m); | ||
496 | } | ||
497 | |||
498 | return true; | ||
499 | } | ||
500 | |||
501 | /* Try to install p2m mapping; fail if intermediate bits missing */ | ||
502 | bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn) | ||
503 | { | ||
504 | unsigned topidx, mididx, idx; | ||
505 | |||
506 | if (unlikely(pfn >= MAX_P2M_PFN)) { | ||
507 | BUG_ON(mfn != INVALID_P2M_ENTRY); | ||
508 | return true; | ||
509 | } | ||
510 | |||
511 | topidx = p2m_top_index(pfn); | ||
512 | mididx = p2m_mid_index(pfn); | ||
513 | idx = p2m_index(pfn); | ||
514 | |||
515 | if (p2m_top[topidx][mididx] == p2m_missing) | ||
516 | return mfn == INVALID_P2M_ENTRY; | ||
517 | |||
518 | p2m_top[topidx][mididx][idx] = mfn; | ||
519 | |||
520 | return true; | ||
521 | } | ||
522 | |||
523 | bool set_phys_to_machine(unsigned long pfn, unsigned long mfn) | ||
524 | { | ||
525 | if (unlikely(xen_feature(XENFEAT_auto_translated_physmap))) { | ||
526 | BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY); | ||
527 | return true; | ||
528 | } | ||
529 | |||
530 | if (unlikely(!__set_phys_to_machine(pfn, mfn))) { | ||
531 | if (!alloc_p2m(pfn)) | ||
532 | return false; | ||
533 | |||
534 | if (!__set_phys_to_machine(pfn, mfn)) | ||
535 | return false; | ||
536 | } | ||
537 | |||
538 | return true; | ||
539 | } | ||
540 | |||
541 | unsigned long arbitrary_virt_to_mfn(void *vaddr) | 176 | unsigned long arbitrary_virt_to_mfn(void *vaddr) |
542 | { | 177 | { |
543 | xmaddr_t maddr = arbitrary_virt_to_machine(vaddr); | 178 | xmaddr_t maddr = arbitrary_virt_to_machine(vaddr); |
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c new file mode 100644 index 000000000000..8f2251d2a3f8 --- /dev/null +++ b/arch/x86/xen/p2m.c | |||
@@ -0,0 +1,510 @@ | |||
1 | /* | ||
2 | * Xen leaves the responsibility for maintaining p2m mappings to the | ||
3 | * guests themselves, but it must also access and update the p2m array | ||
4 | * during suspend/resume when all the pages are reallocated. | ||
5 | * | ||
6 | * The p2m table is logically a flat array, but we implement it as a | ||
7 | * three-level tree to allow the address space to be sparse. | ||
8 | * | ||
9 | * Xen | ||
10 | * | | ||
11 | * p2m_top p2m_top_mfn | ||
12 | * / \ / \ | ||
13 | * p2m_mid p2m_mid p2m_mid_mfn p2m_mid_mfn | ||
14 | * / \ / \ / / | ||
15 | * p2m p2m p2m p2m p2m p2m p2m ... | ||
16 | * | ||
17 | * The p2m_mid_mfn pages are mapped by p2m_top_mfn_p. | ||
18 | * | ||
19 | * The p2m_top and p2m_top_mfn levels are limited to 1 page, so the | ||
20 | * maximum representable pseudo-physical address space is: | ||
21 | * P2M_TOP_PER_PAGE * P2M_MID_PER_PAGE * P2M_PER_PAGE pages | ||
22 | * | ||
23 | * P2M_PER_PAGE depends on the architecture, as a mfn is always | ||
24 | * unsigned long (8 bytes on 64-bit, 4 bytes on 32), leading to | ||
25 | * 512 and 1024 entries respectively. | ||
26 | */ | ||
27 | |||
28 | #include <linux/init.h> | ||
29 | #include <linux/module.h> | ||
30 | #include <linux/list.h> | ||
31 | #include <linux/hash.h> | ||
32 | #include <linux/sched.h> | ||
33 | |||
34 | #include <asm/cache.h> | ||
35 | #include <asm/setup.h> | ||
36 | |||
37 | #include <asm/xen/page.h> | ||
38 | #include <asm/xen/hypercall.h> | ||
39 | #include <asm/xen/hypervisor.h> | ||
40 | |||
41 | #include "xen-ops.h" | ||
42 | |||
43 | static void __init m2p_override_init(void); | ||
44 | |||
45 | unsigned long xen_max_p2m_pfn __read_mostly; | ||
46 | |||
47 | #define P2M_PER_PAGE (PAGE_SIZE / sizeof(unsigned long)) | ||
48 | #define P2M_MID_PER_PAGE (PAGE_SIZE / sizeof(unsigned long *)) | ||
49 | #define P2M_TOP_PER_PAGE (PAGE_SIZE / sizeof(unsigned long **)) | ||
50 | |||
51 | #define MAX_P2M_PFN (P2M_TOP_PER_PAGE * P2M_MID_PER_PAGE * P2M_PER_PAGE) | ||
52 | |||
53 | /* Placeholders for holes in the address space */ | ||
54 | static RESERVE_BRK_ARRAY(unsigned long, p2m_missing, P2M_PER_PAGE); | ||
55 | static RESERVE_BRK_ARRAY(unsigned long *, p2m_mid_missing, P2M_MID_PER_PAGE); | ||
56 | static RESERVE_BRK_ARRAY(unsigned long, p2m_mid_missing_mfn, P2M_MID_PER_PAGE); | ||
57 | |||
58 | static RESERVE_BRK_ARRAY(unsigned long **, p2m_top, P2M_TOP_PER_PAGE); | ||
59 | static RESERVE_BRK_ARRAY(unsigned long, p2m_top_mfn, P2M_TOP_PER_PAGE); | ||
60 | static RESERVE_BRK_ARRAY(unsigned long *, p2m_top_mfn_p, P2M_TOP_PER_PAGE); | ||
61 | |||
62 | RESERVE_BRK(p2m_mid, PAGE_SIZE * (MAX_DOMAIN_PAGES / (P2M_PER_PAGE * P2M_MID_PER_PAGE))); | ||
63 | RESERVE_BRK(p2m_mid_mfn, PAGE_SIZE * (MAX_DOMAIN_PAGES / (P2M_PER_PAGE * P2M_MID_PER_PAGE))); | ||
64 | |||
65 | static inline unsigned p2m_top_index(unsigned long pfn) | ||
66 | { | ||
67 | BUG_ON(pfn >= MAX_P2M_PFN); | ||
68 | return pfn / (P2M_MID_PER_PAGE * P2M_PER_PAGE); | ||
69 | } | ||
70 | |||
71 | static inline unsigned p2m_mid_index(unsigned long pfn) | ||
72 | { | ||
73 | return (pfn / P2M_PER_PAGE) % P2M_MID_PER_PAGE; | ||
74 | } | ||
75 | |||
76 | static inline unsigned p2m_index(unsigned long pfn) | ||
77 | { | ||
78 | return pfn % P2M_PER_PAGE; | ||
79 | } | ||
80 | |||
81 | static void p2m_top_init(unsigned long ***top) | ||
82 | { | ||
83 | unsigned i; | ||
84 | |||
85 | for (i = 0; i < P2M_TOP_PER_PAGE; i++) | ||
86 | top[i] = p2m_mid_missing; | ||
87 | } | ||
88 | |||
89 | static void p2m_top_mfn_init(unsigned long *top) | ||
90 | { | ||
91 | unsigned i; | ||
92 | |||
93 | for (i = 0; i < P2M_TOP_PER_PAGE; i++) | ||
94 | top[i] = virt_to_mfn(p2m_mid_missing_mfn); | ||
95 | } | ||
96 | |||
97 | static void p2m_top_mfn_p_init(unsigned long **top) | ||
98 | { | ||
99 | unsigned i; | ||
100 | |||
101 | for (i = 0; i < P2M_TOP_PER_PAGE; i++) | ||
102 | top[i] = p2m_mid_missing_mfn; | ||
103 | } | ||
104 | |||
105 | static void p2m_mid_init(unsigned long **mid) | ||
106 | { | ||
107 | unsigned i; | ||
108 | |||
109 | for (i = 0; i < P2M_MID_PER_PAGE; i++) | ||
110 | mid[i] = p2m_missing; | ||
111 | } | ||
112 | |||
113 | static void p2m_mid_mfn_init(unsigned long *mid) | ||
114 | { | ||
115 | unsigned i; | ||
116 | |||
117 | for (i = 0; i < P2M_MID_PER_PAGE; i++) | ||
118 | mid[i] = virt_to_mfn(p2m_missing); | ||
119 | } | ||
120 | |||
121 | static void p2m_init(unsigned long *p2m) | ||
122 | { | ||
123 | unsigned i; | ||
124 | |||
125 | for (i = 0; i < P2M_MID_PER_PAGE; i++) | ||
126 | p2m[i] = INVALID_P2M_ENTRY; | ||
127 | } | ||
128 | |||
129 | /* | ||
130 | * Build the parallel p2m_top_mfn and p2m_mid_mfn structures | ||
131 | * | ||
132 | * This is called both at boot time, and after resuming from suspend: | ||
133 | * - At boot time we're called very early, and must use extend_brk() | ||
134 | * to allocate memory. | ||
135 | * | ||
136 | * - After resume we're called from within stop_machine, but the mfn | ||
137 | * tree should alreay be completely allocated. | ||
138 | */ | ||
139 | void xen_build_mfn_list_list(void) | ||
140 | { | ||
141 | unsigned long pfn; | ||
142 | |||
143 | /* Pre-initialize p2m_top_mfn to be completely missing */ | ||
144 | if (p2m_top_mfn == NULL) { | ||
145 | p2m_mid_missing_mfn = extend_brk(PAGE_SIZE, PAGE_SIZE); | ||
146 | p2m_mid_mfn_init(p2m_mid_missing_mfn); | ||
147 | |||
148 | p2m_top_mfn_p = extend_brk(PAGE_SIZE, PAGE_SIZE); | ||
149 | p2m_top_mfn_p_init(p2m_top_mfn_p); | ||
150 | |||
151 | p2m_top_mfn = extend_brk(PAGE_SIZE, PAGE_SIZE); | ||
152 | p2m_top_mfn_init(p2m_top_mfn); | ||
153 | } else { | ||
154 | /* Reinitialise, mfn's all change after migration */ | ||
155 | p2m_mid_mfn_init(p2m_mid_missing_mfn); | ||
156 | } | ||
157 | |||
158 | for (pfn = 0; pfn < xen_max_p2m_pfn; pfn += P2M_PER_PAGE) { | ||
159 | unsigned topidx = p2m_top_index(pfn); | ||
160 | unsigned mididx = p2m_mid_index(pfn); | ||
161 | unsigned long **mid; | ||
162 | unsigned long *mid_mfn_p; | ||
163 | |||
164 | mid = p2m_top[topidx]; | ||
165 | mid_mfn_p = p2m_top_mfn_p[topidx]; | ||
166 | |||
167 | /* Don't bother allocating any mfn mid levels if | ||
168 | * they're just missing, just update the stored mfn, | ||
169 | * since all could have changed over a migrate. | ||
170 | */ | ||
171 | if (mid == p2m_mid_missing) { | ||
172 | BUG_ON(mididx); | ||
173 | BUG_ON(mid_mfn_p != p2m_mid_missing_mfn); | ||
174 | p2m_top_mfn[topidx] = virt_to_mfn(p2m_mid_missing_mfn); | ||
175 | pfn += (P2M_MID_PER_PAGE - 1) * P2M_PER_PAGE; | ||
176 | continue; | ||
177 | } | ||
178 | |||
179 | if (mid_mfn_p == p2m_mid_missing_mfn) { | ||
180 | /* | ||
181 | * XXX boot-time only! We should never find | ||
182 | * missing parts of the mfn tree after | ||
183 | * runtime. extend_brk() will BUG if we call | ||
184 | * it too late. | ||
185 | */ | ||
186 | mid_mfn_p = extend_brk(PAGE_SIZE, PAGE_SIZE); | ||
187 | p2m_mid_mfn_init(mid_mfn_p); | ||
188 | |||
189 | p2m_top_mfn_p[topidx] = mid_mfn_p; | ||
190 | } | ||
191 | |||
192 | p2m_top_mfn[topidx] = virt_to_mfn(mid_mfn_p); | ||
193 | mid_mfn_p[mididx] = virt_to_mfn(mid[mididx]); | ||
194 | } | ||
195 | } | ||
196 | |||
197 | void xen_setup_mfn_list_list(void) | ||
198 | { | ||
199 | BUG_ON(HYPERVISOR_shared_info == &xen_dummy_shared_info); | ||
200 | |||
201 | HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list = | ||
202 | virt_to_mfn(p2m_top_mfn); | ||
203 | HYPERVISOR_shared_info->arch.max_pfn = xen_max_p2m_pfn; | ||
204 | } | ||
205 | |||
206 | /* Set up p2m_top to point to the domain-builder provided p2m pages */ | ||
207 | void __init xen_build_dynamic_phys_to_machine(void) | ||
208 | { | ||
209 | unsigned long *mfn_list = (unsigned long *)xen_start_info->mfn_list; | ||
210 | unsigned long max_pfn = min(MAX_DOMAIN_PAGES, xen_start_info->nr_pages); | ||
211 | unsigned long pfn; | ||
212 | |||
213 | xen_max_p2m_pfn = max_pfn; | ||
214 | |||
215 | p2m_missing = extend_brk(PAGE_SIZE, PAGE_SIZE); | ||
216 | p2m_init(p2m_missing); | ||
217 | |||
218 | p2m_mid_missing = extend_brk(PAGE_SIZE, PAGE_SIZE); | ||
219 | p2m_mid_init(p2m_mid_missing); | ||
220 | |||
221 | p2m_top = extend_brk(PAGE_SIZE, PAGE_SIZE); | ||
222 | p2m_top_init(p2m_top); | ||
223 | |||
224 | /* | ||
225 | * The domain builder gives us a pre-constructed p2m array in | ||
226 | * mfn_list for all the pages initially given to us, so we just | ||
227 | * need to graft that into our tree structure. | ||
228 | */ | ||
229 | for (pfn = 0; pfn < max_pfn; pfn += P2M_PER_PAGE) { | ||
230 | unsigned topidx = p2m_top_index(pfn); | ||
231 | unsigned mididx = p2m_mid_index(pfn); | ||
232 | |||
233 | if (p2m_top[topidx] == p2m_mid_missing) { | ||
234 | unsigned long **mid = extend_brk(PAGE_SIZE, PAGE_SIZE); | ||
235 | p2m_mid_init(mid); | ||
236 | |||
237 | p2m_top[topidx] = mid; | ||
238 | } | ||
239 | |||
240 | p2m_top[topidx][mididx] = &mfn_list[pfn]; | ||
241 | } | ||
242 | |||
243 | m2p_override_init(); | ||
244 | } | ||
245 | |||
246 | unsigned long get_phys_to_machine(unsigned long pfn) | ||
247 | { | ||
248 | unsigned topidx, mididx, idx; | ||
249 | |||
250 | if (unlikely(pfn >= MAX_P2M_PFN)) | ||
251 | return INVALID_P2M_ENTRY; | ||
252 | |||
253 | topidx = p2m_top_index(pfn); | ||
254 | mididx = p2m_mid_index(pfn); | ||
255 | idx = p2m_index(pfn); | ||
256 | |||
257 | return p2m_top[topidx][mididx][idx]; | ||
258 | } | ||
259 | EXPORT_SYMBOL_GPL(get_phys_to_machine); | ||
260 | |||
261 | static void *alloc_p2m_page(void) | ||
262 | { | ||
263 | return (void *)__get_free_page(GFP_KERNEL | __GFP_REPEAT); | ||
264 | } | ||
265 | |||
266 | static void free_p2m_page(void *p) | ||
267 | { | ||
268 | free_page((unsigned long)p); | ||
269 | } | ||
270 | |||
271 | /* | ||
272 | * Fully allocate the p2m structure for a given pfn. We need to check | ||
273 | * that both the top and mid levels are allocated, and make sure the | ||
274 | * parallel mfn tree is kept in sync. We may race with other cpus, so | ||
275 | * the new pages are installed with cmpxchg; if we lose the race then | ||
276 | * simply free the page we allocated and use the one that's there. | ||
277 | */ | ||
278 | static bool alloc_p2m(unsigned long pfn) | ||
279 | { | ||
280 | unsigned topidx, mididx; | ||
281 | unsigned long ***top_p, **mid; | ||
282 | unsigned long *top_mfn_p, *mid_mfn; | ||
283 | |||
284 | topidx = p2m_top_index(pfn); | ||
285 | mididx = p2m_mid_index(pfn); | ||
286 | |||
287 | top_p = &p2m_top[topidx]; | ||
288 | mid = *top_p; | ||
289 | |||
290 | if (mid == p2m_mid_missing) { | ||
291 | /* Mid level is missing, allocate a new one */ | ||
292 | mid = alloc_p2m_page(); | ||
293 | if (!mid) | ||
294 | return false; | ||
295 | |||
296 | p2m_mid_init(mid); | ||
297 | |||
298 | if (cmpxchg(top_p, p2m_mid_missing, mid) != p2m_mid_missing) | ||
299 | free_p2m_page(mid); | ||
300 | } | ||
301 | |||
302 | top_mfn_p = &p2m_top_mfn[topidx]; | ||
303 | mid_mfn = p2m_top_mfn_p[topidx]; | ||
304 | |||
305 | BUG_ON(virt_to_mfn(mid_mfn) != *top_mfn_p); | ||
306 | |||
307 | if (mid_mfn == p2m_mid_missing_mfn) { | ||
308 | /* Separately check the mid mfn level */ | ||
309 | unsigned long missing_mfn; | ||
310 | unsigned long mid_mfn_mfn; | ||
311 | |||
312 | mid_mfn = alloc_p2m_page(); | ||
313 | if (!mid_mfn) | ||
314 | return false; | ||
315 | |||
316 | p2m_mid_mfn_init(mid_mfn); | ||
317 | |||
318 | missing_mfn = virt_to_mfn(p2m_mid_missing_mfn); | ||
319 | mid_mfn_mfn = virt_to_mfn(mid_mfn); | ||
320 | if (cmpxchg(top_mfn_p, missing_mfn, mid_mfn_mfn) != missing_mfn) | ||
321 | free_p2m_page(mid_mfn); | ||
322 | else | ||
323 | p2m_top_mfn_p[topidx] = mid_mfn; | ||
324 | } | ||
325 | |||
326 | if (p2m_top[topidx][mididx] == p2m_missing) { | ||
327 | /* p2m leaf page is missing */ | ||
328 | unsigned long *p2m; | ||
329 | |||
330 | p2m = alloc_p2m_page(); | ||
331 | if (!p2m) | ||
332 | return false; | ||
333 | |||
334 | p2m_init(p2m); | ||
335 | |||
336 | if (cmpxchg(&mid[mididx], p2m_missing, p2m) != p2m_missing) | ||
337 | free_p2m_page(p2m); | ||
338 | else | ||
339 | mid_mfn[mididx] = virt_to_mfn(p2m); | ||
340 | } | ||
341 | |||
342 | return true; | ||
343 | } | ||
344 | |||
345 | /* Try to install p2m mapping; fail if intermediate bits missing */ | ||
346 | bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn) | ||
347 | { | ||
348 | unsigned topidx, mididx, idx; | ||
349 | |||
350 | if (unlikely(pfn >= MAX_P2M_PFN)) { | ||
351 | BUG_ON(mfn != INVALID_P2M_ENTRY); | ||
352 | return true; | ||
353 | } | ||
354 | |||
355 | topidx = p2m_top_index(pfn); | ||
356 | mididx = p2m_mid_index(pfn); | ||
357 | idx = p2m_index(pfn); | ||
358 | |||
359 | if (p2m_top[topidx][mididx] == p2m_missing) | ||
360 | return mfn == INVALID_P2M_ENTRY; | ||
361 | |||
362 | p2m_top[topidx][mididx][idx] = mfn; | ||
363 | |||
364 | return true; | ||
365 | } | ||
366 | |||
367 | bool set_phys_to_machine(unsigned long pfn, unsigned long mfn) | ||
368 | { | ||
369 | if (unlikely(xen_feature(XENFEAT_auto_translated_physmap))) { | ||
370 | BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY); | ||
371 | return true; | ||
372 | } | ||
373 | |||
374 | if (unlikely(!__set_phys_to_machine(pfn, mfn))) { | ||
375 | if (!alloc_p2m(pfn)) | ||
376 | return false; | ||
377 | |||
378 | if (!__set_phys_to_machine(pfn, mfn)) | ||
379 | return false; | ||
380 | } | ||
381 | |||
382 | return true; | ||
383 | } | ||
384 | |||
385 | #define M2P_OVERRIDE_HASH_SHIFT 10 | ||
386 | #define M2P_OVERRIDE_HASH (1 << M2P_OVERRIDE_HASH_SHIFT) | ||
387 | |||
388 | static RESERVE_BRK_ARRAY(struct list_head, m2p_overrides, M2P_OVERRIDE_HASH); | ||
389 | static DEFINE_SPINLOCK(m2p_override_lock); | ||
390 | |||
391 | static void __init m2p_override_init(void) | ||
392 | { | ||
393 | unsigned i; | ||
394 | |||
395 | m2p_overrides = extend_brk(sizeof(*m2p_overrides) * M2P_OVERRIDE_HASH, | ||
396 | sizeof(unsigned long)); | ||
397 | |||
398 | for (i = 0; i < M2P_OVERRIDE_HASH; i++) | ||
399 | INIT_LIST_HEAD(&m2p_overrides[i]); | ||
400 | } | ||
401 | |||
402 | static unsigned long mfn_hash(unsigned long mfn) | ||
403 | { | ||
404 | return hash_long(mfn, M2P_OVERRIDE_HASH_SHIFT); | ||
405 | } | ||
406 | |||
407 | /* Add an MFN override for a particular page */ | ||
408 | int m2p_add_override(unsigned long mfn, struct page *page) | ||
409 | { | ||
410 | unsigned long flags; | ||
411 | unsigned long pfn; | ||
412 | unsigned long address; | ||
413 | unsigned level; | ||
414 | pte_t *ptep = NULL; | ||
415 | |||
416 | pfn = page_to_pfn(page); | ||
417 | if (!PageHighMem(page)) { | ||
418 | address = (unsigned long)__va(pfn << PAGE_SHIFT); | ||
419 | ptep = lookup_address(address, &level); | ||
420 | |||
421 | if (WARN(ptep == NULL || level != PG_LEVEL_4K, | ||
422 | "m2p_add_override: pfn %lx not mapped", pfn)) | ||
423 | return -EINVAL; | ||
424 | } | ||
425 | |||
426 | page->private = mfn; | ||
427 | page->index = pfn_to_mfn(pfn); | ||
428 | |||
429 | __set_phys_to_machine(pfn, FOREIGN_FRAME(mfn)); | ||
430 | if (!PageHighMem(page)) | ||
431 | /* Just zap old mapping for now */ | ||
432 | pte_clear(&init_mm, address, ptep); | ||
433 | |||
434 | spin_lock_irqsave(&m2p_override_lock, flags); | ||
435 | list_add(&page->lru, &m2p_overrides[mfn_hash(mfn)]); | ||
436 | spin_unlock_irqrestore(&m2p_override_lock, flags); | ||
437 | |||
438 | return 0; | ||
439 | } | ||
440 | |||
441 | int m2p_remove_override(struct page *page) | ||
442 | { | ||
443 | unsigned long flags; | ||
444 | unsigned long mfn; | ||
445 | unsigned long pfn; | ||
446 | unsigned long address; | ||
447 | unsigned level; | ||
448 | pte_t *ptep = NULL; | ||
449 | |||
450 | pfn = page_to_pfn(page); | ||
451 | mfn = get_phys_to_machine(pfn); | ||
452 | if (mfn == INVALID_P2M_ENTRY || !(mfn & FOREIGN_FRAME_BIT)) | ||
453 | return -EINVAL; | ||
454 | |||
455 | if (!PageHighMem(page)) { | ||
456 | address = (unsigned long)__va(pfn << PAGE_SHIFT); | ||
457 | ptep = lookup_address(address, &level); | ||
458 | |||
459 | if (WARN(ptep == NULL || level != PG_LEVEL_4K, | ||
460 | "m2p_remove_override: pfn %lx not mapped", pfn)) | ||
461 | return -EINVAL; | ||
462 | } | ||
463 | |||
464 | spin_lock_irqsave(&m2p_override_lock, flags); | ||
465 | list_del(&page->lru); | ||
466 | spin_unlock_irqrestore(&m2p_override_lock, flags); | ||
467 | __set_phys_to_machine(pfn, page->index); | ||
468 | |||
469 | if (!PageHighMem(page)) | ||
470 | set_pte_at(&init_mm, address, ptep, | ||
471 | pfn_pte(pfn, PAGE_KERNEL)); | ||
472 | /* No tlb flush necessary because the caller already | ||
473 | * left the pte unmapped. */ | ||
474 | |||
475 | return 0; | ||
476 | } | ||
477 | |||
478 | struct page *m2p_find_override(unsigned long mfn) | ||
479 | { | ||
480 | unsigned long flags; | ||
481 | struct list_head *bucket = &m2p_overrides[mfn_hash(mfn)]; | ||
482 | struct page *p, *ret; | ||
483 | |||
484 | ret = NULL; | ||
485 | |||
486 | spin_lock_irqsave(&m2p_override_lock, flags); | ||
487 | |||
488 | list_for_each_entry(p, bucket, lru) { | ||
489 | if (p->private == mfn) { | ||
490 | ret = p; | ||
491 | break; | ||
492 | } | ||
493 | } | ||
494 | |||
495 | spin_unlock_irqrestore(&m2p_override_lock, flags); | ||
496 | |||
497 | return ret; | ||
498 | } | ||
499 | |||
500 | unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn) | ||
501 | { | ||
502 | struct page *p = m2p_find_override(mfn); | ||
503 | unsigned long ret = pfn; | ||
504 | |||
505 | if (p) | ||
506 | ret = page_to_pfn(p); | ||
507 | |||
508 | return ret; | ||
509 | } | ||
510 | EXPORT_SYMBOL_GPL(m2p_find_override_pfn); | ||
diff --git a/arch/xtensa/include/asm/mman.h b/arch/xtensa/include/asm/mman.h index fca4db425f6e..30789010733d 100644 --- a/arch/xtensa/include/asm/mman.h +++ b/arch/xtensa/include/asm/mman.h | |||
@@ -83,6 +83,9 @@ | |||
83 | #define MADV_MERGEABLE 12 /* KSM may merge identical pages */ | 83 | #define MADV_MERGEABLE 12 /* KSM may merge identical pages */ |
84 | #define MADV_UNMERGEABLE 13 /* KSM may not merge identical pages */ | 84 | #define MADV_UNMERGEABLE 13 /* KSM may not merge identical pages */ |
85 | 85 | ||
86 | #define MADV_HUGEPAGE 14 /* Worth backing with hugepages */ | ||
87 | #define MADV_NOHUGEPAGE 15 /* Not worth backing with hugepages */ | ||
88 | |||
86 | /* compatibility flags */ | 89 | /* compatibility flags */ |
87 | #define MAP_FILE 0 | 90 | #define MAP_FILE 0 |
88 | 91 | ||