diff options
Diffstat (limited to 'arch/x86')
59 files changed, 774 insertions, 419 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index d1430ef6b4f9..738bdc6b0f8b 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
| @@ -1913,25 +1913,26 @@ config DMAR_DEFAULT_ON | |||
| 1913 | recommended you say N here while the DMAR code remains | 1913 | recommended you say N here while the DMAR code remains |
| 1914 | experimental. | 1914 | experimental. |
| 1915 | 1915 | ||
| 1916 | config DMAR_GFX_WA | 1916 | config DMAR_BROKEN_GFX_WA |
| 1917 | def_bool y | 1917 | def_bool n |
| 1918 | prompt "Support for Graphics workaround" | 1918 | prompt "Workaround broken graphics drivers (going away soon)" |
| 1919 | depends on DMAR | 1919 | depends on DMAR |
| 1920 | ---help--- | 1920 | ---help--- |
| 1921 | Current Graphics drivers tend to use physical address | 1921 | Current Graphics drivers tend to use physical address |
| 1922 | for DMA and avoid using DMA APIs. Setting this config | 1922 | for DMA and avoid using DMA APIs. Setting this config |
| 1923 | option permits the IOMMU driver to set a unity map for | 1923 | option permits the IOMMU driver to set a unity map for |
| 1924 | all the OS-visible memory. Hence the driver can continue | 1924 | all the OS-visible memory. Hence the driver can continue |
| 1925 | to use physical addresses for DMA. | 1925 | to use physical addresses for DMA, at least until this |
| 1926 | option is removed in the 2.6.32 kernel. | ||
| 1926 | 1927 | ||
| 1927 | config DMAR_FLOPPY_WA | 1928 | config DMAR_FLOPPY_WA |
| 1928 | def_bool y | 1929 | def_bool y |
| 1929 | depends on DMAR | 1930 | depends on DMAR |
| 1930 | ---help--- | 1931 | ---help--- |
| 1931 | Floppy disk drivers are know to bypass DMA API calls | 1932 | Floppy disk drivers are known to bypass DMA API calls |
| 1932 | thereby failing to work when IOMMU is enabled. This | 1933 | thereby failing to work when IOMMU is enabled. This |
| 1933 | workaround will setup a 1:1 mapping for the first | 1934 | workaround will setup a 1:1 mapping for the first |
| 1934 | 16M to make floppy (an ISA device) work. | 1935 | 16MiB to make floppy (an ISA device) work. |
| 1935 | 1936 | ||
| 1936 | config INTR_REMAP | 1937 | config INTR_REMAP |
| 1937 | bool "Support for Interrupt Remapping (EXPERIMENTAL)" | 1938 | bool "Support for Interrupt Remapping (EXPERIMENTAL)" |
diff --git a/arch/x86/boot/video-bios.c b/arch/x86/boot/video-bios.c index d660be492363..49e0c18833e0 100644 --- a/arch/x86/boot/video-bios.c +++ b/arch/x86/boot/video-bios.c | |||
| @@ -37,14 +37,13 @@ static int set_bios_mode(u8 mode) | |||
| 37 | ireg.al = mode; /* AH=0x00 Set Video Mode */ | 37 | ireg.al = mode; /* AH=0x00 Set Video Mode */ |
| 38 | intcall(0x10, &ireg, NULL); | 38 | intcall(0x10, &ireg, NULL); |
| 39 | 39 | ||
| 40 | |||
| 41 | ireg.ah = 0x0f; /* Get Current Video Mode */ | 40 | ireg.ah = 0x0f; /* Get Current Video Mode */ |
| 42 | intcall(0x10, &ireg, &oreg); | 41 | intcall(0x10, &ireg, &oreg); |
| 43 | 42 | ||
| 44 | do_restore = 1; /* Assume video contents were lost */ | 43 | do_restore = 1; /* Assume video contents were lost */ |
| 45 | 44 | ||
| 46 | /* Not all BIOSes are clean with the top bit */ | 45 | /* Not all BIOSes are clean with the top bit */ |
| 47 | new_mode = ireg.al & 0x7f; | 46 | new_mode = oreg.al & 0x7f; |
| 48 | 47 | ||
| 49 | if (new_mode == mode) | 48 | if (new_mode == mode) |
| 50 | return 0; /* Mode change OK */ | 49 | return 0; /* Mode change OK */ |
diff --git a/arch/x86/boot/video-vesa.c b/arch/x86/boot/video-vesa.c index c700147d6ffb..275dd177f198 100644 --- a/arch/x86/boot/video-vesa.c +++ b/arch/x86/boot/video-vesa.c | |||
| @@ -45,7 +45,7 @@ static int vesa_probe(void) | |||
| 45 | ireg.di = (size_t)&vginfo; | 45 | ireg.di = (size_t)&vginfo; |
| 46 | intcall(0x10, &ireg, &oreg); | 46 | intcall(0x10, &ireg, &oreg); |
| 47 | 47 | ||
| 48 | if (ireg.ax != 0x004f || | 48 | if (oreg.ax != 0x004f || |
| 49 | vginfo.signature != VESA_MAGIC || | 49 | vginfo.signature != VESA_MAGIC || |
| 50 | vginfo.version < 0x0102) | 50 | vginfo.version < 0x0102) |
| 51 | return 0; /* Not present */ | 51 | return 0; /* Not present */ |
| @@ -70,7 +70,7 @@ static int vesa_probe(void) | |||
| 70 | ireg.di = (size_t)&vminfo; | 70 | ireg.di = (size_t)&vminfo; |
| 71 | intcall(0x10, &ireg, &oreg); | 71 | intcall(0x10, &ireg, &oreg); |
| 72 | 72 | ||
| 73 | if (ireg.ax != 0x004f) | 73 | if (oreg.ax != 0x004f) |
| 74 | continue; | 74 | continue; |
| 75 | 75 | ||
| 76 | if ((vminfo.mode_attr & 0x15) == 0x05) { | 76 | if ((vminfo.mode_attr & 0x15) == 0x05) { |
diff --git a/arch/x86/include/asm/atomic_32.h b/arch/x86/include/asm/atomic_32.h index 2503d4e64c2a..dc5a667ff791 100644 --- a/arch/x86/include/asm/atomic_32.h +++ b/arch/x86/include/asm/atomic_32.h | |||
| @@ -19,7 +19,10 @@ | |||
| 19 | * | 19 | * |
| 20 | * Atomically reads the value of @v. | 20 | * Atomically reads the value of @v. |
| 21 | */ | 21 | */ |
| 22 | #define atomic_read(v) ((v)->counter) | 22 | static inline int atomic_read(const atomic_t *v) |
| 23 | { | ||
| 24 | return v->counter; | ||
| 25 | } | ||
| 23 | 26 | ||
| 24 | /** | 27 | /** |
| 25 | * atomic_set - set atomic variable | 28 | * atomic_set - set atomic variable |
| @@ -28,7 +31,10 @@ | |||
| 28 | * | 31 | * |
| 29 | * Atomically sets the value of @v to @i. | 32 | * Atomically sets the value of @v to @i. |
| 30 | */ | 33 | */ |
| 31 | #define atomic_set(v, i) (((v)->counter) = (i)) | 34 | static inline void atomic_set(atomic_t *v, int i) |
| 35 | { | ||
| 36 | v->counter = i; | ||
| 37 | } | ||
| 32 | 38 | ||
| 33 | /** | 39 | /** |
| 34 | * atomic_add - add integer to atomic variable | 40 | * atomic_add - add integer to atomic variable |
| @@ -200,8 +206,15 @@ static inline int atomic_sub_return(int i, atomic_t *v) | |||
| 200 | return atomic_add_return(-i, v); | 206 | return atomic_add_return(-i, v); |
| 201 | } | 207 | } |
| 202 | 208 | ||
| 203 | #define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), (old), (new))) | 209 | static inline int atomic_cmpxchg(atomic_t *v, int old, int new) |
| 204 | #define atomic_xchg(v, new) (xchg(&((v)->counter), (new))) | 210 | { |
| 211 | return cmpxchg(&v->counter, old, new); | ||
| 212 | } | ||
| 213 | |||
| 214 | static inline int atomic_xchg(atomic_t *v, int new) | ||
| 215 | { | ||
| 216 | return xchg(&v->counter, new); | ||
| 217 | } | ||
| 205 | 218 | ||
| 206 | /** | 219 | /** |
| 207 | * atomic_add_unless - add unless the number is already a given value | 220 | * atomic_add_unless - add unless the number is already a given value |
| @@ -250,45 +263,12 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u) | |||
| 250 | /* An 64bit atomic type */ | 263 | /* An 64bit atomic type */ |
| 251 | 264 | ||
| 252 | typedef struct { | 265 | typedef struct { |
| 253 | unsigned long long counter; | 266 | u64 __aligned(8) counter; |
| 254 | } atomic64_t; | 267 | } atomic64_t; |
| 255 | 268 | ||
| 256 | #define ATOMIC64_INIT(val) { (val) } | 269 | #define ATOMIC64_INIT(val) { (val) } |
| 257 | 270 | ||
| 258 | /** | 271 | extern u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old_val, u64 new_val); |
| 259 | * atomic64_read - read atomic64 variable | ||
| 260 | * @ptr: pointer of type atomic64_t | ||
| 261 | * | ||
| 262 | * Atomically reads the value of @v. | ||
| 263 | * Doesn't imply a read memory barrier. | ||
| 264 | */ | ||
| 265 | #define __atomic64_read(ptr) ((ptr)->counter) | ||
| 266 | |||
| 267 | static inline unsigned long long | ||
| 268 | cmpxchg8b(unsigned long long *ptr, unsigned long long old, unsigned long long new) | ||
| 269 | { | ||
| 270 | asm volatile( | ||
| 271 | |||
| 272 | LOCK_PREFIX "cmpxchg8b (%[ptr])\n" | ||
| 273 | |||
| 274 | : "=A" (old) | ||
| 275 | |||
| 276 | : [ptr] "D" (ptr), | ||
| 277 | "A" (old), | ||
| 278 | "b" (ll_low(new)), | ||
| 279 | "c" (ll_high(new)) | ||
| 280 | |||
| 281 | : "memory"); | ||
| 282 | |||
| 283 | return old; | ||
| 284 | } | ||
| 285 | |||
| 286 | static inline unsigned long long | ||
| 287 | atomic64_cmpxchg(atomic64_t *ptr, unsigned long long old_val, | ||
| 288 | unsigned long long new_val) | ||
| 289 | { | ||
| 290 | return cmpxchg8b(&ptr->counter, old_val, new_val); | ||
| 291 | } | ||
| 292 | 272 | ||
| 293 | /** | 273 | /** |
| 294 | * atomic64_xchg - xchg atomic64 variable | 274 | * atomic64_xchg - xchg atomic64 variable |
| @@ -298,18 +278,7 @@ atomic64_cmpxchg(atomic64_t *ptr, unsigned long long old_val, | |||
| 298 | * Atomically xchgs the value of @ptr to @new_val and returns | 278 | * Atomically xchgs the value of @ptr to @new_val and returns |
| 299 | * the old value. | 279 | * the old value. |
| 300 | */ | 280 | */ |
| 301 | 281 | extern u64 atomic64_xchg(atomic64_t *ptr, u64 new_val); | |
| 302 | static inline unsigned long long | ||
| 303 | atomic64_xchg(atomic64_t *ptr, unsigned long long new_val) | ||
| 304 | { | ||
| 305 | unsigned long long old_val; | ||
| 306 | |||
| 307 | do { | ||
| 308 | old_val = atomic_read(ptr); | ||
| 309 | } while (atomic64_cmpxchg(ptr, old_val, new_val) != old_val); | ||
| 310 | |||
| 311 | return old_val; | ||
| 312 | } | ||
| 313 | 282 | ||
| 314 | /** | 283 | /** |
| 315 | * atomic64_set - set atomic64 variable | 284 | * atomic64_set - set atomic64 variable |
| @@ -318,10 +287,7 @@ atomic64_xchg(atomic64_t *ptr, unsigned long long new_val) | |||
| 318 | * | 287 | * |
| 319 | * Atomically sets the value of @ptr to @new_val. | 288 | * Atomically sets the value of @ptr to @new_val. |
| 320 | */ | 289 | */ |
| 321 | static inline void atomic64_set(atomic64_t *ptr, unsigned long long new_val) | 290 | extern void atomic64_set(atomic64_t *ptr, u64 new_val); |
| 322 | { | ||
| 323 | atomic64_xchg(ptr, new_val); | ||
| 324 | } | ||
| 325 | 291 | ||
| 326 | /** | 292 | /** |
| 327 | * atomic64_read - read atomic64 variable | 293 | * atomic64_read - read atomic64 variable |
| @@ -329,17 +295,30 @@ static inline void atomic64_set(atomic64_t *ptr, unsigned long long new_val) | |||
| 329 | * | 295 | * |
| 330 | * Atomically reads the value of @ptr and returns it. | 296 | * Atomically reads the value of @ptr and returns it. |
| 331 | */ | 297 | */ |
| 332 | static inline unsigned long long atomic64_read(atomic64_t *ptr) | 298 | static inline u64 atomic64_read(atomic64_t *ptr) |
| 333 | { | 299 | { |
| 334 | unsigned long long curr_val; | 300 | u64 res; |
| 335 | 301 | ||
| 336 | do { | 302 | /* |
| 337 | curr_val = __atomic64_read(ptr); | 303 | * Note, we inline this atomic64_t primitive because |
| 338 | } while (atomic64_cmpxchg(ptr, curr_val, curr_val) != curr_val); | 304 | * it only clobbers EAX/EDX and leaves the others |
| 339 | 305 | * untouched. We also (somewhat subtly) rely on the | |
| 340 | return curr_val; | 306 | * fact that cmpxchg8b returns the current 64-bit value |
| 307 | * of the memory location we are touching: | ||
| 308 | */ | ||
| 309 | asm volatile( | ||
| 310 | "mov %%ebx, %%eax\n\t" | ||
| 311 | "mov %%ecx, %%edx\n\t" | ||
| 312 | LOCK_PREFIX "cmpxchg8b %1\n" | ||
| 313 | : "=&A" (res) | ||
| 314 | : "m" (*ptr) | ||
| 315 | ); | ||
| 316 | |||
| 317 | return res; | ||
| 341 | } | 318 | } |
| 342 | 319 | ||
| 320 | extern u64 atomic64_read(atomic64_t *ptr); | ||
| 321 | |||
| 343 | /** | 322 | /** |
| 344 | * atomic64_add_return - add and return | 323 | * atomic64_add_return - add and return |
| 345 | * @delta: integer value to add | 324 | * @delta: integer value to add |
| @@ -347,34 +326,14 @@ static inline unsigned long long atomic64_read(atomic64_t *ptr) | |||
| 347 | * | 326 | * |
| 348 | * Atomically adds @delta to @ptr and returns @delta + *@ptr | 327 | * Atomically adds @delta to @ptr and returns @delta + *@ptr |
| 349 | */ | 328 | */ |
| 350 | static inline unsigned long long | 329 | extern u64 atomic64_add_return(u64 delta, atomic64_t *ptr); |
| 351 | atomic64_add_return(unsigned long long delta, atomic64_t *ptr) | ||
| 352 | { | ||
| 353 | unsigned long long old_val, new_val; | ||
| 354 | |||
| 355 | do { | ||
| 356 | old_val = atomic_read(ptr); | ||
| 357 | new_val = old_val + delta; | ||
| 358 | |||
| 359 | } while (atomic64_cmpxchg(ptr, old_val, new_val) != old_val); | ||
| 360 | |||
| 361 | return new_val; | ||
| 362 | } | ||
| 363 | |||
| 364 | static inline long atomic64_sub_return(unsigned long long delta, atomic64_t *ptr) | ||
| 365 | { | ||
| 366 | return atomic64_add_return(-delta, ptr); | ||
| 367 | } | ||
| 368 | 330 | ||
| 369 | static inline long atomic64_inc_return(atomic64_t *ptr) | 331 | /* |
| 370 | { | 332 | * Other variants with different arithmetic operators: |
| 371 | return atomic64_add_return(1, ptr); | 333 | */ |
| 372 | } | 334 | extern u64 atomic64_sub_return(u64 delta, atomic64_t *ptr); |
| 373 | 335 | extern u64 atomic64_inc_return(atomic64_t *ptr); | |
| 374 | static inline long atomic64_dec_return(atomic64_t *ptr) | 336 | extern u64 atomic64_dec_return(atomic64_t *ptr); |
| 375 | { | ||
| 376 | return atomic64_sub_return(1, ptr); | ||
| 377 | } | ||
| 378 | 337 | ||
| 379 | /** | 338 | /** |
| 380 | * atomic64_add - add integer to atomic64 variable | 339 | * atomic64_add - add integer to atomic64 variable |
| @@ -383,10 +342,7 @@ static inline long atomic64_dec_return(atomic64_t *ptr) | |||
| 383 | * | 342 | * |
| 384 | * Atomically adds @delta to @ptr. | 343 | * Atomically adds @delta to @ptr. |
| 385 | */ | 344 | */ |
| 386 | static inline void atomic64_add(unsigned long long delta, atomic64_t *ptr) | 345 | extern void atomic64_add(u64 delta, atomic64_t *ptr); |
| 387 | { | ||
| 388 | atomic64_add_return(delta, ptr); | ||
| 389 | } | ||
| 390 | 346 | ||
| 391 | /** | 347 | /** |
| 392 | * atomic64_sub - subtract the atomic64 variable | 348 | * atomic64_sub - subtract the atomic64 variable |
| @@ -395,10 +351,7 @@ static inline void atomic64_add(unsigned long long delta, atomic64_t *ptr) | |||
| 395 | * | 351 | * |
| 396 | * Atomically subtracts @delta from @ptr. | 352 | * Atomically subtracts @delta from @ptr. |
| 397 | */ | 353 | */ |
| 398 | static inline void atomic64_sub(unsigned long long delta, atomic64_t *ptr) | 354 | extern void atomic64_sub(u64 delta, atomic64_t *ptr); |
| 399 | { | ||
| 400 | atomic64_add(-delta, ptr); | ||
| 401 | } | ||
| 402 | 355 | ||
| 403 | /** | 356 | /** |
| 404 | * atomic64_sub_and_test - subtract value from variable and test result | 357 | * atomic64_sub_and_test - subtract value from variable and test result |
| @@ -409,13 +362,7 @@ static inline void atomic64_sub(unsigned long long delta, atomic64_t *ptr) | |||
| 409 | * true if the result is zero, or false for all | 362 | * true if the result is zero, or false for all |
| 410 | * other cases. | 363 | * other cases. |
| 411 | */ | 364 | */ |
| 412 | static inline int | 365 | extern int atomic64_sub_and_test(u64 delta, atomic64_t *ptr); |
| 413 | atomic64_sub_and_test(unsigned long long delta, atomic64_t *ptr) | ||
| 414 | { | ||
| 415 | unsigned long long old_val = atomic64_sub_return(delta, ptr); | ||
| 416 | |||
| 417 | return old_val == 0; | ||
| 418 | } | ||
| 419 | 366 | ||
| 420 | /** | 367 | /** |
| 421 | * atomic64_inc - increment atomic64 variable | 368 | * atomic64_inc - increment atomic64 variable |
| @@ -423,10 +370,7 @@ atomic64_sub_and_test(unsigned long long delta, atomic64_t *ptr) | |||
| 423 | * | 370 | * |
| 424 | * Atomically increments @ptr by 1. | 371 | * Atomically increments @ptr by 1. |
| 425 | */ | 372 | */ |
| 426 | static inline void atomic64_inc(atomic64_t *ptr) | 373 | extern void atomic64_inc(atomic64_t *ptr); |
| 427 | { | ||
| 428 | atomic64_add(1, ptr); | ||
| 429 | } | ||
| 430 | 374 | ||
| 431 | /** | 375 | /** |
| 432 | * atomic64_dec - decrement atomic64 variable | 376 | * atomic64_dec - decrement atomic64 variable |
| @@ -434,10 +378,7 @@ static inline void atomic64_inc(atomic64_t *ptr) | |||
| 434 | * | 378 | * |
| 435 | * Atomically decrements @ptr by 1. | 379 | * Atomically decrements @ptr by 1. |
| 436 | */ | 380 | */ |
| 437 | static inline void atomic64_dec(atomic64_t *ptr) | 381 | extern void atomic64_dec(atomic64_t *ptr); |
| 438 | { | ||
| 439 | atomic64_sub(1, ptr); | ||
| 440 | } | ||
| 441 | 382 | ||
| 442 | /** | 383 | /** |
| 443 | * atomic64_dec_and_test - decrement and test | 384 | * atomic64_dec_and_test - decrement and test |
| @@ -447,10 +388,7 @@ static inline void atomic64_dec(atomic64_t *ptr) | |||
| 447 | * returns true if the result is 0, or false for all other | 388 | * returns true if the result is 0, or false for all other |
| 448 | * cases. | 389 | * cases. |
| 449 | */ | 390 | */ |
| 450 | static inline int atomic64_dec_and_test(atomic64_t *ptr) | 391 | extern int atomic64_dec_and_test(atomic64_t *ptr); |
| 451 | { | ||
| 452 | return atomic64_sub_and_test(1, ptr); | ||
| 453 | } | ||
| 454 | 392 | ||
| 455 | /** | 393 | /** |
| 456 | * atomic64_inc_and_test - increment and test | 394 | * atomic64_inc_and_test - increment and test |
| @@ -460,10 +398,7 @@ static inline int atomic64_dec_and_test(atomic64_t *ptr) | |||
| 460 | * and returns true if the result is zero, or false for all | 398 | * and returns true if the result is zero, or false for all |
| 461 | * other cases. | 399 | * other cases. |
| 462 | */ | 400 | */ |
| 463 | static inline int atomic64_inc_and_test(atomic64_t *ptr) | 401 | extern int atomic64_inc_and_test(atomic64_t *ptr); |
| 464 | { | ||
| 465 | return atomic64_sub_and_test(-1, ptr); | ||
| 466 | } | ||
| 467 | 402 | ||
| 468 | /** | 403 | /** |
| 469 | * atomic64_add_negative - add and test if negative | 404 | * atomic64_add_negative - add and test if negative |
| @@ -474,13 +409,7 @@ static inline int atomic64_inc_and_test(atomic64_t *ptr) | |||
| 474 | * if the result is negative, or false when | 409 | * if the result is negative, or false when |
| 475 | * result is greater than or equal to zero. | 410 | * result is greater than or equal to zero. |
| 476 | */ | 411 | */ |
| 477 | static inline int | 412 | extern int atomic64_add_negative(u64 delta, atomic64_t *ptr); |
| 478 | atomic64_add_negative(unsigned long long delta, atomic64_t *ptr) | ||
| 479 | { | ||
| 480 | long long old_val = atomic64_add_return(delta, ptr); | ||
| 481 | |||
| 482 | return old_val < 0; | ||
| 483 | } | ||
| 484 | 413 | ||
| 485 | #include <asm-generic/atomic-long.h> | 414 | #include <asm-generic/atomic-long.h> |
| 486 | #endif /* _ASM_X86_ATOMIC_32_H */ | 415 | #endif /* _ASM_X86_ATOMIC_32_H */ |
diff --git a/arch/x86/include/asm/atomic_64.h b/arch/x86/include/asm/atomic_64.h index 0d6360220007..d605dc268e79 100644 --- a/arch/x86/include/asm/atomic_64.h +++ b/arch/x86/include/asm/atomic_64.h | |||
| @@ -18,7 +18,10 @@ | |||
| 18 | * | 18 | * |
| 19 | * Atomically reads the value of @v. | 19 | * Atomically reads the value of @v. |
| 20 | */ | 20 | */ |
| 21 | #define atomic_read(v) ((v)->counter) | 21 | static inline int atomic_read(const atomic_t *v) |
| 22 | { | ||
| 23 | return v->counter; | ||
| 24 | } | ||
| 22 | 25 | ||
| 23 | /** | 26 | /** |
| 24 | * atomic_set - set atomic variable | 27 | * atomic_set - set atomic variable |
| @@ -27,7 +30,10 @@ | |||
| 27 | * | 30 | * |
| 28 | * Atomically sets the value of @v to @i. | 31 | * Atomically sets the value of @v to @i. |
| 29 | */ | 32 | */ |
| 30 | #define atomic_set(v, i) (((v)->counter) = (i)) | 33 | static inline void atomic_set(atomic_t *v, int i) |
| 34 | { | ||
| 35 | v->counter = i; | ||
| 36 | } | ||
| 31 | 37 | ||
| 32 | /** | 38 | /** |
| 33 | * atomic_add - add integer to atomic variable | 39 | * atomic_add - add integer to atomic variable |
| @@ -192,7 +198,10 @@ static inline int atomic_sub_return(int i, atomic_t *v) | |||
| 192 | * Atomically reads the value of @v. | 198 | * Atomically reads the value of @v. |
| 193 | * Doesn't imply a read memory barrier. | 199 | * Doesn't imply a read memory barrier. |
| 194 | */ | 200 | */ |
| 195 | #define atomic64_read(v) ((v)->counter) | 201 | static inline long atomic64_read(const atomic64_t *v) |
| 202 | { | ||
| 203 | return v->counter; | ||
| 204 | } | ||
| 196 | 205 | ||
| 197 | /** | 206 | /** |
| 198 | * atomic64_set - set atomic64 variable | 207 | * atomic64_set - set atomic64 variable |
| @@ -201,7 +210,10 @@ static inline int atomic_sub_return(int i, atomic_t *v) | |||
| 201 | * | 210 | * |
| 202 | * Atomically sets the value of @v to @i. | 211 | * Atomically sets the value of @v to @i. |
| 203 | */ | 212 | */ |
| 204 | #define atomic64_set(v, i) (((v)->counter) = (i)) | 213 | static inline void atomic64_set(atomic64_t *v, long i) |
| 214 | { | ||
| 215 | v->counter = i; | ||
| 216 | } | ||
| 205 | 217 | ||
| 206 | /** | 218 | /** |
| 207 | * atomic64_add - add integer to atomic64 variable | 219 | * atomic64_add - add integer to atomic64 variable |
| @@ -355,11 +367,25 @@ static inline long atomic64_sub_return(long i, atomic64_t *v) | |||
| 355 | #define atomic64_inc_return(v) (atomic64_add_return(1, (v))) | 367 | #define atomic64_inc_return(v) (atomic64_add_return(1, (v))) |
| 356 | #define atomic64_dec_return(v) (atomic64_sub_return(1, (v))) | 368 | #define atomic64_dec_return(v) (atomic64_sub_return(1, (v))) |
| 357 | 369 | ||
| 358 | #define atomic64_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), (old), (new))) | 370 | static inline long atomic64_cmpxchg(atomic64_t *v, long old, long new) |
| 359 | #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) | 371 | { |
| 372 | return cmpxchg(&v->counter, old, new); | ||
| 373 | } | ||
| 374 | |||
| 375 | static inline long atomic64_xchg(atomic64_t *v, long new) | ||
| 376 | { | ||
| 377 | return xchg(&v->counter, new); | ||
| 378 | } | ||
| 360 | 379 | ||
| 361 | #define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), (old), (new))) | 380 | static inline long atomic_cmpxchg(atomic_t *v, int old, int new) |
| 362 | #define atomic_xchg(v, new) (xchg(&((v)->counter), (new))) | 381 | { |
| 382 | return cmpxchg(&v->counter, old, new); | ||
| 383 | } | ||
| 384 | |||
| 385 | static inline long atomic_xchg(atomic_t *v, int new) | ||
| 386 | { | ||
| 387 | return xchg(&v->counter, new); | ||
| 388 | } | ||
| 363 | 389 | ||
| 364 | /** | 390 | /** |
| 365 | * atomic_add_unless - add unless the number is a given value | 391 | * atomic_add_unless - add unless the number is a given value |
diff --git a/arch/x86/include/asm/boot.h b/arch/x86/include/asm/boot.h index 418e632d4a80..7a1065958ba9 100644 --- a/arch/x86/include/asm/boot.h +++ b/arch/x86/include/asm/boot.h | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | 8 | ||
| 9 | #ifdef __KERNEL__ | 9 | #ifdef __KERNEL__ |
| 10 | 10 | ||
| 11 | #include <asm/page_types.h> | 11 | #include <asm/pgtable_types.h> |
| 12 | 12 | ||
| 13 | /* Physical address where kernel should be loaded. */ | 13 | /* Physical address where kernel should be loaded. */ |
| 14 | #define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \ | 14 | #define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \ |
| @@ -16,10 +16,10 @@ | |||
| 16 | & ~(CONFIG_PHYSICAL_ALIGN - 1)) | 16 | & ~(CONFIG_PHYSICAL_ALIGN - 1)) |
| 17 | 17 | ||
| 18 | /* Minimum kernel alignment, as a power of two */ | 18 | /* Minimum kernel alignment, as a power of two */ |
| 19 | #ifdef CONFIG_x86_64 | 19 | #ifdef CONFIG_X86_64 |
| 20 | #define MIN_KERNEL_ALIGN_LG2 PMD_SHIFT | 20 | #define MIN_KERNEL_ALIGN_LG2 PMD_SHIFT |
| 21 | #else | 21 | #else |
| 22 | #define MIN_KERNEL_ALIGN_LG2 (PAGE_SHIFT+1) | 22 | #define MIN_KERNEL_ALIGN_LG2 (PAGE_SHIFT + THREAD_ORDER) |
| 23 | #endif | 23 | #endif |
| 24 | #define MIN_KERNEL_ALIGN (_AC(1, UL) << MIN_KERNEL_ALIGN_LG2) | 24 | #define MIN_KERNEL_ALIGN (_AC(1, UL) << MIN_KERNEL_ALIGN_LG2) |
| 25 | 25 | ||
diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h index 2d81af3974a0..7b2d71df39a6 100644 --- a/arch/x86/include/asm/fixmap.h +++ b/arch/x86/include/asm/fixmap.h | |||
| @@ -111,12 +111,9 @@ enum fixed_addresses { | |||
| 111 | #ifdef CONFIG_PARAVIRT | 111 | #ifdef CONFIG_PARAVIRT |
| 112 | FIX_PARAVIRT_BOOTMAP, | 112 | FIX_PARAVIRT_BOOTMAP, |
| 113 | #endif | 113 | #endif |
| 114 | FIX_TEXT_POKE0, /* reserve 2 pages for text_poke() */ | 114 | FIX_TEXT_POKE1, /* reserve 2 pages for text_poke() */ |
| 115 | FIX_TEXT_POKE1, | 115 | FIX_TEXT_POKE0, /* first page is last, because allocation is backward */ |
| 116 | __end_of_permanent_fixed_addresses, | 116 | __end_of_permanent_fixed_addresses, |
| 117 | #ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT | ||
| 118 | FIX_OHCI1394_BASE, | ||
| 119 | #endif | ||
| 120 | /* | 117 | /* |
| 121 | * 256 temporary boot-time mappings, used by early_ioremap(), | 118 | * 256 temporary boot-time mappings, used by early_ioremap(), |
| 122 | * before ioremap() is functional. | 119 | * before ioremap() is functional. |
| @@ -129,6 +126,9 @@ enum fixed_addresses { | |||
| 129 | FIX_BTMAP_END = __end_of_permanent_fixed_addresses + 256 - | 126 | FIX_BTMAP_END = __end_of_permanent_fixed_addresses + 256 - |
| 130 | (__end_of_permanent_fixed_addresses & 255), | 127 | (__end_of_permanent_fixed_addresses & 255), |
| 131 | FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS*FIX_BTMAPS_SLOTS - 1, | 128 | FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS*FIX_BTMAPS_SLOTS - 1, |
| 129 | #ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT | ||
| 130 | FIX_OHCI1394_BASE, | ||
| 131 | #endif | ||
| 132 | #ifdef CONFIG_X86_32 | 132 | #ifdef CONFIG_X86_32 |
| 133 | FIX_WP_TEST, | 133 | FIX_WP_TEST, |
| 134 | #endif | 134 | #endif |
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 1692fb5050e3..6be7fc254b59 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h | |||
| @@ -246,10 +246,6 @@ | |||
| 246 | #define MSR_IA32_MISC_ENABLE_TURBO_DISABLE (1ULL << 38) | 246 | #define MSR_IA32_MISC_ENABLE_TURBO_DISABLE (1ULL << 38) |
| 247 | #define MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE (1ULL << 39) | 247 | #define MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE (1ULL << 39) |
| 248 | 248 | ||
| 249 | /* Intel Model 6 */ | ||
| 250 | #define MSR_P6_EVNTSEL0 0x00000186 | ||
| 251 | #define MSR_P6_EVNTSEL1 0x00000187 | ||
| 252 | |||
| 253 | /* P4/Xeon+ specific */ | 249 | /* P4/Xeon+ specific */ |
| 254 | #define MSR_IA32_MCG_EAX 0x00000180 | 250 | #define MSR_IA32_MCG_EAX 0x00000180 |
| 255 | #define MSR_IA32_MCG_EBX 0x00000181 | 251 | #define MSR_IA32_MCG_EBX 0x00000181 |
diff --git a/arch/x86/include/asm/nmi.h b/arch/x86/include/asm/nmi.h index c97264409934..c86e5ed4af51 100644 --- a/arch/x86/include/asm/nmi.h +++ b/arch/x86/include/asm/nmi.h | |||
| @@ -72,7 +72,6 @@ void lapic_watchdog_stop(void); | |||
| 72 | int lapic_watchdog_init(unsigned nmi_hz); | 72 | int lapic_watchdog_init(unsigned nmi_hz); |
| 73 | int lapic_wd_event(unsigned nmi_hz); | 73 | int lapic_wd_event(unsigned nmi_hz); |
| 74 | unsigned lapic_adjust_nmi_hz(unsigned hz); | 74 | unsigned lapic_adjust_nmi_hz(unsigned hz); |
| 75 | int lapic_watchdog_ok(void); | ||
| 76 | void disable_lapic_nmi_watchdog(void); | 75 | void disable_lapic_nmi_watchdog(void); |
| 77 | void enable_lapic_nmi_watchdog(void); | 76 | void enable_lapic_nmi_watchdog(void); |
| 78 | void stop_nmi(void); | 77 | void stop_nmi(void); |
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h index 927958d13c19..1ff685ca221c 100644 --- a/arch/x86/include/asm/pci.h +++ b/arch/x86/include/asm/pci.h | |||
| @@ -91,7 +91,7 @@ extern void pci_iommu_alloc(void); | |||
| 91 | 91 | ||
| 92 | #define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys) | 92 | #define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys) |
| 93 | 93 | ||
| 94 | #if defined(CONFIG_X86_64) || defined(CONFIG_DMA_API_DEBUG) | 94 | #if defined(CONFIG_X86_64) || defined(CONFIG_DMAR) || defined(CONFIG_DMA_API_DEBUG) |
| 95 | 95 | ||
| 96 | #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \ | 96 | #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \ |
| 97 | dma_addr_t ADDR_NAME; | 97 | dma_addr_t ADDR_NAME; |
diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h index 02ecb30982a3..103f1ddb0d85 100644 --- a/arch/x86/include/asm/percpu.h +++ b/arch/x86/include/asm/percpu.h | |||
| @@ -42,6 +42,7 @@ | |||
| 42 | 42 | ||
| 43 | #else /* ...!ASSEMBLY */ | 43 | #else /* ...!ASSEMBLY */ |
| 44 | 44 | ||
| 45 | #include <linux/kernel.h> | ||
| 45 | #include <linux/stringify.h> | 46 | #include <linux/stringify.h> |
| 46 | 47 | ||
| 47 | #ifdef CONFIG_SMP | 48 | #ifdef CONFIG_SMP |
| @@ -155,6 +156,15 @@ do { \ | |||
| 155 | /* We can use this directly for local CPU (faster). */ | 156 | /* We can use this directly for local CPU (faster). */ |
| 156 | DECLARE_PER_CPU(unsigned long, this_cpu_off); | 157 | DECLARE_PER_CPU(unsigned long, this_cpu_off); |
| 157 | 158 | ||
| 159 | #ifdef CONFIG_NEED_MULTIPLE_NODES | ||
| 160 | void *pcpu_lpage_remapped(void *kaddr); | ||
| 161 | #else | ||
| 162 | static inline void *pcpu_lpage_remapped(void *kaddr) | ||
| 163 | { | ||
| 164 | return NULL; | ||
| 165 | } | ||
| 166 | #endif | ||
| 167 | |||
| 158 | #endif /* !__ASSEMBLY__ */ | 168 | #endif /* !__ASSEMBLY__ */ |
| 159 | 169 | ||
| 160 | #ifdef CONFIG_SMP | 170 | #ifdef CONFIG_SMP |
diff --git a/arch/x86/include/asm/perf_counter.h b/arch/x86/include/asm/perf_counter.h index 5fb33e160ea0..fa64e401589d 100644 --- a/arch/x86/include/asm/perf_counter.h +++ b/arch/x86/include/asm/perf_counter.h | |||
| @@ -87,6 +87,9 @@ union cpuid10_edx { | |||
| 87 | #ifdef CONFIG_PERF_COUNTERS | 87 | #ifdef CONFIG_PERF_COUNTERS |
| 88 | extern void init_hw_perf_counters(void); | 88 | extern void init_hw_perf_counters(void); |
| 89 | extern void perf_counters_lapic_init(void); | 89 | extern void perf_counters_lapic_init(void); |
| 90 | |||
| 91 | #define PERF_COUNTER_INDEX_OFFSET 0 | ||
| 92 | |||
| 90 | #else | 93 | #else |
| 91 | static inline void init_hw_perf_counters(void) { } | 94 | static inline void init_hw_perf_counters(void) { } |
| 92 | static inline void perf_counters_lapic_init(void) { } | 95 | static inline void perf_counters_lapic_init(void) { } |
diff --git a/arch/x86/include/asm/proto.h b/arch/x86/include/asm/proto.h index 49fb3ecf3bb3..621f56d73121 100644 --- a/arch/x86/include/asm/proto.h +++ b/arch/x86/include/asm/proto.h | |||
| @@ -22,7 +22,14 @@ extern int reboot_force; | |||
| 22 | 22 | ||
| 23 | long do_arch_prctl(struct task_struct *task, int code, unsigned long addr); | 23 | long do_arch_prctl(struct task_struct *task, int code, unsigned long addr); |
| 24 | 24 | ||
| 25 | #define round_up(x, y) (((x) + (y) - 1) & ~((y) - 1)) | 25 | /* |
| 26 | #define round_down(x, y) ((x) & ~((y) - 1)) | 26 | * This looks more complex than it should be. But we need to |
| 27 | * get the type for the ~ right in round_down (it needs to be | ||
| 28 | * as wide as the result!), and we want to evaluate the macro | ||
| 29 | * arguments just once each. | ||
| 30 | */ | ||
| 31 | #define __round_mask(x,y) ((__typeof__(x))((y)-1)) | ||
| 32 | #define round_up(x,y) ((((x)-1) | __round_mask(x,y))+1) | ||
| 33 | #define round_down(x,y) ((x) & ~__round_mask(x,y)) | ||
| 27 | 34 | ||
| 28 | #endif /* _ASM_X86_PROTO_H */ | 35 | #endif /* _ASM_X86_PROTO_H */ |
diff --git a/arch/x86/include/asm/spinlock.h b/arch/x86/include/asm/spinlock.h index b7e5db876399..4e77853321db 100644 --- a/arch/x86/include/asm/spinlock.h +++ b/arch/x86/include/asm/spinlock.h | |||
| @@ -302,4 +302,8 @@ static inline void __raw_write_unlock(raw_rwlock_t *rw) | |||
| 302 | #define _raw_read_relax(lock) cpu_relax() | 302 | #define _raw_read_relax(lock) cpu_relax() |
| 303 | #define _raw_write_relax(lock) cpu_relax() | 303 | #define _raw_write_relax(lock) cpu_relax() |
| 304 | 304 | ||
| 305 | /* The {read|write|spin}_lock() on x86 are full memory barriers. */ | ||
| 306 | static inline void smp_mb__after_lock(void) { } | ||
| 307 | #define ARCH_HAS_SMP_MB_AFTER_LOCK | ||
| 308 | |||
| 305 | #endif /* _ASM_X86_SPINLOCK_H */ | 309 | #endif /* _ASM_X86_SPINLOCK_H */ |
diff --git a/arch/x86/include/asm/stacktrace.h b/arch/x86/include/asm/stacktrace.h index f517944b2b17..cf86a5e73815 100644 --- a/arch/x86/include/asm/stacktrace.h +++ b/arch/x86/include/asm/stacktrace.h | |||
| @@ -3,6 +3,8 @@ | |||
| 3 | 3 | ||
| 4 | extern int kstack_depth_to_print; | 4 | extern int kstack_depth_to_print; |
| 5 | 5 | ||
| 6 | int x86_is_stack_id(int id, char *name); | ||
| 7 | |||
| 6 | /* Generic stack tracer with callbacks */ | 8 | /* Generic stack tracer with callbacks */ |
| 7 | 9 | ||
| 8 | struct stacktrace_ops { | 10 | struct stacktrace_ops { |
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index b0783520988b..fad7d40b75f8 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h | |||
| @@ -49,7 +49,7 @@ struct thread_info { | |||
| 49 | .exec_domain = &default_exec_domain, \ | 49 | .exec_domain = &default_exec_domain, \ |
| 50 | .flags = 0, \ | 50 | .flags = 0, \ |
| 51 | .cpu = 0, \ | 51 | .cpu = 0, \ |
| 52 | .preempt_count = 1, \ | 52 | .preempt_count = INIT_PREEMPT_COUNT, \ |
| 53 | .addr_limit = KERNEL_DS, \ | 53 | .addr_limit = KERNEL_DS, \ |
| 54 | .restart_block = { \ | 54 | .restart_block = { \ |
| 55 | .fn = do_no_restart_syscall, \ | 55 | .fn = do_no_restart_syscall, \ |
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 6c327b852e23..430d5b24af7b 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile | |||
| @@ -26,6 +26,8 @@ CFLAGS_tsc.o := $(nostackp) | |||
| 26 | CFLAGS_paravirt.o := $(nostackp) | 26 | CFLAGS_paravirt.o := $(nostackp) |
| 27 | GCOV_PROFILE_vsyscall_64.o := n | 27 | GCOV_PROFILE_vsyscall_64.o := n |
| 28 | GCOV_PROFILE_hpet.o := n | 28 | GCOV_PROFILE_hpet.o := n |
| 29 | GCOV_PROFILE_tsc.o := n | ||
| 30 | GCOV_PROFILE_paravirt.o := n | ||
| 29 | 31 | ||
| 30 | obj-y := process_$(BITS).o signal.o entry_$(BITS).o | 32 | obj-y := process_$(BITS).o signal.o entry_$(BITS).o |
| 31 | obj-y += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o | 33 | obj-y += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o |
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index 9372f0406ad4..6c99f5037801 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c | |||
| @@ -1192,7 +1192,7 @@ out: | |||
| 1192 | return 0; | 1192 | return 0; |
| 1193 | } | 1193 | } |
| 1194 | 1194 | ||
| 1195 | struct notifier_block device_nb = { | 1195 | static struct notifier_block device_nb = { |
| 1196 | .notifier_call = device_change_notifier, | 1196 | .notifier_call = device_change_notifier, |
| 1197 | }; | 1197 | }; |
| 1198 | 1198 | ||
| @@ -1763,7 +1763,7 @@ static void *alloc_coherent(struct device *dev, size_t size, | |||
| 1763 | flag |= __GFP_ZERO; | 1763 | flag |= __GFP_ZERO; |
| 1764 | virt_addr = (void *)__get_free_pages(flag, get_order(size)); | 1764 | virt_addr = (void *)__get_free_pages(flag, get_order(size)); |
| 1765 | if (!virt_addr) | 1765 | if (!virt_addr) |
| 1766 | return 0; | 1766 | return NULL; |
| 1767 | 1767 | ||
| 1768 | paddr = virt_to_phys(virt_addr); | 1768 | paddr = virt_to_phys(virt_addr); |
| 1769 | 1769 | ||
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index 10b2accd12ea..c1b17e97252e 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c | |||
| @@ -472,6 +472,8 @@ static u8 * __init alloc_event_buffer(struct amd_iommu *iommu) | |||
| 472 | if (iommu->evt_buf == NULL) | 472 | if (iommu->evt_buf == NULL) |
| 473 | return NULL; | 473 | return NULL; |
| 474 | 474 | ||
| 475 | iommu->evt_buf_size = EVT_BUFFER_SIZE; | ||
| 476 | |||
| 475 | return iommu->evt_buf; | 477 | return iommu->evt_buf; |
| 476 | } | 478 | } |
| 477 | 479 | ||
| @@ -691,6 +693,7 @@ static void __init init_iommu_from_acpi(struct amd_iommu *iommu, | |||
| 691 | 693 | ||
| 692 | devid = e->devid; | 694 | devid = e->devid; |
| 693 | devid_to = e->ext >> 8; | 695 | devid_to = e->ext >> 8; |
| 696 | set_dev_entry_from_acpi(iommu, devid , e->flags, 0); | ||
| 694 | set_dev_entry_from_acpi(iommu, devid_to, e->flags, 0); | 697 | set_dev_entry_from_acpi(iommu, devid_to, e->flags, 0); |
| 695 | amd_iommu_alias_table[devid] = devid_to; | 698 | amd_iommu_alias_table[devid] = devid_to; |
| 696 | break; | 699 | break; |
| @@ -749,11 +752,13 @@ static void __init init_iommu_from_acpi(struct amd_iommu *iommu, | |||
| 749 | 752 | ||
| 750 | devid = e->devid; | 753 | devid = e->devid; |
| 751 | for (dev_i = devid_start; dev_i <= devid; ++dev_i) { | 754 | for (dev_i = devid_start; dev_i <= devid; ++dev_i) { |
| 752 | if (alias) | 755 | if (alias) { |
| 753 | amd_iommu_alias_table[dev_i] = devid_to; | 756 | amd_iommu_alias_table[dev_i] = devid_to; |
| 754 | set_dev_entry_from_acpi(iommu, | 757 | set_dev_entry_from_acpi(iommu, |
| 755 | amd_iommu_alias_table[dev_i], | 758 | devid_to, flags, ext_flags); |
| 756 | flags, ext_flags); | 759 | } |
| 760 | set_dev_entry_from_acpi(iommu, dev_i, | ||
| 761 | flags, ext_flags); | ||
| 757 | } | 762 | } |
| 758 | break; | 763 | break; |
| 759 | default: | 764 | default: |
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 8c7c042ecad1..0a1c2830ec66 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
| @@ -140,7 +140,6 @@ int x2apic_mode; | |||
| 140 | #ifdef CONFIG_X86_X2APIC | 140 | #ifdef CONFIG_X86_X2APIC |
| 141 | /* x2apic enabled before OS handover */ | 141 | /* x2apic enabled before OS handover */ |
| 142 | static int x2apic_preenabled; | 142 | static int x2apic_preenabled; |
| 143 | static int disable_x2apic; | ||
| 144 | static __init int setup_nox2apic(char *str) | 143 | static __init int setup_nox2apic(char *str) |
| 145 | { | 144 | { |
| 146 | if (x2apic_enabled()) { | 145 | if (x2apic_enabled()) { |
| @@ -149,7 +148,6 @@ static __init int setup_nox2apic(char *str) | |||
| 149 | return 0; | 148 | return 0; |
| 150 | } | 149 | } |
| 151 | 150 | ||
| 152 | disable_x2apic = 1; | ||
| 153 | setup_clear_cpu_cap(X86_FEATURE_X2APIC); | 151 | setup_clear_cpu_cap(X86_FEATURE_X2APIC); |
| 154 | return 0; | 152 | return 0; |
| 155 | } | 153 | } |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 4d0216fcb36c..90b5e6efa938 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
| @@ -1716,25 +1716,19 @@ __apicdebuginit(void) print_IO_APIC(void) | |||
| 1716 | return; | 1716 | return; |
| 1717 | } | 1717 | } |
| 1718 | 1718 | ||
| 1719 | __apicdebuginit(void) print_APIC_bitfield(int base) | 1719 | __apicdebuginit(void) print_APIC_field(int base) |
| 1720 | { | 1720 | { |
| 1721 | unsigned int v; | 1721 | int i; |
| 1722 | int i, j; | ||
| 1723 | 1722 | ||
| 1724 | if (apic_verbosity == APIC_QUIET) | 1723 | if (apic_verbosity == APIC_QUIET) |
| 1725 | return; | 1724 | return; |
| 1726 | 1725 | ||
| 1727 | printk(KERN_DEBUG "0123456789abcdef0123456789abcdef\n" KERN_DEBUG); | 1726 | printk(KERN_DEBUG); |
| 1728 | for (i = 0; i < 8; i++) { | 1727 | |
| 1729 | v = apic_read(base + i*0x10); | 1728 | for (i = 0; i < 8; i++) |
| 1730 | for (j = 0; j < 32; j++) { | 1729 | printk(KERN_CONT "%08x", apic_read(base + i*0x10)); |
| 1731 | if (v & (1<<j)) | 1730 | |
| 1732 | printk("1"); | 1731 | printk(KERN_CONT "\n"); |
| 1733 | else | ||
| 1734 | printk("0"); | ||
| 1735 | } | ||
| 1736 | printk("\n"); | ||
| 1737 | } | ||
| 1738 | } | 1732 | } |
| 1739 | 1733 | ||
| 1740 | __apicdebuginit(void) print_local_APIC(void *dummy) | 1734 | __apicdebuginit(void) print_local_APIC(void *dummy) |
| @@ -1745,7 +1739,7 @@ __apicdebuginit(void) print_local_APIC(void *dummy) | |||
| 1745 | if (apic_verbosity == APIC_QUIET) | 1739 | if (apic_verbosity == APIC_QUIET) |
| 1746 | return; | 1740 | return; |
| 1747 | 1741 | ||
| 1748 | printk("\n" KERN_DEBUG "printing local APIC contents on CPU#%d/%d:\n", | 1742 | printk(KERN_DEBUG "printing local APIC contents on CPU#%d/%d:\n", |
| 1749 | smp_processor_id(), hard_smp_processor_id()); | 1743 | smp_processor_id(), hard_smp_processor_id()); |
| 1750 | v = apic_read(APIC_ID); | 1744 | v = apic_read(APIC_ID); |
| 1751 | printk(KERN_INFO "... APIC ID: %08x (%01x)\n", v, read_apic_id()); | 1745 | printk(KERN_INFO "... APIC ID: %08x (%01x)\n", v, read_apic_id()); |
| @@ -1786,11 +1780,11 @@ __apicdebuginit(void) print_local_APIC(void *dummy) | |||
| 1786 | printk(KERN_DEBUG "... APIC SPIV: %08x\n", v); | 1780 | printk(KERN_DEBUG "... APIC SPIV: %08x\n", v); |
| 1787 | 1781 | ||
| 1788 | printk(KERN_DEBUG "... APIC ISR field:\n"); | 1782 | printk(KERN_DEBUG "... APIC ISR field:\n"); |
| 1789 | print_APIC_bitfield(APIC_ISR); | 1783 | print_APIC_field(APIC_ISR); |
| 1790 | printk(KERN_DEBUG "... APIC TMR field:\n"); | 1784 | printk(KERN_DEBUG "... APIC TMR field:\n"); |
| 1791 | print_APIC_bitfield(APIC_TMR); | 1785 | print_APIC_field(APIC_TMR); |
| 1792 | printk(KERN_DEBUG "... APIC IRR field:\n"); | 1786 | printk(KERN_DEBUG "... APIC IRR field:\n"); |
| 1793 | print_APIC_bitfield(APIC_IRR); | 1787 | print_APIC_field(APIC_IRR); |
| 1794 | 1788 | ||
| 1795 | if (APIC_INTEGRATED(ver)) { /* !82489DX */ | 1789 | if (APIC_INTEGRATED(ver)) { /* !82489DX */ |
| 1796 | if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */ | 1790 | if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */ |
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index e5b27d8f1b47..28e5f5956042 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c | |||
| @@ -258,13 +258,15 @@ static void __cpuinit amd_detect_cmp(struct cpuinfo_x86 *c) | |||
| 258 | { | 258 | { |
| 259 | #ifdef CONFIG_X86_HT | 259 | #ifdef CONFIG_X86_HT |
| 260 | unsigned bits; | 260 | unsigned bits; |
| 261 | int cpu = smp_processor_id(); | ||
| 261 | 262 | ||
| 262 | bits = c->x86_coreid_bits; | 263 | bits = c->x86_coreid_bits; |
| 263 | |||
| 264 | /* Low order bits define the core id (index of core in socket) */ | 264 | /* Low order bits define the core id (index of core in socket) */ |
| 265 | c->cpu_core_id = c->initial_apicid & ((1 << bits)-1); | 265 | c->cpu_core_id = c->initial_apicid & ((1 << bits)-1); |
| 266 | /* Convert the initial APIC ID into the socket ID */ | 266 | /* Convert the initial APIC ID into the socket ID */ |
| 267 | c->phys_proc_id = c->initial_apicid >> bits; | 267 | c->phys_proc_id = c->initial_apicid >> bits; |
| 268 | /* use socket ID also for last level cache */ | ||
| 269 | per_cpu(cpu_llc_id, cpu) = c->phys_proc_id; | ||
| 268 | #endif | 270 | #endif |
| 269 | } | 271 | } |
| 270 | 272 | ||
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 6b26d4deada0..f1961c07af9a 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
| @@ -848,9 +848,6 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) | |||
| 848 | #if defined(CONFIG_NUMA) && defined(CONFIG_X86_64) | 848 | #if defined(CONFIG_NUMA) && defined(CONFIG_X86_64) |
| 849 | numa_add_cpu(smp_processor_id()); | 849 | numa_add_cpu(smp_processor_id()); |
| 850 | #endif | 850 | #endif |
| 851 | |||
| 852 | /* Cap the iomem address space to what is addressable on all CPUs */ | ||
| 853 | iomem_resource.end &= (1ULL << c->x86_phys_bits) - 1; | ||
| 854 | } | 851 | } |
| 855 | 852 | ||
| 856 | #ifdef CONFIG_X86_64 | 853 | #ifdef CONFIG_X86_64 |
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index 81cbe64ed6b4..2a50ef891000 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c | |||
| @@ -299,7 +299,7 @@ static int transition_pstate(struct powernow_k8_data *data, u32 pstate) | |||
| 299 | static int transition_fid_vid(struct powernow_k8_data *data, | 299 | static int transition_fid_vid(struct powernow_k8_data *data, |
| 300 | u32 reqfid, u32 reqvid) | 300 | u32 reqfid, u32 reqvid) |
| 301 | { | 301 | { |
| 302 | if (core_voltage_pre_transition(data, reqvid)) | 302 | if (core_voltage_pre_transition(data, reqvid, reqfid)) |
| 303 | return 1; | 303 | return 1; |
| 304 | 304 | ||
| 305 | if (core_frequency_transition(data, reqfid)) | 305 | if (core_frequency_transition(data, reqfid)) |
| @@ -327,17 +327,20 @@ static int transition_fid_vid(struct powernow_k8_data *data, | |||
| 327 | 327 | ||
| 328 | /* Phase 1 - core voltage transition ... setup voltage */ | 328 | /* Phase 1 - core voltage transition ... setup voltage */ |
| 329 | static int core_voltage_pre_transition(struct powernow_k8_data *data, | 329 | static int core_voltage_pre_transition(struct powernow_k8_data *data, |
| 330 | u32 reqvid) | 330 | u32 reqvid, u32 reqfid) |
| 331 | { | 331 | { |
| 332 | u32 rvosteps = data->rvo; | 332 | u32 rvosteps = data->rvo; |
| 333 | u32 savefid = data->currfid; | 333 | u32 savefid = data->currfid; |
| 334 | u32 maxvid, lo; | 334 | u32 maxvid, lo, rvomult = 1; |
| 335 | 335 | ||
| 336 | dprintk("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, " | 336 | dprintk("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, " |
| 337 | "reqvid 0x%x, rvo 0x%x\n", | 337 | "reqvid 0x%x, rvo 0x%x\n", |
| 338 | smp_processor_id(), | 338 | smp_processor_id(), |
| 339 | data->currfid, data->currvid, reqvid, data->rvo); | 339 | data->currfid, data->currvid, reqvid, data->rvo); |
| 340 | 340 | ||
| 341 | if ((savefid < LO_FID_TABLE_TOP) && (reqfid < LO_FID_TABLE_TOP)) | ||
| 342 | rvomult = 2; | ||
| 343 | rvosteps *= rvomult; | ||
| 341 | rdmsr(MSR_FIDVID_STATUS, lo, maxvid); | 344 | rdmsr(MSR_FIDVID_STATUS, lo, maxvid); |
| 342 | maxvid = 0x1f & (maxvid >> 16); | 345 | maxvid = 0x1f & (maxvid >> 16); |
| 343 | dprintk("ph1 maxvid=0x%x\n", maxvid); | 346 | dprintk("ph1 maxvid=0x%x\n", maxvid); |
| @@ -351,7 +354,8 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, | |||
| 351 | return 1; | 354 | return 1; |
| 352 | } | 355 | } |
| 353 | 356 | ||
| 354 | while ((rvosteps > 0) && ((data->rvo + data->currvid) > reqvid)) { | 357 | while ((rvosteps > 0) && |
| 358 | ((rvomult * data->rvo + data->currvid) > reqvid)) { | ||
| 355 | if (data->currvid == maxvid) { | 359 | if (data->currvid == maxvid) { |
| 356 | rvosteps = 0; | 360 | rvosteps = 0; |
| 357 | } else { | 361 | } else { |
| @@ -384,13 +388,6 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid) | |||
| 384 | u32 vcoreqfid, vcocurrfid, vcofiddiff; | 388 | u32 vcoreqfid, vcocurrfid, vcofiddiff; |
| 385 | u32 fid_interval, savevid = data->currvid; | 389 | u32 fid_interval, savevid = data->currvid; |
| 386 | 390 | ||
| 387 | if ((reqfid < HI_FID_TABLE_BOTTOM) && | ||
| 388 | (data->currfid < HI_FID_TABLE_BOTTOM)) { | ||
| 389 | printk(KERN_ERR PFX "ph2: illegal lo-lo transition " | ||
| 390 | "0x%x 0x%x\n", reqfid, data->currfid); | ||
| 391 | return 1; | ||
| 392 | } | ||
| 393 | |||
| 394 | if (data->currfid == reqfid) { | 391 | if (data->currfid == reqfid) { |
| 395 | printk(KERN_ERR PFX "ph2 null fid transition 0x%x\n", | 392 | printk(KERN_ERR PFX "ph2 null fid transition 0x%x\n", |
| 396 | data->currfid); | 393 | data->currfid); |
| @@ -407,6 +404,9 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid) | |||
| 407 | vcofiddiff = vcocurrfid > vcoreqfid ? vcocurrfid - vcoreqfid | 404 | vcofiddiff = vcocurrfid > vcoreqfid ? vcocurrfid - vcoreqfid |
| 408 | : vcoreqfid - vcocurrfid; | 405 | : vcoreqfid - vcocurrfid; |
| 409 | 406 | ||
| 407 | if ((reqfid <= LO_FID_TABLE_TOP) && (data->currfid <= LO_FID_TABLE_TOP)) | ||
| 408 | vcofiddiff = 0; | ||
| 409 | |||
| 410 | while (vcofiddiff > 2) { | 410 | while (vcofiddiff > 2) { |
| 411 | (data->currfid & 1) ? (fid_interval = 1) : (fid_interval = 2); | 411 | (data->currfid & 1) ? (fid_interval = 1) : (fid_interval = 2); |
| 412 | 412 | ||
| @@ -1081,14 +1081,6 @@ static int transition_frequency_fidvid(struct powernow_k8_data *data, | |||
| 1081 | return 0; | 1081 | return 0; |
| 1082 | } | 1082 | } |
| 1083 | 1083 | ||
| 1084 | if ((fid < HI_FID_TABLE_BOTTOM) && | ||
| 1085 | (data->currfid < HI_FID_TABLE_BOTTOM)) { | ||
| 1086 | printk(KERN_ERR PFX | ||
| 1087 | "ignoring illegal change in lo freq table-%x to 0x%x\n", | ||
| 1088 | data->currfid, fid); | ||
| 1089 | return 1; | ||
| 1090 | } | ||
| 1091 | |||
| 1092 | dprintk("cpu %d, changing to fid 0x%x, vid 0x%x\n", | 1084 | dprintk("cpu %d, changing to fid 0x%x, vid 0x%x\n", |
| 1093 | smp_processor_id(), fid, vid); | 1085 | smp_processor_id(), fid, vid); |
| 1094 | freqs.old = find_khz_freq_from_fid(data->currfid); | 1086 | freqs.old = find_khz_freq_from_fid(data->currfid); |
| @@ -1267,7 +1259,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
| 1267 | { | 1259 | { |
| 1268 | static const char ACPI_PSS_BIOS_BUG_MSG[] = | 1260 | static const char ACPI_PSS_BIOS_BUG_MSG[] = |
| 1269 | KERN_ERR FW_BUG PFX "No compatible ACPI _PSS objects found.\n" | 1261 | KERN_ERR FW_BUG PFX "No compatible ACPI _PSS objects found.\n" |
| 1270 | KERN_ERR FW_BUG PFX "Try again with latest BIOS.\n"; | 1262 | FW_BUG PFX "Try again with latest BIOS.\n"; |
| 1271 | struct powernow_k8_data *data; | 1263 | struct powernow_k8_data *data; |
| 1272 | struct init_on_cpu init_on_cpu; | 1264 | struct init_on_cpu init_on_cpu; |
| 1273 | int rc; | 1265 | int rc; |
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.h b/arch/x86/kernel/cpu/cpufreq/powernow-k8.h index c9c1190b5e1f..02ce824073cb 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.h +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.h | |||
| @@ -215,7 +215,8 @@ struct pst_s { | |||
| 215 | 215 | ||
| 216 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "powernow-k8", msg) | 216 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "powernow-k8", msg) |
| 217 | 217 | ||
| 218 | static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid); | 218 | static int core_voltage_pre_transition(struct powernow_k8_data *data, |
| 219 | u32 reqvid, u32 regfid); | ||
| 219 | static int core_voltage_post_transition(struct powernow_k8_data *data, u32 reqvid); | 220 | static int core_voltage_post_transition(struct powernow_k8_data *data, u32 reqvid); |
| 220 | static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid); | 221 | static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid); |
| 221 | 222 | ||
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 284d1de968bc..484c1e5f658e 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
| @@ -194,14 +194,14 @@ static void print_mce(struct mce *m) | |||
| 194 | m->cs, m->ip); | 194 | m->cs, m->ip); |
| 195 | if (m->cs == __KERNEL_CS) | 195 | if (m->cs == __KERNEL_CS) |
| 196 | print_symbol("{%s}", m->ip); | 196 | print_symbol("{%s}", m->ip); |
| 197 | printk("\n"); | 197 | printk(KERN_CONT "\n"); |
| 198 | } | 198 | } |
| 199 | printk(KERN_EMERG "TSC %llx ", m->tsc); | 199 | printk(KERN_EMERG "TSC %llx ", m->tsc); |
| 200 | if (m->addr) | 200 | if (m->addr) |
| 201 | printk("ADDR %llx ", m->addr); | 201 | printk(KERN_CONT "ADDR %llx ", m->addr); |
| 202 | if (m->misc) | 202 | if (m->misc) |
| 203 | printk("MISC %llx ", m->misc); | 203 | printk(KERN_CONT "MISC %llx ", m->misc); |
| 204 | printk("\n"); | 204 | printk(KERN_CONT "\n"); |
| 205 | printk(KERN_EMERG "PROCESSOR %u:%x TIME %llu SOCKET %u APIC %x\n", | 205 | printk(KERN_EMERG "PROCESSOR %u:%x TIME %llu SOCKET %u APIC %x\n", |
| 206 | m->cpuvendor, m->cpuid, m->time, m->socketid, | 206 | m->cpuvendor, m->cpuid, m->time, m->socketid, |
| 207 | m->apicid); | 207 | m->apicid); |
| @@ -209,13 +209,13 @@ static void print_mce(struct mce *m) | |||
| 209 | 209 | ||
| 210 | static void print_mce_head(void) | 210 | static void print_mce_head(void) |
| 211 | { | 211 | { |
| 212 | printk(KERN_EMERG "\n" KERN_EMERG "HARDWARE ERROR\n"); | 212 | printk(KERN_EMERG "\nHARDWARE ERROR\n"); |
| 213 | } | 213 | } |
| 214 | 214 | ||
| 215 | static void print_mce_tail(void) | 215 | static void print_mce_tail(void) |
| 216 | { | 216 | { |
| 217 | printk(KERN_EMERG "This is not a software problem!\n" | 217 | printk(KERN_EMERG "This is not a software problem!\n" |
| 218 | KERN_EMERG "Run through mcelog --ascii to decode and contact your hardware vendor\n"); | 218 | "Run through mcelog --ascii to decode and contact your hardware vendor\n"); |
| 219 | } | 219 | } |
| 220 | 220 | ||
| 221 | #define PANIC_TIMEOUT 5 /* 5 seconds */ | 221 | #define PANIC_TIMEOUT 5 /* 5 seconds */ |
| @@ -1117,7 +1117,7 @@ static void mcheck_timer(unsigned long data) | |||
| 1117 | *n = min(*n*2, (int)round_jiffies_relative(check_interval*HZ)); | 1117 | *n = min(*n*2, (int)round_jiffies_relative(check_interval*HZ)); |
| 1118 | 1118 | ||
| 1119 | t->expires = jiffies + *n; | 1119 | t->expires = jiffies + *n; |
| 1120 | add_timer(t); | 1120 | add_timer_on(t, smp_processor_id()); |
| 1121 | } | 1121 | } |
| 1122 | 1122 | ||
| 1123 | static void mce_do_trigger(struct work_struct *work) | 1123 | static void mce_do_trigger(struct work_struct *work) |
| @@ -1321,7 +1321,7 @@ static void mce_init_timer(void) | |||
| 1321 | return; | 1321 | return; |
| 1322 | setup_timer(t, mcheck_timer, smp_processor_id()); | 1322 | setup_timer(t, mcheck_timer, smp_processor_id()); |
| 1323 | t->expires = round_jiffies(jiffies + *n); | 1323 | t->expires = round_jiffies(jiffies + *n); |
| 1324 | add_timer(t); | 1324 | add_timer_on(t, smp_processor_id()); |
| 1325 | } | 1325 | } |
| 1326 | 1326 | ||
| 1327 | /* | 1327 | /* |
diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 76dfef23f789..36c3dc7b8991 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c | |||
| @@ -401,7 +401,7 @@ static const u64 amd_hw_cache_event_ids | |||
| 401 | [ C(RESULT_MISS) ] = 0x0041, /* Data Cache Misses */ | 401 | [ C(RESULT_MISS) ] = 0x0041, /* Data Cache Misses */ |
| 402 | }, | 402 | }, |
| 403 | [ C(OP_WRITE) ] = { | 403 | [ C(OP_WRITE) ] = { |
| 404 | [ C(RESULT_ACCESS) ] = 0x0042, /* Data Cache Refills from L2 */ | 404 | [ C(RESULT_ACCESS) ] = 0x0142, /* Data Cache Refills :system */ |
| 405 | [ C(RESULT_MISS) ] = 0, | 405 | [ C(RESULT_MISS) ] = 0, |
| 406 | }, | 406 | }, |
| 407 | [ C(OP_PREFETCH) ] = { | 407 | [ C(OP_PREFETCH) ] = { |
| @@ -912,6 +912,8 @@ x86_perf_counter_set_period(struct perf_counter *counter, | |||
| 912 | err = checking_wrmsrl(hwc->counter_base + idx, | 912 | err = checking_wrmsrl(hwc->counter_base + idx, |
| 913 | (u64)(-left) & x86_pmu.counter_mask); | 913 | (u64)(-left) & x86_pmu.counter_mask); |
| 914 | 914 | ||
| 915 | perf_counter_update_userpage(counter); | ||
| 916 | |||
| 915 | return ret; | 917 | return ret; |
| 916 | } | 918 | } |
| 917 | 919 | ||
| @@ -969,13 +971,6 @@ fixed_mode_idx(struct perf_counter *counter, struct hw_perf_counter *hwc) | |||
| 969 | if (!x86_pmu.num_counters_fixed) | 971 | if (!x86_pmu.num_counters_fixed) |
| 970 | return -1; | 972 | return -1; |
| 971 | 973 | ||
| 972 | /* | ||
| 973 | * Quirk, IA32_FIXED_CTRs do not work on current Atom processors: | ||
| 974 | */ | ||
| 975 | if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && | ||
| 976 | boot_cpu_data.x86_model == 28) | ||
| 977 | return -1; | ||
| 978 | |||
| 979 | event = hwc->config & ARCH_PERFMON_EVENT_MASK; | 974 | event = hwc->config & ARCH_PERFMON_EVENT_MASK; |
| 980 | 975 | ||
| 981 | if (unlikely(event == x86_pmu.event_map(PERF_COUNT_HW_INSTRUCTIONS))) | 976 | if (unlikely(event == x86_pmu.event_map(PERF_COUNT_HW_INSTRUCTIONS))) |
| @@ -1041,6 +1036,8 @@ try_generic: | |||
| 1041 | x86_perf_counter_set_period(counter, hwc, idx); | 1036 | x86_perf_counter_set_period(counter, hwc, idx); |
| 1042 | x86_pmu.enable(hwc, idx); | 1037 | x86_pmu.enable(hwc, idx); |
| 1043 | 1038 | ||
| 1039 | perf_counter_update_userpage(counter); | ||
| 1040 | |||
| 1044 | return 0; | 1041 | return 0; |
| 1045 | } | 1042 | } |
| 1046 | 1043 | ||
| @@ -1133,6 +1130,8 @@ static void x86_pmu_disable(struct perf_counter *counter) | |||
| 1133 | x86_perf_counter_update(counter, hwc, idx); | 1130 | x86_perf_counter_update(counter, hwc, idx); |
| 1134 | cpuc->counters[idx] = NULL; | 1131 | cpuc->counters[idx] = NULL; |
| 1135 | clear_bit(idx, cpuc->used_mask); | 1132 | clear_bit(idx, cpuc->used_mask); |
| 1133 | |||
| 1134 | perf_counter_update_userpage(counter); | ||
| 1136 | } | 1135 | } |
| 1137 | 1136 | ||
| 1138 | /* | 1137 | /* |
| @@ -1428,8 +1427,6 @@ static int intel_pmu_init(void) | |||
| 1428 | */ | 1427 | */ |
| 1429 | x86_pmu.num_counters_fixed = max((int)edx.split.num_counters_fixed, 3); | 1428 | x86_pmu.num_counters_fixed = max((int)edx.split.num_counters_fixed, 3); |
| 1430 | 1429 | ||
| 1431 | rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, x86_pmu.intel_ctrl); | ||
| 1432 | |||
| 1433 | /* | 1430 | /* |
| 1434 | * Install the hw-cache-events table: | 1431 | * Install the hw-cache-events table: |
| 1435 | */ | 1432 | */ |
| @@ -1499,21 +1496,22 @@ void __init init_hw_perf_counters(void) | |||
| 1499 | pr_cont("%s PMU driver.\n", x86_pmu.name); | 1496 | pr_cont("%s PMU driver.\n", x86_pmu.name); |
| 1500 | 1497 | ||
| 1501 | if (x86_pmu.num_counters > X86_PMC_MAX_GENERIC) { | 1498 | if (x86_pmu.num_counters > X86_PMC_MAX_GENERIC) { |
| 1502 | x86_pmu.num_counters = X86_PMC_MAX_GENERIC; | ||
| 1503 | WARN(1, KERN_ERR "hw perf counters %d > max(%d), clipping!", | 1499 | WARN(1, KERN_ERR "hw perf counters %d > max(%d), clipping!", |
| 1504 | x86_pmu.num_counters, X86_PMC_MAX_GENERIC); | 1500 | x86_pmu.num_counters, X86_PMC_MAX_GENERIC); |
| 1501 | x86_pmu.num_counters = X86_PMC_MAX_GENERIC; | ||
| 1505 | } | 1502 | } |
| 1506 | perf_counter_mask = (1 << x86_pmu.num_counters) - 1; | 1503 | perf_counter_mask = (1 << x86_pmu.num_counters) - 1; |
| 1507 | perf_max_counters = x86_pmu.num_counters; | 1504 | perf_max_counters = x86_pmu.num_counters; |
| 1508 | 1505 | ||
| 1509 | if (x86_pmu.num_counters_fixed > X86_PMC_MAX_FIXED) { | 1506 | if (x86_pmu.num_counters_fixed > X86_PMC_MAX_FIXED) { |
| 1510 | x86_pmu.num_counters_fixed = X86_PMC_MAX_FIXED; | ||
| 1511 | WARN(1, KERN_ERR "hw perf counters fixed %d > max(%d), clipping!", | 1507 | WARN(1, KERN_ERR "hw perf counters fixed %d > max(%d), clipping!", |
| 1512 | x86_pmu.num_counters_fixed, X86_PMC_MAX_FIXED); | 1508 | x86_pmu.num_counters_fixed, X86_PMC_MAX_FIXED); |
| 1509 | x86_pmu.num_counters_fixed = X86_PMC_MAX_FIXED; | ||
| 1513 | } | 1510 | } |
| 1514 | 1511 | ||
| 1515 | perf_counter_mask |= | 1512 | perf_counter_mask |= |
| 1516 | ((1LL << x86_pmu.num_counters_fixed)-1) << X86_PMC_IDX_FIXED; | 1513 | ((1LL << x86_pmu.num_counters_fixed)-1) << X86_PMC_IDX_FIXED; |
| 1514 | x86_pmu.intel_ctrl = perf_counter_mask; | ||
| 1517 | 1515 | ||
| 1518 | perf_counters_lapic_init(); | 1516 | perf_counters_lapic_init(); |
| 1519 | register_die_notifier(&perf_counter_nmi_notifier); | 1517 | register_die_notifier(&perf_counter_nmi_notifier); |
| @@ -1563,6 +1561,7 @@ void callchain_store(struct perf_callchain_entry *entry, u64 ip) | |||
| 1563 | 1561 | ||
| 1564 | static DEFINE_PER_CPU(struct perf_callchain_entry, irq_entry); | 1562 | static DEFINE_PER_CPU(struct perf_callchain_entry, irq_entry); |
| 1565 | static DEFINE_PER_CPU(struct perf_callchain_entry, nmi_entry); | 1563 | static DEFINE_PER_CPU(struct perf_callchain_entry, nmi_entry); |
| 1564 | static DEFINE_PER_CPU(int, in_nmi_frame); | ||
| 1566 | 1565 | ||
| 1567 | 1566 | ||
| 1568 | static void | 1567 | static void |
| @@ -1578,7 +1577,9 @@ static void backtrace_warning(void *data, char *msg) | |||
| 1578 | 1577 | ||
| 1579 | static int backtrace_stack(void *data, char *name) | 1578 | static int backtrace_stack(void *data, char *name) |
| 1580 | { | 1579 | { |
| 1581 | /* Process all stacks: */ | 1580 | per_cpu(in_nmi_frame, smp_processor_id()) = |
| 1581 | x86_is_stack_id(NMI_STACK, name); | ||
| 1582 | |||
| 1582 | return 0; | 1583 | return 0; |
| 1583 | } | 1584 | } |
| 1584 | 1585 | ||
| @@ -1586,6 +1587,9 @@ static void backtrace_address(void *data, unsigned long addr, int reliable) | |||
| 1586 | { | 1587 | { |
| 1587 | struct perf_callchain_entry *entry = data; | 1588 | struct perf_callchain_entry *entry = data; |
| 1588 | 1589 | ||
| 1590 | if (per_cpu(in_nmi_frame, smp_processor_id())) | ||
| 1591 | return; | ||
| 1592 | |||
| 1589 | if (reliable) | 1593 | if (reliable) |
| 1590 | callchain_store(entry, addr); | 1594 | callchain_store(entry, addr); |
| 1591 | } | 1595 | } |
diff --git a/arch/x86/kernel/cpu/perfctr-watchdog.c b/arch/x86/kernel/cpu/perfctr-watchdog.c index 5c481f6205bf..e60ed740d2b3 100644 --- a/arch/x86/kernel/cpu/perfctr-watchdog.c +++ b/arch/x86/kernel/cpu/perfctr-watchdog.c | |||
| @@ -803,8 +803,3 @@ int __kprobes lapic_wd_event(unsigned nmi_hz) | |||
| 803 | wd_ops->rearm(wd, nmi_hz); | 803 | wd_ops->rearm(wd, nmi_hz); |
| 804 | return 1; | 804 | return 1; |
| 805 | } | 805 | } |
| 806 | |||
| 807 | int lapic_watchdog_ok(void) | ||
| 808 | { | ||
| 809 | return wd_ops != NULL; | ||
| 810 | } | ||
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c index 95ea5fa7d444..c8405718a4c3 100644 --- a/arch/x86/kernel/dumpstack.c +++ b/arch/x86/kernel/dumpstack.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include "dumpstack.h" | 22 | #include "dumpstack.h" |
| 23 | 23 | ||
| 24 | int panic_on_unrecovered_nmi; | 24 | int panic_on_unrecovered_nmi; |
| 25 | int panic_on_io_nmi; | ||
| 25 | unsigned int code_bytes = 64; | 26 | unsigned int code_bytes = 64; |
| 26 | int kstack_depth_to_print = 3 * STACKSLOTS_PER_LINE; | 27 | int kstack_depth_to_print = 3 * STACKSLOTS_PER_LINE; |
| 27 | static int die_counter; | 28 | static int die_counter; |
diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c index d593cd1f58dc..bca5fba91c9e 100644 --- a/arch/x86/kernel/dumpstack_32.c +++ b/arch/x86/kernel/dumpstack_32.c | |||
| @@ -19,6 +19,12 @@ | |||
| 19 | 19 | ||
| 20 | #include "dumpstack.h" | 20 | #include "dumpstack.h" |
| 21 | 21 | ||
| 22 | /* Just a stub for now */ | ||
| 23 | int x86_is_stack_id(int id, char *name) | ||
| 24 | { | ||
| 25 | return 0; | ||
| 26 | } | ||
| 27 | |||
| 22 | void dump_trace(struct task_struct *task, struct pt_regs *regs, | 28 | void dump_trace(struct task_struct *task, struct pt_regs *regs, |
| 23 | unsigned long *stack, unsigned long bp, | 29 | unsigned long *stack, unsigned long bp, |
| 24 | const struct stacktrace_ops *ops, void *data) | 30 | const struct stacktrace_ops *ops, void *data) |
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c index d35db5993fd6..54b0a3276766 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c | |||
| @@ -19,10 +19,8 @@ | |||
| 19 | 19 | ||
| 20 | #include "dumpstack.h" | 20 | #include "dumpstack.h" |
| 21 | 21 | ||
| 22 | static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, | 22 | |
| 23 | unsigned *usedp, char **idp) | 23 | static char x86_stack_ids[][8] = { |
| 24 | { | ||
| 25 | static char ids[][8] = { | ||
| 26 | [DEBUG_STACK - 1] = "#DB", | 24 | [DEBUG_STACK - 1] = "#DB", |
| 27 | [NMI_STACK - 1] = "NMI", | 25 | [NMI_STACK - 1] = "NMI", |
| 28 | [DOUBLEFAULT_STACK - 1] = "#DF", | 26 | [DOUBLEFAULT_STACK - 1] = "#DF", |
| @@ -33,6 +31,15 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, | |||
| 33 | N_EXCEPTION_STACKS + DEBUG_STKSZ / EXCEPTION_STKSZ - 2] = "#DB[?]" | 31 | N_EXCEPTION_STACKS + DEBUG_STKSZ / EXCEPTION_STKSZ - 2] = "#DB[?]" |
| 34 | #endif | 32 | #endif |
| 35 | }; | 33 | }; |
| 34 | |||
| 35 | int x86_is_stack_id(int id, char *name) | ||
| 36 | { | ||
| 37 | return x86_stack_ids[id - 1] == name; | ||
| 38 | } | ||
| 39 | |||
| 40 | static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, | ||
| 41 | unsigned *usedp, char **idp) | ||
| 42 | { | ||
| 36 | unsigned k; | 43 | unsigned k; |
| 37 | 44 | ||
| 38 | /* | 45 | /* |
| @@ -61,7 +68,7 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, | |||
| 61 | if (*usedp & (1U << k)) | 68 | if (*usedp & (1U << k)) |
| 62 | break; | 69 | break; |
| 63 | *usedp |= 1U << k; | 70 | *usedp |= 1U << k; |
| 64 | *idp = ids[k]; | 71 | *idp = x86_stack_ids[k]; |
| 65 | return (unsigned long *)end; | 72 | return (unsigned long *)end; |
| 66 | } | 73 | } |
| 67 | /* | 74 | /* |
| @@ -81,12 +88,13 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, | |||
| 81 | do { | 88 | do { |
| 82 | ++j; | 89 | ++j; |
| 83 | end -= EXCEPTION_STKSZ; | 90 | end -= EXCEPTION_STKSZ; |
| 84 | ids[j][4] = '1' + (j - N_EXCEPTION_STACKS); | 91 | x86_stack_ids[j][4] = '1' + |
| 92 | (j - N_EXCEPTION_STACKS); | ||
| 85 | } while (stack < end - EXCEPTION_STKSZ); | 93 | } while (stack < end - EXCEPTION_STKSZ); |
| 86 | if (*usedp & (1U << j)) | 94 | if (*usedp & (1U << j)) |
| 87 | break; | 95 | break; |
| 88 | *usedp |= 1U << j; | 96 | *usedp |= 1U << j; |
| 89 | *idp = ids[j]; | 97 | *idp = x86_stack_ids[j]; |
| 90 | return (unsigned long *)end; | 98 | return (unsigned long *)end; |
| 91 | } | 99 | } |
| 92 | #endif | 100 | #endif |
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 7271fa33d791..5cb5725b2bae 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c | |||
| @@ -627,10 +627,9 @@ __init void e820_setup_gap(void) | |||
| 627 | #ifdef CONFIG_X86_64 | 627 | #ifdef CONFIG_X86_64 |
| 628 | if (!found) { | 628 | if (!found) { |
| 629 | gapstart = (max_pfn << PAGE_SHIFT) + 1024*1024; | 629 | gapstart = (max_pfn << PAGE_SHIFT) + 1024*1024; |
| 630 | printk(KERN_ERR "PCI: Warning: Cannot find a gap in the 32bit " | 630 | printk(KERN_ERR |
| 631 | "address range\n" | 631 | "PCI: Warning: Cannot find a gap in the 32bit address range\n" |
| 632 | KERN_ERR "PCI: Unassigned devices with 32bit resource " | 632 | "PCI: Unassigned devices with 32bit resource registers may break!\n"); |
| 633 | "registers may break!\n"); | ||
| 634 | } | 633 | } |
| 635 | #endif | 634 | #endif |
| 636 | 635 | ||
| @@ -1383,6 +1382,8 @@ static unsigned long ram_alignment(resource_size_t pos) | |||
| 1383 | return 32*1024*1024; | 1382 | return 32*1024*1024; |
| 1384 | } | 1383 | } |
| 1385 | 1384 | ||
| 1385 | #define MAX_RESOURCE_SIZE ((resource_size_t)-1) | ||
| 1386 | |||
| 1386 | void __init e820_reserve_resources_late(void) | 1387 | void __init e820_reserve_resources_late(void) |
| 1387 | { | 1388 | { |
| 1388 | int i; | 1389 | int i; |
| @@ -1400,17 +1401,19 @@ void __init e820_reserve_resources_late(void) | |||
| 1400 | * avoid stolen RAM: | 1401 | * avoid stolen RAM: |
| 1401 | */ | 1402 | */ |
| 1402 | for (i = 0; i < e820.nr_map; i++) { | 1403 | for (i = 0; i < e820.nr_map; i++) { |
| 1403 | struct e820entry *entry = &e820_saved.map[i]; | 1404 | struct e820entry *entry = &e820.map[i]; |
| 1404 | resource_size_t start, end; | 1405 | u64 start, end; |
| 1405 | 1406 | ||
| 1406 | if (entry->type != E820_RAM) | 1407 | if (entry->type != E820_RAM) |
| 1407 | continue; | 1408 | continue; |
| 1408 | start = entry->addr + entry->size; | 1409 | start = entry->addr + entry->size; |
| 1409 | end = round_up(start, ram_alignment(start)); | 1410 | end = round_up(start, ram_alignment(start)) - 1; |
| 1410 | if (start == end) | 1411 | if (end > MAX_RESOURCE_SIZE) |
| 1412 | end = MAX_RESOURCE_SIZE; | ||
| 1413 | if (start >= end) | ||
| 1411 | continue; | 1414 | continue; |
| 1412 | reserve_region_with_split(&iomem_resource, start, | 1415 | reserve_region_with_split(&iomem_resource, start, end, |
| 1413 | end - 1, "RAM buffer"); | 1416 | "RAM buffer"); |
| 1414 | } | 1417 | } |
| 1415 | } | 1418 | } |
| 1416 | 1419 | ||
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index a78ecad0c900..c664d515f613 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c | |||
| @@ -200,7 +200,7 @@ static void kvm_leave_lazy_mmu(void) | |||
| 200 | state->mode = paravirt_get_lazy_mode(); | 200 | state->mode = paravirt_get_lazy_mode(); |
| 201 | } | 201 | } |
| 202 | 202 | ||
| 203 | static void paravirt_ops_setup(void) | 203 | static void __init paravirt_ops_setup(void) |
| 204 | { | 204 | { |
| 205 | pv_info.name = "KVM"; | 205 | pv_info.name = "KVM"; |
| 206 | pv_info.paravirt_enabled = 1; | 206 | pv_info.paravirt_enabled = 1; |
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index 47630479b067..1a041bcf506b 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c | |||
| @@ -211,11 +211,11 @@ static __init int iommu_setup(char *p) | |||
| 211 | #ifdef CONFIG_SWIOTLB | 211 | #ifdef CONFIG_SWIOTLB |
| 212 | if (!strncmp(p, "soft", 4)) | 212 | if (!strncmp(p, "soft", 4)) |
| 213 | swiotlb = 1; | 213 | swiotlb = 1; |
| 214 | #endif | ||
| 214 | if (!strncmp(p, "pt", 2)) { | 215 | if (!strncmp(p, "pt", 2)) { |
| 215 | iommu_pass_through = 1; | 216 | iommu_pass_through = 1; |
| 216 | return 1; | 217 | return 1; |
| 217 | } | 218 | } |
| 218 | #endif | ||
| 219 | 219 | ||
| 220 | gart_parse_options(p); | 220 | gart_parse_options(p); |
| 221 | 221 | ||
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index cfd9f9063896..d2e56b8f48e7 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c | |||
| @@ -675,7 +675,7 @@ static __init int init_k8_gatt(struct agp_kern_info *info) | |||
| 675 | nommu: | 675 | nommu: |
| 676 | /* Should not happen anymore */ | 676 | /* Should not happen anymore */ |
| 677 | printk(KERN_WARNING "PCI-DMA: More than 4GB of RAM and no IOMMU\n" | 677 | printk(KERN_WARNING "PCI-DMA: More than 4GB of RAM and no IOMMU\n" |
| 678 | KERN_WARNING "falling back to iommu=soft.\n"); | 678 | "falling back to iommu=soft.\n"); |
| 679 | return -1; | 679 | return -1; |
| 680 | } | 680 | } |
| 681 | 681 | ||
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index be5ae80f897f..de2cab132844 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
| @@ -289,6 +289,20 @@ void * __init extend_brk(size_t size, size_t align) | |||
| 289 | return ret; | 289 | return ret; |
| 290 | } | 290 | } |
| 291 | 291 | ||
| 292 | #ifdef CONFIG_X86_64 | ||
| 293 | static void __init init_gbpages(void) | ||
| 294 | { | ||
| 295 | if (direct_gbpages && cpu_has_gbpages) | ||
| 296 | printk(KERN_INFO "Using GB pages for direct mapping\n"); | ||
| 297 | else | ||
| 298 | direct_gbpages = 0; | ||
| 299 | } | ||
| 300 | #else | ||
| 301 | static inline void init_gbpages(void) | ||
| 302 | { | ||
| 303 | } | ||
| 304 | #endif | ||
| 305 | |||
| 292 | static void __init reserve_brk(void) | 306 | static void __init reserve_brk(void) |
| 293 | { | 307 | { |
| 294 | if (_brk_end > _brk_start) | 308 | if (_brk_end > _brk_start) |
| @@ -871,6 +885,8 @@ void __init setup_arch(char **cmdline_p) | |||
| 871 | 885 | ||
| 872 | reserve_brk(); | 886 | reserve_brk(); |
| 873 | 887 | ||
| 888 | init_gbpages(); | ||
| 889 | |||
| 874 | /* max_pfn_mapped is updated here */ | 890 | /* max_pfn_mapped is updated here */ |
| 875 | max_low_pfn_mapped = init_memory_mapping(0, max_low_pfn<<PAGE_SHIFT); | 891 | max_low_pfn_mapped = init_memory_mapping(0, max_low_pfn<<PAGE_SHIFT); |
| 876 | max_pfn_mapped = max_low_pfn_mapped; | 892 | max_pfn_mapped = max_low_pfn_mapped; |
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index 9c3f0823e6aa..29a3eef7cf4a 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c | |||
| @@ -124,7 +124,7 @@ static void * __init pcpu_alloc_bootmem(unsigned int cpu, unsigned long size, | |||
| 124 | } | 124 | } |
| 125 | 125 | ||
| 126 | /* | 126 | /* |
| 127 | * Remap allocator | 127 | * Large page remap allocator |
| 128 | * | 128 | * |
| 129 | * This allocator uses PMD page as unit. A PMD page is allocated for | 129 | * This allocator uses PMD page as unit. A PMD page is allocated for |
| 130 | * each cpu and each is remapped into vmalloc area using PMD mapping. | 130 | * each cpu and each is remapped into vmalloc area using PMD mapping. |
| @@ -137,105 +137,185 @@ static void * __init pcpu_alloc_bootmem(unsigned int cpu, unsigned long size, | |||
| 137 | * better than only using 4k mappings while still being NUMA friendly. | 137 | * better than only using 4k mappings while still being NUMA friendly. |
| 138 | */ | 138 | */ |
| 139 | #ifdef CONFIG_NEED_MULTIPLE_NODES | 139 | #ifdef CONFIG_NEED_MULTIPLE_NODES |
| 140 | static size_t pcpur_size __initdata; | 140 | struct pcpul_ent { |
| 141 | static void **pcpur_ptrs __initdata; | 141 | unsigned int cpu; |
| 142 | void *ptr; | ||
| 143 | }; | ||
| 144 | |||
| 145 | static size_t pcpul_size; | ||
| 146 | static struct pcpul_ent *pcpul_map; | ||
| 147 | static struct vm_struct pcpul_vm; | ||
| 142 | 148 | ||
| 143 | static struct page * __init pcpur_get_page(unsigned int cpu, int pageno) | 149 | static struct page * __init pcpul_get_page(unsigned int cpu, int pageno) |
| 144 | { | 150 | { |
| 145 | size_t off = (size_t)pageno << PAGE_SHIFT; | 151 | size_t off = (size_t)pageno << PAGE_SHIFT; |
| 146 | 152 | ||
| 147 | if (off >= pcpur_size) | 153 | if (off >= pcpul_size) |
| 148 | return NULL; | 154 | return NULL; |
| 149 | 155 | ||
| 150 | return virt_to_page(pcpur_ptrs[cpu] + off); | 156 | return virt_to_page(pcpul_map[cpu].ptr + off); |
| 151 | } | 157 | } |
| 152 | 158 | ||
| 153 | static ssize_t __init setup_pcpu_remap(size_t static_size) | 159 | static ssize_t __init setup_pcpu_lpage(size_t static_size, bool chosen) |
| 154 | { | 160 | { |
| 155 | static struct vm_struct vm; | 161 | size_t map_size, dyn_size; |
| 156 | size_t ptrs_size, dyn_size; | ||
| 157 | unsigned int cpu; | 162 | unsigned int cpu; |
| 163 | int i, j; | ||
| 158 | ssize_t ret; | 164 | ssize_t ret; |
| 159 | 165 | ||
| 160 | /* | 166 | if (!chosen) { |
| 161 | * If large page isn't supported, there's no benefit in doing | 167 | size_t vm_size = VMALLOC_END - VMALLOC_START; |
| 162 | * this. Also, on non-NUMA, embedding is better. | 168 | size_t tot_size = num_possible_cpus() * PMD_SIZE; |
| 163 | * | 169 | |
| 164 | * NOTE: disabled for now. | 170 | /* on non-NUMA, embedding is better */ |
| 165 | */ | 171 | if (!pcpu_need_numa()) |
| 166 | if (true || !cpu_has_pse || !pcpu_need_numa()) | 172 | return -EINVAL; |
| 173 | |||
| 174 | /* don't consume more than 20% of vmalloc area */ | ||
| 175 | if (tot_size > vm_size / 5) { | ||
| 176 | pr_info("PERCPU: too large chunk size %zuMB for " | ||
| 177 | "large page remap\n", tot_size >> 20); | ||
| 178 | return -EINVAL; | ||
| 179 | } | ||
| 180 | } | ||
| 181 | |||
| 182 | /* need PSE */ | ||
| 183 | if (!cpu_has_pse) { | ||
| 184 | pr_warning("PERCPU: lpage allocator requires PSE\n"); | ||
| 167 | return -EINVAL; | 185 | return -EINVAL; |
| 186 | } | ||
| 168 | 187 | ||
| 169 | /* | 188 | /* |
| 170 | * Currently supports only single page. Supporting multiple | 189 | * Currently supports only single page. Supporting multiple |
| 171 | * pages won't be too difficult if it ever becomes necessary. | 190 | * pages won't be too difficult if it ever becomes necessary. |
| 172 | */ | 191 | */ |
| 173 | pcpur_size = PFN_ALIGN(static_size + PERCPU_MODULE_RESERVE + | 192 | pcpul_size = PFN_ALIGN(static_size + PERCPU_MODULE_RESERVE + |
| 174 | PERCPU_DYNAMIC_RESERVE); | 193 | PERCPU_DYNAMIC_RESERVE); |
| 175 | if (pcpur_size > PMD_SIZE) { | 194 | if (pcpul_size > PMD_SIZE) { |
| 176 | pr_warning("PERCPU: static data is larger than large page, " | 195 | pr_warning("PERCPU: static data is larger than large page, " |
| 177 | "can't use large page\n"); | 196 | "can't use large page\n"); |
| 178 | return -EINVAL; | 197 | return -EINVAL; |
| 179 | } | 198 | } |
| 180 | dyn_size = pcpur_size - static_size - PERCPU_FIRST_CHUNK_RESERVE; | 199 | dyn_size = pcpul_size - static_size - PERCPU_FIRST_CHUNK_RESERVE; |
| 181 | 200 | ||
| 182 | /* allocate pointer array and alloc large pages */ | 201 | /* allocate pointer array and alloc large pages */ |
| 183 | ptrs_size = PFN_ALIGN(num_possible_cpus() * sizeof(pcpur_ptrs[0])); | 202 | map_size = PFN_ALIGN(num_possible_cpus() * sizeof(pcpul_map[0])); |
| 184 | pcpur_ptrs = alloc_bootmem(ptrs_size); | 203 | pcpul_map = alloc_bootmem(map_size); |
| 185 | 204 | ||
| 186 | for_each_possible_cpu(cpu) { | 205 | for_each_possible_cpu(cpu) { |
| 187 | pcpur_ptrs[cpu] = pcpu_alloc_bootmem(cpu, PMD_SIZE, PMD_SIZE); | 206 | pcpul_map[cpu].cpu = cpu; |
| 188 | if (!pcpur_ptrs[cpu]) | 207 | pcpul_map[cpu].ptr = pcpu_alloc_bootmem(cpu, PMD_SIZE, |
| 208 | PMD_SIZE); | ||
| 209 | if (!pcpul_map[cpu].ptr) { | ||
| 210 | pr_warning("PERCPU: failed to allocate large page " | ||
| 211 | "for cpu%u\n", cpu); | ||
| 189 | goto enomem; | 212 | goto enomem; |
| 213 | } | ||
| 190 | 214 | ||
| 191 | /* | 215 | /* |
| 192 | * Only use pcpur_size bytes and give back the rest. | 216 | * Only use pcpul_size bytes and give back the rest. |
| 193 | * | 217 | * |
| 194 | * Ingo: The 2MB up-rounding bootmem is needed to make | 218 | * Ingo: The 2MB up-rounding bootmem is needed to make |
| 195 | * sure the partial 2MB page is still fully RAM - it's | 219 | * sure the partial 2MB page is still fully RAM - it's |
| 196 | * not well-specified to have a PAT-incompatible area | 220 | * not well-specified to have a PAT-incompatible area |
| 197 | * (unmapped RAM, device memory, etc.) in that hole. | 221 | * (unmapped RAM, device memory, etc.) in that hole. |
| 198 | */ | 222 | */ |
| 199 | free_bootmem(__pa(pcpur_ptrs[cpu] + pcpur_size), | 223 | free_bootmem(__pa(pcpul_map[cpu].ptr + pcpul_size), |
| 200 | PMD_SIZE - pcpur_size); | 224 | PMD_SIZE - pcpul_size); |
| 201 | 225 | ||
| 202 | memcpy(pcpur_ptrs[cpu], __per_cpu_load, static_size); | 226 | memcpy(pcpul_map[cpu].ptr, __per_cpu_load, static_size); |
| 203 | } | 227 | } |
| 204 | 228 | ||
| 205 | /* allocate address and map */ | 229 | /* allocate address and map */ |
| 206 | vm.flags = VM_ALLOC; | 230 | pcpul_vm.flags = VM_ALLOC; |
| 207 | vm.size = num_possible_cpus() * PMD_SIZE; | 231 | pcpul_vm.size = num_possible_cpus() * PMD_SIZE; |
| 208 | vm_area_register_early(&vm, PMD_SIZE); | 232 | vm_area_register_early(&pcpul_vm, PMD_SIZE); |
| 209 | 233 | ||
| 210 | for_each_possible_cpu(cpu) { | 234 | for_each_possible_cpu(cpu) { |
| 211 | pmd_t *pmd; | 235 | pmd_t *pmd, pmd_v; |
| 212 | 236 | ||
| 213 | pmd = populate_extra_pmd((unsigned long)vm.addr | 237 | pmd = populate_extra_pmd((unsigned long)pcpul_vm.addr + |
| 214 | + cpu * PMD_SIZE); | 238 | cpu * PMD_SIZE); |
| 215 | set_pmd(pmd, pfn_pmd(page_to_pfn(virt_to_page(pcpur_ptrs[cpu])), | 239 | pmd_v = pfn_pmd(page_to_pfn(virt_to_page(pcpul_map[cpu].ptr)), |
| 216 | PAGE_KERNEL_LARGE)); | 240 | PAGE_KERNEL_LARGE); |
| 241 | set_pmd(pmd, pmd_v); | ||
| 217 | } | 242 | } |
| 218 | 243 | ||
| 219 | /* we're ready, commit */ | 244 | /* we're ready, commit */ |
| 220 | pr_info("PERCPU: Remapped at %p with large pages, static data " | 245 | pr_info("PERCPU: Remapped at %p with large pages, static data " |
| 221 | "%zu bytes\n", vm.addr, static_size); | 246 | "%zu bytes\n", pcpul_vm.addr, static_size); |
| 222 | 247 | ||
| 223 | ret = pcpu_setup_first_chunk(pcpur_get_page, static_size, | 248 | ret = pcpu_setup_first_chunk(pcpul_get_page, static_size, |
| 224 | PERCPU_FIRST_CHUNK_RESERVE, dyn_size, | 249 | PERCPU_FIRST_CHUNK_RESERVE, dyn_size, |
| 225 | PMD_SIZE, vm.addr, NULL); | 250 | PMD_SIZE, pcpul_vm.addr, NULL); |
| 226 | goto out_free_ar; | 251 | |
| 252 | /* sort pcpul_map array for pcpu_lpage_remapped() */ | ||
| 253 | for (i = 0; i < num_possible_cpus() - 1; i++) | ||
| 254 | for (j = i + 1; j < num_possible_cpus(); j++) | ||
| 255 | if (pcpul_map[i].ptr > pcpul_map[j].ptr) { | ||
| 256 | struct pcpul_ent tmp = pcpul_map[i]; | ||
| 257 | pcpul_map[i] = pcpul_map[j]; | ||
| 258 | pcpul_map[j] = tmp; | ||
| 259 | } | ||
| 260 | |||
| 261 | return ret; | ||
| 227 | 262 | ||
| 228 | enomem: | 263 | enomem: |
| 229 | for_each_possible_cpu(cpu) | 264 | for_each_possible_cpu(cpu) |
| 230 | if (pcpur_ptrs[cpu]) | 265 | if (pcpul_map[cpu].ptr) |
| 231 | free_bootmem(__pa(pcpur_ptrs[cpu]), PMD_SIZE); | 266 | free_bootmem(__pa(pcpul_map[cpu].ptr), pcpul_size); |
| 232 | ret = -ENOMEM; | 267 | free_bootmem(__pa(pcpul_map), map_size); |
| 233 | out_free_ar: | 268 | return -ENOMEM; |
| 234 | free_bootmem(__pa(pcpur_ptrs), ptrs_size); | 269 | } |
| 235 | return ret; | 270 | |
| 271 | /** | ||
| 272 | * pcpu_lpage_remapped - determine whether a kaddr is in pcpul recycled area | ||
| 273 | * @kaddr: the kernel address in question | ||
| 274 | * | ||
| 275 | * Determine whether @kaddr falls in the pcpul recycled area. This is | ||
| 276 | * used by pageattr to detect VM aliases and break up the pcpu PMD | ||
| 277 | * mapping such that the same physical page is not mapped under | ||
| 278 | * different attributes. | ||
| 279 | * | ||
| 280 | * The recycled area is always at the tail of a partially used PMD | ||
| 281 | * page. | ||
| 282 | * | ||
| 283 | * RETURNS: | ||
| 284 | * Address of corresponding remapped pcpu address if match is found; | ||
| 285 | * otherwise, NULL. | ||
| 286 | */ | ||
| 287 | void *pcpu_lpage_remapped(void *kaddr) | ||
| 288 | { | ||
| 289 | void *pmd_addr = (void *)((unsigned long)kaddr & PMD_MASK); | ||
| 290 | unsigned long offset = (unsigned long)kaddr & ~PMD_MASK; | ||
| 291 | int left = 0, right = num_possible_cpus() - 1; | ||
| 292 | int pos; | ||
| 293 | |||
| 294 | /* pcpul in use at all? */ | ||
| 295 | if (!pcpul_map) | ||
| 296 | return NULL; | ||
| 297 | |||
| 298 | /* okay, perform binary search */ | ||
| 299 | while (left <= right) { | ||
| 300 | pos = (left + right) / 2; | ||
| 301 | |||
| 302 | if (pcpul_map[pos].ptr < pmd_addr) | ||
| 303 | left = pos + 1; | ||
| 304 | else if (pcpul_map[pos].ptr > pmd_addr) | ||
| 305 | right = pos - 1; | ||
| 306 | else { | ||
| 307 | /* it shouldn't be in the area for the first chunk */ | ||
| 308 | WARN_ON(offset < pcpul_size); | ||
| 309 | |||
| 310 | return pcpul_vm.addr + | ||
| 311 | pcpul_map[pos].cpu * PMD_SIZE + offset; | ||
| 312 | } | ||
| 313 | } | ||
| 314 | |||
| 315 | return NULL; | ||
| 236 | } | 316 | } |
| 237 | #else | 317 | #else |
| 238 | static ssize_t __init setup_pcpu_remap(size_t static_size) | 318 | static ssize_t __init setup_pcpu_lpage(size_t static_size, bool chosen) |
| 239 | { | 319 | { |
| 240 | return -EINVAL; | 320 | return -EINVAL; |
| 241 | } | 321 | } |
| @@ -249,7 +329,7 @@ static ssize_t __init setup_pcpu_remap(size_t static_size) | |||
| 249 | * mapping so that it can use PMD mapping without additional TLB | 329 | * mapping so that it can use PMD mapping without additional TLB |
| 250 | * pressure. | 330 | * pressure. |
| 251 | */ | 331 | */ |
| 252 | static ssize_t __init setup_pcpu_embed(size_t static_size) | 332 | static ssize_t __init setup_pcpu_embed(size_t static_size, bool chosen) |
| 253 | { | 333 | { |
| 254 | size_t reserve = PERCPU_MODULE_RESERVE + PERCPU_DYNAMIC_RESERVE; | 334 | size_t reserve = PERCPU_MODULE_RESERVE + PERCPU_DYNAMIC_RESERVE; |
| 255 | 335 | ||
| @@ -258,7 +338,7 @@ static ssize_t __init setup_pcpu_embed(size_t static_size) | |||
| 258 | * this. Also, embedding allocation doesn't play well with | 338 | * this. Also, embedding allocation doesn't play well with |
| 259 | * NUMA. | 339 | * NUMA. |
| 260 | */ | 340 | */ |
| 261 | if (!cpu_has_pse || pcpu_need_numa()) | 341 | if (!chosen && (!cpu_has_pse || pcpu_need_numa())) |
| 262 | return -EINVAL; | 342 | return -EINVAL; |
| 263 | 343 | ||
| 264 | return pcpu_embed_first_chunk(static_size, PERCPU_FIRST_CHUNK_RESERVE, | 344 | return pcpu_embed_first_chunk(static_size, PERCPU_FIRST_CHUNK_RESERVE, |
| @@ -308,8 +388,11 @@ static ssize_t __init setup_pcpu_4k(size_t static_size) | |||
| 308 | void *ptr; | 388 | void *ptr; |
| 309 | 389 | ||
| 310 | ptr = pcpu_alloc_bootmem(cpu, PAGE_SIZE, PAGE_SIZE); | 390 | ptr = pcpu_alloc_bootmem(cpu, PAGE_SIZE, PAGE_SIZE); |
| 311 | if (!ptr) | 391 | if (!ptr) { |
| 392 | pr_warning("PERCPU: failed to allocate " | ||
| 393 | "4k page for cpu%u\n", cpu); | ||
| 312 | goto enomem; | 394 | goto enomem; |
| 395 | } | ||
| 313 | 396 | ||
| 314 | memcpy(ptr, __per_cpu_load + i * PAGE_SIZE, PAGE_SIZE); | 397 | memcpy(ptr, __per_cpu_load + i * PAGE_SIZE, PAGE_SIZE); |
| 315 | pcpu4k_pages[j++] = virt_to_page(ptr); | 398 | pcpu4k_pages[j++] = virt_to_page(ptr); |
| @@ -333,6 +416,16 @@ out_free_ar: | |||
| 333 | return ret; | 416 | return ret; |
| 334 | } | 417 | } |
| 335 | 418 | ||
| 419 | /* for explicit first chunk allocator selection */ | ||
| 420 | static char pcpu_chosen_alloc[16] __initdata; | ||
| 421 | |||
| 422 | static int __init percpu_alloc_setup(char *str) | ||
| 423 | { | ||
| 424 | strncpy(pcpu_chosen_alloc, str, sizeof(pcpu_chosen_alloc) - 1); | ||
| 425 | return 0; | ||
| 426 | } | ||
| 427 | early_param("percpu_alloc", percpu_alloc_setup); | ||
| 428 | |||
| 336 | static inline void setup_percpu_segment(int cpu) | 429 | static inline void setup_percpu_segment(int cpu) |
| 337 | { | 430 | { |
| 338 | #ifdef CONFIG_X86_32 | 431 | #ifdef CONFIG_X86_32 |
| @@ -346,11 +439,6 @@ static inline void setup_percpu_segment(int cpu) | |||
| 346 | #endif | 439 | #endif |
| 347 | } | 440 | } |
| 348 | 441 | ||
| 349 | /* | ||
| 350 | * Great future plan: | ||
| 351 | * Declare PDA itself and support (irqstack,tss,pgd) as per cpu data. | ||
| 352 | * Always point %gs to its beginning | ||
| 353 | */ | ||
| 354 | void __init setup_per_cpu_areas(void) | 442 | void __init setup_per_cpu_areas(void) |
| 355 | { | 443 | { |
| 356 | size_t static_size = __per_cpu_end - __per_cpu_start; | 444 | size_t static_size = __per_cpu_end - __per_cpu_start; |
| @@ -367,9 +455,26 @@ void __init setup_per_cpu_areas(void) | |||
| 367 | * of large page mappings. Please read comments on top of | 455 | * of large page mappings. Please read comments on top of |
| 368 | * each allocator for details. | 456 | * each allocator for details. |
| 369 | */ | 457 | */ |
| 370 | ret = setup_pcpu_remap(static_size); | 458 | ret = -EINVAL; |
| 371 | if (ret < 0) | 459 | if (strlen(pcpu_chosen_alloc)) { |
| 372 | ret = setup_pcpu_embed(static_size); | 460 | if (strcmp(pcpu_chosen_alloc, "4k")) { |
| 461 | if (!strcmp(pcpu_chosen_alloc, "lpage")) | ||
| 462 | ret = setup_pcpu_lpage(static_size, true); | ||
| 463 | else if (!strcmp(pcpu_chosen_alloc, "embed")) | ||
| 464 | ret = setup_pcpu_embed(static_size, true); | ||
| 465 | else | ||
| 466 | pr_warning("PERCPU: unknown allocator %s " | ||
| 467 | "specified\n", pcpu_chosen_alloc); | ||
| 468 | if (ret < 0) | ||
| 469 | pr_warning("PERCPU: %s allocator failed (%zd), " | ||
| 470 | "falling back to 4k\n", | ||
| 471 | pcpu_chosen_alloc, ret); | ||
| 472 | } | ||
| 473 | } else { | ||
| 474 | ret = setup_pcpu_lpage(static_size, false); | ||
| 475 | if (ret < 0) | ||
| 476 | ret = setup_pcpu_embed(static_size, false); | ||
| 477 | } | ||
| 373 | if (ret < 0) | 478 | if (ret < 0) |
| 374 | ret = setup_pcpu_4k(static_size); | 479 | ret = setup_pcpu_4k(static_size); |
| 375 | if (ret < 0) | 480 | if (ret < 0) |
diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c index 124d40c575df..8ccabb8a2f6a 100644 --- a/arch/x86/kernel/tlb_uv.c +++ b/arch/x86/kernel/tlb_uv.c | |||
| @@ -711,7 +711,6 @@ uv_activation_descriptor_init(int node, int pnode) | |||
| 711 | unsigned long pa; | 711 | unsigned long pa; |
| 712 | unsigned long m; | 712 | unsigned long m; |
| 713 | unsigned long n; | 713 | unsigned long n; |
| 714 | unsigned long mmr_image; | ||
| 715 | struct bau_desc *adp; | 714 | struct bau_desc *adp; |
| 716 | struct bau_desc *ad2; | 715 | struct bau_desc *ad2; |
| 717 | 716 | ||
| @@ -727,12 +726,8 @@ uv_activation_descriptor_init(int node, int pnode) | |||
| 727 | n = pa >> uv_nshift; | 726 | n = pa >> uv_nshift; |
| 728 | m = pa & uv_mmask; | 727 | m = pa & uv_mmask; |
| 729 | 728 | ||
| 730 | mmr_image = uv_read_global_mmr64(pnode, UVH_LB_BAU_SB_DESCRIPTOR_BASE); | 729 | uv_write_global_mmr64(pnode, UVH_LB_BAU_SB_DESCRIPTOR_BASE, |
| 731 | if (mmr_image) { | 730 | (n << UV_DESC_BASE_PNODE_SHIFT | m)); |
| 732 | uv_write_global_mmr64(pnode, (unsigned long) | ||
| 733 | UVH_LB_BAU_SB_DESCRIPTOR_BASE, | ||
| 734 | (n << UV_DESC_BASE_PNODE_SHIFT | m)); | ||
| 735 | } | ||
| 736 | 731 | ||
| 737 | /* | 732 | /* |
| 738 | * initializing all 8 (UV_ITEMS_PER_DESCRIPTOR) descriptors for each | 733 | * initializing all 8 (UV_ITEMS_PER_DESCRIPTOR) descriptors for each |
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index a0f48f5671c0..5204332f475d 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
| @@ -346,6 +346,9 @@ io_check_error(unsigned char reason, struct pt_regs *regs) | |||
| 346 | printk(KERN_EMERG "NMI: IOCK error (debug interrupt?)\n"); | 346 | printk(KERN_EMERG "NMI: IOCK error (debug interrupt?)\n"); |
| 347 | show_registers(regs); | 347 | show_registers(regs); |
| 348 | 348 | ||
| 349 | if (panic_on_io_nmi) | ||
| 350 | panic("NMI IOCK error: Not continuing"); | ||
| 351 | |||
| 349 | /* Re-enable the IOCK line, wait for a few seconds */ | 352 | /* Re-enable the IOCK line, wait for a few seconds */ |
| 350 | reason = (reason & 0xf) | 8; | 353 | reason = (reason & 0xf) | 8; |
| 351 | outb(reason, 0x61); | 354 | outb(reason, 0x61); |
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 5c3d6e81a7dc..7030b5f911bf 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
| @@ -2157,7 +2157,7 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu, int level) | |||
| 2157 | else | 2157 | else |
| 2158 | /* 32 bits PSE 4MB page */ | 2158 | /* 32 bits PSE 4MB page */ |
| 2159 | context->rsvd_bits_mask[1][1] = rsvd_bits(13, 21); | 2159 | context->rsvd_bits_mask[1][1] = rsvd_bits(13, 21); |
| 2160 | context->rsvd_bits_mask[1][0] = ~0ull; | 2160 | context->rsvd_bits_mask[1][0] = context->rsvd_bits_mask[1][0]; |
| 2161 | break; | 2161 | break; |
| 2162 | case PT32E_ROOT_LEVEL: | 2162 | case PT32E_ROOT_LEVEL: |
| 2163 | context->rsvd_bits_mask[0][2] = | 2163 | context->rsvd_bits_mask[0][2] = |
| @@ -2170,7 +2170,7 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu, int level) | |||
| 2170 | context->rsvd_bits_mask[1][1] = exb_bit_rsvd | | 2170 | context->rsvd_bits_mask[1][1] = exb_bit_rsvd | |
| 2171 | rsvd_bits(maxphyaddr, 62) | | 2171 | rsvd_bits(maxphyaddr, 62) | |
| 2172 | rsvd_bits(13, 20); /* large page */ | 2172 | rsvd_bits(13, 20); /* large page */ |
| 2173 | context->rsvd_bits_mask[1][0] = ~0ull; | 2173 | context->rsvd_bits_mask[1][0] = context->rsvd_bits_mask[1][0]; |
| 2174 | break; | 2174 | break; |
| 2175 | case PT64_ROOT_LEVEL: | 2175 | case PT64_ROOT_LEVEL: |
| 2176 | context->rsvd_bits_mask[0][3] = exb_bit_rsvd | | 2176 | context->rsvd_bits_mask[0][3] = exb_bit_rsvd | |
| @@ -2186,7 +2186,7 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu, int level) | |||
| 2186 | context->rsvd_bits_mask[1][1] = exb_bit_rsvd | | 2186 | context->rsvd_bits_mask[1][1] = exb_bit_rsvd | |
| 2187 | rsvd_bits(maxphyaddr, 51) | | 2187 | rsvd_bits(maxphyaddr, 51) | |
| 2188 | rsvd_bits(13, 20); /* large page */ | 2188 | rsvd_bits(13, 20); /* large page */ |
| 2189 | context->rsvd_bits_mask[1][0] = ~0ull; | 2189 | context->rsvd_bits_mask[1][0] = context->rsvd_bits_mask[1][0]; |
| 2190 | break; | 2190 | break; |
| 2191 | } | 2191 | } |
| 2192 | } | 2192 | } |
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index 258e4591e1ca..67785f635399 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h | |||
| @@ -281,7 +281,7 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr, | |||
| 281 | { | 281 | { |
| 282 | unsigned access = gw->pt_access; | 282 | unsigned access = gw->pt_access; |
| 283 | struct kvm_mmu_page *shadow_page; | 283 | struct kvm_mmu_page *shadow_page; |
| 284 | u64 spte, *sptep; | 284 | u64 spte, *sptep = NULL; |
| 285 | int direct; | 285 | int direct; |
| 286 | gfn_t table_gfn; | 286 | gfn_t table_gfn; |
| 287 | int r; | 287 | int r; |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index e770bf349ec4..356a0ce85c68 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
| @@ -3012,6 +3012,12 @@ static int handle_vmcall(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 3012 | return 1; | 3012 | return 1; |
| 3013 | } | 3013 | } |
| 3014 | 3014 | ||
| 3015 | static int handle_vmx_insn(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | ||
| 3016 | { | ||
| 3017 | kvm_queue_exception(vcpu, UD_VECTOR); | ||
| 3018 | return 1; | ||
| 3019 | } | ||
| 3020 | |||
| 3015 | static int handle_invlpg(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | 3021 | static int handle_invlpg(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) |
| 3016 | { | 3022 | { |
| 3017 | unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION); | 3023 | unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION); |
| @@ -3198,6 +3204,15 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu, | |||
| 3198 | [EXIT_REASON_HLT] = handle_halt, | 3204 | [EXIT_REASON_HLT] = handle_halt, |
| 3199 | [EXIT_REASON_INVLPG] = handle_invlpg, | 3205 | [EXIT_REASON_INVLPG] = handle_invlpg, |
| 3200 | [EXIT_REASON_VMCALL] = handle_vmcall, | 3206 | [EXIT_REASON_VMCALL] = handle_vmcall, |
| 3207 | [EXIT_REASON_VMCLEAR] = handle_vmx_insn, | ||
| 3208 | [EXIT_REASON_VMLAUNCH] = handle_vmx_insn, | ||
| 3209 | [EXIT_REASON_VMPTRLD] = handle_vmx_insn, | ||
| 3210 | [EXIT_REASON_VMPTRST] = handle_vmx_insn, | ||
| 3211 | [EXIT_REASON_VMREAD] = handle_vmx_insn, | ||
| 3212 | [EXIT_REASON_VMRESUME] = handle_vmx_insn, | ||
| 3213 | [EXIT_REASON_VMWRITE] = handle_vmx_insn, | ||
| 3214 | [EXIT_REASON_VMOFF] = handle_vmx_insn, | ||
| 3215 | [EXIT_REASON_VMON] = handle_vmx_insn, | ||
| 3201 | [EXIT_REASON_TPR_BELOW_THRESHOLD] = handle_tpr_below_threshold, | 3216 | [EXIT_REASON_TPR_BELOW_THRESHOLD] = handle_tpr_below_threshold, |
| 3202 | [EXIT_REASON_APIC_ACCESS] = handle_apic_access, | 3217 | [EXIT_REASON_APIC_ACCESS] = handle_apic_access, |
| 3203 | [EXIT_REASON_WBINVD] = handle_wbinvd, | 3218 | [EXIT_REASON_WBINVD] = handle_wbinvd, |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 249540f98513..fe5474aec41a 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
| @@ -898,6 +898,7 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) | |||
| 898 | case MSR_VM_HSAVE_PA: | 898 | case MSR_VM_HSAVE_PA: |
| 899 | case MSR_P6_EVNTSEL0: | 899 | case MSR_P6_EVNTSEL0: |
| 900 | case MSR_P6_EVNTSEL1: | 900 | case MSR_P6_EVNTSEL1: |
| 901 | case MSR_K7_EVNTSEL0: | ||
| 901 | data = 0; | 902 | data = 0; |
| 902 | break; | 903 | break; |
| 903 | case MSR_MTRRcap: | 904 | case MSR_MTRRcap: |
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index c1b6c232e02b..616de4628d60 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c | |||
| @@ -1361,7 +1361,7 @@ static inline int writeback(struct x86_emulate_ctxt *ctxt, | |||
| 1361 | return 0; | 1361 | return 0; |
| 1362 | } | 1362 | } |
| 1363 | 1363 | ||
| 1364 | void toggle_interruptibility(struct x86_emulate_ctxt *ctxt, u32 mask) | 1364 | static void toggle_interruptibility(struct x86_emulate_ctxt *ctxt, u32 mask) |
| 1365 | { | 1365 | { |
| 1366 | u32 int_shadow = kvm_x86_ops->get_interrupt_shadow(ctxt->vcpu, mask); | 1366 | u32 int_shadow = kvm_x86_ops->get_interrupt_shadow(ctxt->vcpu, mask); |
| 1367 | /* | 1367 | /* |
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index f9d35632666b..07c31899c9c2 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile | |||
| @@ -10,6 +10,7 @@ lib-y += usercopy_$(BITS).o getuser.o putuser.o | |||
| 10 | lib-y += memcpy_$(BITS).o | 10 | lib-y += memcpy_$(BITS).o |
| 11 | 11 | ||
| 12 | ifeq ($(CONFIG_X86_32),y) | 12 | ifeq ($(CONFIG_X86_32),y) |
| 13 | obj-y += atomic64_32.o | ||
| 13 | lib-y += checksum_32.o | 14 | lib-y += checksum_32.o |
| 14 | lib-y += strstr_32.o | 15 | lib-y += strstr_32.o |
| 15 | lib-y += semaphore_32.o string_32.o | 16 | lib-y += semaphore_32.o string_32.o |
diff --git a/arch/x86/lib/atomic64_32.c b/arch/x86/lib/atomic64_32.c new file mode 100644 index 000000000000..824fa0be55a3 --- /dev/null +++ b/arch/x86/lib/atomic64_32.c | |||
| @@ -0,0 +1,230 @@ | |||
| 1 | #include <linux/compiler.h> | ||
| 2 | #include <linux/module.h> | ||
| 3 | #include <linux/types.h> | ||
| 4 | |||
| 5 | #include <asm/processor.h> | ||
| 6 | #include <asm/cmpxchg.h> | ||
| 7 | #include <asm/atomic.h> | ||
| 8 | |||
| 9 | static noinline u64 cmpxchg8b(u64 *ptr, u64 old, u64 new) | ||
| 10 | { | ||
| 11 | u32 low = new; | ||
| 12 | u32 high = new >> 32; | ||
| 13 | |||
| 14 | asm volatile( | ||
| 15 | LOCK_PREFIX "cmpxchg8b %1\n" | ||
| 16 | : "+A" (old), "+m" (*ptr) | ||
| 17 | : "b" (low), "c" (high) | ||
| 18 | ); | ||
| 19 | return old; | ||
| 20 | } | ||
| 21 | |||
| 22 | u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old_val, u64 new_val) | ||
| 23 | { | ||
| 24 | return cmpxchg8b(&ptr->counter, old_val, new_val); | ||
| 25 | } | ||
| 26 | EXPORT_SYMBOL(atomic64_cmpxchg); | ||
| 27 | |||
| 28 | /** | ||
| 29 | * atomic64_xchg - xchg atomic64 variable | ||
| 30 | * @ptr: pointer to type atomic64_t | ||
| 31 | * @new_val: value to assign | ||
| 32 | * | ||
| 33 | * Atomically xchgs the value of @ptr to @new_val and returns | ||
| 34 | * the old value. | ||
| 35 | */ | ||
| 36 | u64 atomic64_xchg(atomic64_t *ptr, u64 new_val) | ||
| 37 | { | ||
| 38 | /* | ||
| 39 | * Try first with a (possibly incorrect) assumption about | ||
| 40 | * what we have there. We'll do two loops most likely, | ||
| 41 | * but we'll get an ownership MESI transaction straight away | ||
| 42 | * instead of a read transaction followed by a | ||
| 43 | * flush-for-ownership transaction: | ||
| 44 | */ | ||
| 45 | u64 old_val, real_val = 0; | ||
| 46 | |||
| 47 | do { | ||
| 48 | old_val = real_val; | ||
| 49 | |||
| 50 | real_val = atomic64_cmpxchg(ptr, old_val, new_val); | ||
| 51 | |||
| 52 | } while (real_val != old_val); | ||
| 53 | |||
| 54 | return old_val; | ||
| 55 | } | ||
| 56 | EXPORT_SYMBOL(atomic64_xchg); | ||
| 57 | |||
| 58 | /** | ||
| 59 | * atomic64_set - set atomic64 variable | ||
| 60 | * @ptr: pointer to type atomic64_t | ||
| 61 | * @new_val: value to assign | ||
| 62 | * | ||
| 63 | * Atomically sets the value of @ptr to @new_val. | ||
| 64 | */ | ||
| 65 | void atomic64_set(atomic64_t *ptr, u64 new_val) | ||
| 66 | { | ||
| 67 | atomic64_xchg(ptr, new_val); | ||
| 68 | } | ||
| 69 | EXPORT_SYMBOL(atomic64_set); | ||
| 70 | |||
| 71 | /** | ||
| 72 | EXPORT_SYMBOL(atomic64_read); | ||
| 73 | * atomic64_add_return - add and return | ||
| 74 | * @delta: integer value to add | ||
| 75 | * @ptr: pointer to type atomic64_t | ||
| 76 | * | ||
| 77 | * Atomically adds @delta to @ptr and returns @delta + *@ptr | ||
| 78 | */ | ||
| 79 | noinline u64 atomic64_add_return(u64 delta, atomic64_t *ptr) | ||
| 80 | { | ||
| 81 | /* | ||
| 82 | * Try first with a (possibly incorrect) assumption about | ||
| 83 | * what we have there. We'll do two loops most likely, | ||
| 84 | * but we'll get an ownership MESI transaction straight away | ||
| 85 | * instead of a read transaction followed by a | ||
| 86 | * flush-for-ownership transaction: | ||
| 87 | */ | ||
| 88 | u64 old_val, new_val, real_val = 0; | ||
| 89 | |||
| 90 | do { | ||
| 91 | old_val = real_val; | ||
| 92 | new_val = old_val + delta; | ||
| 93 | |||
| 94 | real_val = atomic64_cmpxchg(ptr, old_val, new_val); | ||
| 95 | |||
| 96 | } while (real_val != old_val); | ||
| 97 | |||
| 98 | return new_val; | ||
| 99 | } | ||
| 100 | EXPORT_SYMBOL(atomic64_add_return); | ||
| 101 | |||
| 102 | u64 atomic64_sub_return(u64 delta, atomic64_t *ptr) | ||
| 103 | { | ||
| 104 | return atomic64_add_return(-delta, ptr); | ||
| 105 | } | ||
| 106 | EXPORT_SYMBOL(atomic64_sub_return); | ||
| 107 | |||
| 108 | u64 atomic64_inc_return(atomic64_t *ptr) | ||
| 109 | { | ||
| 110 | return atomic64_add_return(1, ptr); | ||
| 111 | } | ||
| 112 | EXPORT_SYMBOL(atomic64_inc_return); | ||
| 113 | |||
| 114 | u64 atomic64_dec_return(atomic64_t *ptr) | ||
| 115 | { | ||
| 116 | return atomic64_sub_return(1, ptr); | ||
| 117 | } | ||
| 118 | EXPORT_SYMBOL(atomic64_dec_return); | ||
| 119 | |||
| 120 | /** | ||
| 121 | * atomic64_add - add integer to atomic64 variable | ||
| 122 | * @delta: integer value to add | ||
| 123 | * @ptr: pointer to type atomic64_t | ||
| 124 | * | ||
| 125 | * Atomically adds @delta to @ptr. | ||
| 126 | */ | ||
| 127 | void atomic64_add(u64 delta, atomic64_t *ptr) | ||
| 128 | { | ||
| 129 | atomic64_add_return(delta, ptr); | ||
| 130 | } | ||
| 131 | EXPORT_SYMBOL(atomic64_add); | ||
| 132 | |||
| 133 | /** | ||
| 134 | * atomic64_sub - subtract the atomic64 variable | ||
| 135 | * @delta: integer value to subtract | ||
| 136 | * @ptr: pointer to type atomic64_t | ||
| 137 | * | ||
| 138 | * Atomically subtracts @delta from @ptr. | ||
| 139 | */ | ||
| 140 | void atomic64_sub(u64 delta, atomic64_t *ptr) | ||
| 141 | { | ||
| 142 | atomic64_add(-delta, ptr); | ||
| 143 | } | ||
| 144 | EXPORT_SYMBOL(atomic64_sub); | ||
| 145 | |||
| 146 | /** | ||
| 147 | * atomic64_sub_and_test - subtract value from variable and test result | ||
| 148 | * @delta: integer value to subtract | ||
| 149 | * @ptr: pointer to type atomic64_t | ||
| 150 | * | ||
| 151 | * Atomically subtracts @delta from @ptr and returns | ||
| 152 | * true if the result is zero, or false for all | ||
| 153 | * other cases. | ||
| 154 | */ | ||
| 155 | int atomic64_sub_and_test(u64 delta, atomic64_t *ptr) | ||
| 156 | { | ||
| 157 | u64 new_val = atomic64_sub_return(delta, ptr); | ||
| 158 | |||
| 159 | return new_val == 0; | ||
| 160 | } | ||
| 161 | EXPORT_SYMBOL(atomic64_sub_and_test); | ||
| 162 | |||
| 163 | /** | ||
| 164 | * atomic64_inc - increment atomic64 variable | ||
| 165 | * @ptr: pointer to type atomic64_t | ||
| 166 | * | ||
| 167 | * Atomically increments @ptr by 1. | ||
| 168 | */ | ||
| 169 | void atomic64_inc(atomic64_t *ptr) | ||
| 170 | { | ||
| 171 | atomic64_add(1, ptr); | ||
| 172 | } | ||
| 173 | EXPORT_SYMBOL(atomic64_inc); | ||
| 174 | |||
| 175 | /** | ||
| 176 | * atomic64_dec - decrement atomic64 variable | ||
| 177 | * @ptr: pointer to type atomic64_t | ||
| 178 | * | ||
| 179 | * Atomically decrements @ptr by 1. | ||
| 180 | */ | ||
| 181 | void atomic64_dec(atomic64_t *ptr) | ||
| 182 | { | ||
| 183 | atomic64_sub(1, ptr); | ||
| 184 | } | ||
| 185 | EXPORT_SYMBOL(atomic64_dec); | ||
| 186 | |||
| 187 | /** | ||
| 188 | * atomic64_dec_and_test - decrement and test | ||
| 189 | * @ptr: pointer to type atomic64_t | ||
| 190 | * | ||
| 191 | * Atomically decrements @ptr by 1 and | ||
| 192 | * returns true if the result is 0, or false for all other | ||
| 193 | * cases. | ||
| 194 | */ | ||
| 195 | int atomic64_dec_and_test(atomic64_t *ptr) | ||
| 196 | { | ||
| 197 | return atomic64_sub_and_test(1, ptr); | ||
| 198 | } | ||
| 199 | EXPORT_SYMBOL(atomic64_dec_and_test); | ||
| 200 | |||
| 201 | /** | ||
| 202 | * atomic64_inc_and_test - increment and test | ||
| 203 | * @ptr: pointer to type atomic64_t | ||
| 204 | * | ||
| 205 | * Atomically increments @ptr by 1 | ||
| 206 | * and returns true if the result is zero, or false for all | ||
| 207 | * other cases. | ||
| 208 | */ | ||
| 209 | int atomic64_inc_and_test(atomic64_t *ptr) | ||
| 210 | { | ||
| 211 | return atomic64_sub_and_test(-1, ptr); | ||
| 212 | } | ||
| 213 | EXPORT_SYMBOL(atomic64_inc_and_test); | ||
| 214 | |||
| 215 | /** | ||
| 216 | * atomic64_add_negative - add and test if negative | ||
| 217 | * @delta: integer value to add | ||
| 218 | * @ptr: pointer to type atomic64_t | ||
| 219 | * | ||
| 220 | * Atomically adds @delta to @ptr and returns true | ||
| 221 | * if the result is negative, or false when | ||
| 222 | * result is greater than or equal to zero. | ||
| 223 | */ | ||
| 224 | int atomic64_add_negative(u64 delta, atomic64_t *ptr) | ||
| 225 | { | ||
| 226 | s64 new_val = atomic64_add_return(delta, ptr); | ||
| 227 | |||
| 228 | return new_val < 0; | ||
| 229 | } | ||
| 230 | EXPORT_SYMBOL(atomic64_add_negative); | ||
diff --git a/arch/x86/lib/clear_page_64.S b/arch/x86/lib/clear_page_64.S index 9a10a78bb4a4..ebeafcce04a9 100644 --- a/arch/x86/lib/clear_page_64.S +++ b/arch/x86/lib/clear_page_64.S | |||
| @@ -5,15 +5,14 @@ | |||
| 5 | * Zero a page. | 5 | * Zero a page. |
| 6 | * rdi page | 6 | * rdi page |
| 7 | */ | 7 | */ |
| 8 | ALIGN | 8 | ENTRY(clear_page_c) |
| 9 | clear_page_c: | ||
| 10 | CFI_STARTPROC | 9 | CFI_STARTPROC |
| 11 | movl $4096/8,%ecx | 10 | movl $4096/8,%ecx |
| 12 | xorl %eax,%eax | 11 | xorl %eax,%eax |
| 13 | rep stosq | 12 | rep stosq |
| 14 | ret | 13 | ret |
| 15 | CFI_ENDPROC | 14 | CFI_ENDPROC |
| 16 | ENDPROC(clear_page) | 15 | ENDPROC(clear_page_c) |
| 17 | 16 | ||
| 18 | ENTRY(clear_page) | 17 | ENTRY(clear_page) |
| 19 | CFI_STARTPROC | 18 | CFI_STARTPROC |
diff --git a/arch/x86/lib/copy_user_64.S b/arch/x86/lib/copy_user_64.S index f118c110af32..6ba0f7bb85ea 100644 --- a/arch/x86/lib/copy_user_64.S +++ b/arch/x86/lib/copy_user_64.S | |||
| @@ -75,6 +75,7 @@ ENTRY(copy_to_user) | |||
| 75 | jae bad_to_user | 75 | jae bad_to_user |
| 76 | ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string | 76 | ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string |
| 77 | CFI_ENDPROC | 77 | CFI_ENDPROC |
| 78 | ENDPROC(copy_to_user) | ||
| 78 | 79 | ||
| 79 | /* Standard copy_from_user with segment limit checking */ | 80 | /* Standard copy_from_user with segment limit checking */ |
| 80 | ENTRY(copy_from_user) | 81 | ENTRY(copy_from_user) |
diff --git a/arch/x86/lib/delay.c b/arch/x86/lib/delay.c index f4568605d7d5..ff485d361182 100644 --- a/arch/x86/lib/delay.c +++ b/arch/x86/lib/delay.c | |||
| @@ -55,8 +55,10 @@ static void delay_tsc(unsigned long loops) | |||
| 55 | 55 | ||
| 56 | preempt_disable(); | 56 | preempt_disable(); |
| 57 | cpu = smp_processor_id(); | 57 | cpu = smp_processor_id(); |
| 58 | rdtsc_barrier(); | ||
| 58 | rdtscl(bclock); | 59 | rdtscl(bclock); |
| 59 | for (;;) { | 60 | for (;;) { |
| 61 | rdtsc_barrier(); | ||
| 60 | rdtscl(now); | 62 | rdtscl(now); |
| 61 | if ((now - bclock) >= loops) | 63 | if ((now - bclock) >= loops) |
| 62 | break; | 64 | break; |
| @@ -78,6 +80,7 @@ static void delay_tsc(unsigned long loops) | |||
| 78 | if (unlikely(cpu != smp_processor_id())) { | 80 | if (unlikely(cpu != smp_processor_id())) { |
| 79 | loops -= (now - bclock); | 81 | loops -= (now - bclock); |
| 80 | cpu = smp_processor_id(); | 82 | cpu = smp_processor_id(); |
| 83 | rdtsc_barrier(); | ||
| 81 | rdtscl(bclock); | 84 | rdtscl(bclock); |
| 82 | } | 85 | } |
| 83 | } | 86 | } |
diff --git a/arch/x86/lib/usercopy_32.c b/arch/x86/lib/usercopy_32.c index 7c8ca91bb9ec..1f118d462acc 100644 --- a/arch/x86/lib/usercopy_32.c +++ b/arch/x86/lib/usercopy_32.c | |||
| @@ -751,7 +751,7 @@ survive: | |||
| 751 | 751 | ||
| 752 | if (retval == -ENOMEM && is_global_init(current)) { | 752 | if (retval == -ENOMEM && is_global_init(current)) { |
| 753 | up_read(¤t->mm->mmap_sem); | 753 | up_read(¤t->mm->mmap_sem); |
| 754 | congestion_wait(WRITE, HZ/50); | 754 | congestion_wait(BLK_RW_ASYNC, HZ/50); |
| 755 | goto survive; | 755 | goto survive; |
| 756 | } | 756 | } |
| 757 | 757 | ||
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 78a5fff857be..85307cc6e45f 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c | |||
| @@ -426,10 +426,11 @@ static noinline int vmalloc_fault(unsigned long address) | |||
| 426 | } | 426 | } |
| 427 | 427 | ||
| 428 | static const char errata93_warning[] = | 428 | static const char errata93_warning[] = |
| 429 | KERN_ERR "******* Your BIOS seems to not contain a fix for K8 errata #93\n" | 429 | KERN_ERR |
| 430 | KERN_ERR "******* Working around it, but it may cause SEGVs or burn power.\n" | 430 | "******* Your BIOS seems to not contain a fix for K8 errata #93\n" |
| 431 | KERN_ERR "******* Please consider a BIOS update.\n" | 431 | "******* Working around it, but it may cause SEGVs or burn power.\n" |
| 432 | KERN_ERR "******* Disabling USB legacy in the BIOS may also help.\n"; | 432 | "******* Please consider a BIOS update.\n" |
| 433 | "******* Disabling USB legacy in the BIOS may also help.\n"; | ||
| 433 | 434 | ||
| 434 | /* | 435 | /* |
| 435 | * No vm86 mode in 64-bit mode: | 436 | * No vm86 mode in 64-bit mode: |
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index f53b57e4086f..0607119cef94 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <asm/system.h> | 12 | #include <asm/system.h> |
| 13 | #include <asm/tlbflush.h> | 13 | #include <asm/tlbflush.h> |
| 14 | #include <asm/tlb.h> | 14 | #include <asm/tlb.h> |
| 15 | #include <asm/proto.h> | ||
| 15 | 16 | ||
| 16 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); | 17 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); |
| 17 | 18 | ||
| @@ -177,20 +178,6 @@ static int __meminit save_mr(struct map_range *mr, int nr_range, | |||
| 177 | return nr_range; | 178 | return nr_range; |
| 178 | } | 179 | } |
| 179 | 180 | ||
| 180 | #ifdef CONFIG_X86_64 | ||
| 181 | static void __init init_gbpages(void) | ||
| 182 | { | ||
| 183 | if (direct_gbpages && cpu_has_gbpages) | ||
| 184 | printk(KERN_INFO "Using GB pages for direct mapping\n"); | ||
| 185 | else | ||
| 186 | direct_gbpages = 0; | ||
| 187 | } | ||
| 188 | #else | ||
| 189 | static inline void init_gbpages(void) | ||
| 190 | { | ||
| 191 | } | ||
| 192 | #endif | ||
| 193 | |||
| 194 | /* | 181 | /* |
| 195 | * Setup the direct mapping of the physical memory at PAGE_OFFSET. | 182 | * Setup the direct mapping of the physical memory at PAGE_OFFSET. |
| 196 | * This runs before bootmem is initialized and gets pages directly from | 183 | * This runs before bootmem is initialized and gets pages directly from |
| @@ -210,9 +197,6 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, | |||
| 210 | 197 | ||
| 211 | printk(KERN_INFO "init_memory_mapping: %016lx-%016lx\n", start, end); | 198 | printk(KERN_INFO "init_memory_mapping: %016lx-%016lx\n", start, end); |
| 212 | 199 | ||
| 213 | if (!after_bootmem) | ||
| 214 | init_gbpages(); | ||
| 215 | |||
| 216 | #if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_KMEMCHECK) | 200 | #if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_KMEMCHECK) |
| 217 | /* | 201 | /* |
| 218 | * For CONFIG_DEBUG_PAGEALLOC, identity mapping will use small pages. | 202 | * For CONFIG_DEBUG_PAGEALLOC, identity mapping will use small pages. |
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index c4378f4fd4a5..6176fe8f29e0 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c | |||
| @@ -598,6 +598,15 @@ void __init paging_init(void) | |||
| 598 | 598 | ||
| 599 | sparse_memory_present_with_active_regions(MAX_NUMNODES); | 599 | sparse_memory_present_with_active_regions(MAX_NUMNODES); |
| 600 | sparse_init(); | 600 | sparse_init(); |
| 601 | |||
| 602 | /* | ||
| 603 | * clear the default setting with node 0 | ||
| 604 | * note: don't use nodes_clear here, that is really clearing when | ||
| 605 | * numa support is not compiled in, and later node_set_state | ||
| 606 | * will not set it back. | ||
| 607 | */ | ||
| 608 | node_clear_state(0, N_NORMAL_MEMORY); | ||
| 609 | |||
| 601 | free_area_init_nodes(max_zone_pfns); | 610 | free_area_init_nodes(max_zone_pfns); |
| 602 | } | 611 | } |
| 603 | 612 | ||
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 3cfe9ced8a4c..1b734d7a8966 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | #include <linux/interrupt.h> | 11 | #include <linux/interrupt.h> |
| 12 | #include <linux/seq_file.h> | 12 | #include <linux/seq_file.h> |
| 13 | #include <linux/debugfs.h> | 13 | #include <linux/debugfs.h> |
| 14 | #include <linux/pfn.h> | ||
| 14 | 15 | ||
| 15 | #include <asm/e820.h> | 16 | #include <asm/e820.h> |
| 16 | #include <asm/processor.h> | 17 | #include <asm/processor.h> |
| @@ -681,8 +682,9 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias); | |||
| 681 | static int cpa_process_alias(struct cpa_data *cpa) | 682 | static int cpa_process_alias(struct cpa_data *cpa) |
| 682 | { | 683 | { |
| 683 | struct cpa_data alias_cpa; | 684 | struct cpa_data alias_cpa; |
| 684 | int ret = 0; | 685 | unsigned long laddr = (unsigned long)__va(cpa->pfn << PAGE_SHIFT); |
| 685 | unsigned long temp_cpa_vaddr, vaddr; | 686 | unsigned long vaddr, remapped; |
| 687 | int ret; | ||
| 686 | 688 | ||
| 687 | if (cpa->pfn >= max_pfn_mapped) | 689 | if (cpa->pfn >= max_pfn_mapped) |
| 688 | return 0; | 690 | return 0; |
| @@ -706,42 +708,55 @@ static int cpa_process_alias(struct cpa_data *cpa) | |||
| 706 | PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT)))) { | 708 | PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT)))) { |
| 707 | 709 | ||
| 708 | alias_cpa = *cpa; | 710 | alias_cpa = *cpa; |
| 709 | temp_cpa_vaddr = (unsigned long) __va(cpa->pfn << PAGE_SHIFT); | 711 | alias_cpa.vaddr = &laddr; |
| 710 | alias_cpa.vaddr = &temp_cpa_vaddr; | ||
| 711 | alias_cpa.flags &= ~(CPA_PAGES_ARRAY | CPA_ARRAY); | 712 | alias_cpa.flags &= ~(CPA_PAGES_ARRAY | CPA_ARRAY); |
| 712 | 713 | ||
| 713 | |||
| 714 | ret = __change_page_attr_set_clr(&alias_cpa, 0); | 714 | ret = __change_page_attr_set_clr(&alias_cpa, 0); |
| 715 | if (ret) | ||
| 716 | return ret; | ||
| 715 | } | 717 | } |
| 716 | 718 | ||
| 717 | #ifdef CONFIG_X86_64 | 719 | #ifdef CONFIG_X86_64 |
| 718 | if (ret) | ||
| 719 | return ret; | ||
| 720 | /* | 720 | /* |
| 721 | * No need to redo, when the primary call touched the high | 721 | * If the primary call didn't touch the high mapping already |
| 722 | * mapping already: | 722 | * and the physical address is inside the kernel map, we need |
| 723 | */ | ||
| 724 | if (within(vaddr, (unsigned long) _text, _brk_end)) | ||
| 725 | return 0; | ||
| 726 | |||
| 727 | /* | ||
| 728 | * If the physical address is inside the kernel map, we need | ||
| 729 | * to touch the high mapped kernel as well: | 723 | * to touch the high mapped kernel as well: |
| 730 | */ | 724 | */ |
| 731 | if (!within(cpa->pfn, highmap_start_pfn(), highmap_end_pfn())) | 725 | if (!within(vaddr, (unsigned long)_text, _brk_end) && |
| 732 | return 0; | 726 | within(cpa->pfn, highmap_start_pfn(), highmap_end_pfn())) { |
| 727 | unsigned long temp_cpa_vaddr = (cpa->pfn << PAGE_SHIFT) + | ||
| 728 | __START_KERNEL_map - phys_base; | ||
| 729 | alias_cpa = *cpa; | ||
| 730 | alias_cpa.vaddr = &temp_cpa_vaddr; | ||
| 731 | alias_cpa.flags &= ~(CPA_PAGES_ARRAY | CPA_ARRAY); | ||
| 733 | 732 | ||
| 734 | alias_cpa = *cpa; | 733 | /* |
| 735 | temp_cpa_vaddr = (cpa->pfn << PAGE_SHIFT) + __START_KERNEL_map - phys_base; | 734 | * The high mapping range is imprecise, so ignore the |
| 736 | alias_cpa.vaddr = &temp_cpa_vaddr; | 735 | * return value. |
| 737 | alias_cpa.flags &= ~(CPA_PAGES_ARRAY | CPA_ARRAY); | 736 | */ |
| 737 | __change_page_attr_set_clr(&alias_cpa, 0); | ||
| 738 | } | ||
| 739 | #endif | ||
| 738 | 740 | ||
| 739 | /* | 741 | /* |
| 740 | * The high mapping range is imprecise, so ignore the return value. | 742 | * If the PMD page was partially used for per-cpu remapping, |
| 743 | * the recycled area needs to be split and modified. Because | ||
| 744 | * the area is always proper subset of a PMD page | ||
| 745 | * cpa->numpages is guaranteed to be 1 for these areas, so | ||
| 746 | * there's no need to loop over and check for further remaps. | ||
| 741 | */ | 747 | */ |
| 742 | __change_page_attr_set_clr(&alias_cpa, 0); | 748 | remapped = (unsigned long)pcpu_lpage_remapped((void *)laddr); |
| 743 | #endif | 749 | if (remapped) { |
| 744 | return ret; | 750 | WARN_ON(cpa->numpages > 1); |
| 751 | alias_cpa = *cpa; | ||
| 752 | alias_cpa.vaddr = &remapped; | ||
| 753 | alias_cpa.flags &= ~(CPA_PAGES_ARRAY | CPA_ARRAY); | ||
| 754 | ret = __change_page_attr_set_clr(&alias_cpa, 0); | ||
| 755 | if (ret) | ||
| 756 | return ret; | ||
| 757 | } | ||
| 758 | |||
| 759 | return 0; | ||
| 745 | } | 760 | } |
| 746 | 761 | ||
| 747 | static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias) | 762 | static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias) |
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index b07dd8d0b321..89b9a5cd63da 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c | |||
| @@ -390,7 +390,7 @@ static int __init p4_init(char **cpu_type) | |||
| 390 | static int force_arch_perfmon; | 390 | static int force_arch_perfmon; |
| 391 | static int force_cpu_type(const char *str, struct kernel_param *kp) | 391 | static int force_cpu_type(const char *str, struct kernel_param *kp) |
| 392 | { | 392 | { |
| 393 | if (!strcmp(str, "archperfmon")) { | 393 | if (!strcmp(str, "arch_perfmon")) { |
| 394 | force_arch_perfmon = 1; | 394 | force_arch_perfmon = 1; |
| 395 | printk(KERN_INFO "oprofile: forcing architectural perfmon\n"); | 395 | printk(KERN_INFO "oprofile: forcing architectural perfmon\n"); |
| 396 | } | 396 | } |
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index b26626dc517c..1014eb4bfc37 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c | |||
| @@ -68,6 +68,10 @@ setup_resource(struct acpi_resource *acpi_res, void *data) | |||
| 68 | unsigned long flags; | 68 | unsigned long flags; |
| 69 | struct resource *root; | 69 | struct resource *root; |
| 70 | int max_root_bus_resources = PCI_BUS_NUM_RESOURCES; | 70 | int max_root_bus_resources = PCI_BUS_NUM_RESOURCES; |
| 71 | u64 start, end; | ||
| 72 | |||
| 73 | if (bus_has_transparent_bridge(info->bus)) | ||
| 74 | max_root_bus_resources -= 3; | ||
| 71 | 75 | ||
| 72 | status = resource_to_addr(acpi_res, &addr); | 76 | status = resource_to_addr(acpi_res, &addr); |
| 73 | if (!ACPI_SUCCESS(status)) | 77 | if (!ACPI_SUCCESS(status)) |
| @@ -84,25 +88,24 @@ setup_resource(struct acpi_resource *acpi_res, void *data) | |||
| 84 | } else | 88 | } else |
| 85 | return AE_OK; | 89 | return AE_OK; |
| 86 | 90 | ||
| 87 | res = &info->res[info->res_num]; | 91 | start = addr.minimum + addr.translation_offset; |
| 88 | res->name = info->name; | 92 | end = start + addr.address_length - 1; |
| 89 | res->flags = flags; | ||
| 90 | res->start = addr.minimum + addr.translation_offset; | ||
| 91 | res->end = res->start + addr.address_length - 1; | ||
| 92 | res->child = NULL; | ||
| 93 | |||
| 94 | if (bus_has_transparent_bridge(info->bus)) | ||
| 95 | max_root_bus_resources -= 3; | ||
| 96 | if (info->res_num >= max_root_bus_resources) { | 93 | if (info->res_num >= max_root_bus_resources) { |
| 97 | printk(KERN_WARNING "PCI: Failed to allocate 0x%lx-0x%lx " | 94 | printk(KERN_WARNING "PCI: Failed to allocate 0x%lx-0x%lx " |
| 98 | "from %s for %s due to _CRS returning more than " | 95 | "from %s for %s due to _CRS returning more than " |
| 99 | "%d resource descriptors\n", (unsigned long) res->start, | 96 | "%d resource descriptors\n", (unsigned long) start, |
| 100 | (unsigned long) res->end, root->name, info->name, | 97 | (unsigned long) end, root->name, info->name, |
| 101 | max_root_bus_resources); | 98 | max_root_bus_resources); |
| 102 | info->res_num++; | ||
| 103 | return AE_OK; | 99 | return AE_OK; |
| 104 | } | 100 | } |
| 105 | 101 | ||
| 102 | res = &info->res[info->res_num]; | ||
| 103 | res->name = info->name; | ||
| 104 | res->flags = flags; | ||
| 105 | res->start = start; | ||
| 106 | res->end = end; | ||
| 107 | res->child = NULL; | ||
| 108 | |||
| 106 | if (insert_resource(root, res)) { | 109 | if (insert_resource(root, res)) { |
| 107 | printk(KERN_ERR "PCI: Failed to allocate 0x%lx-0x%lx " | 110 | printk(KERN_ERR "PCI: Failed to allocate 0x%lx-0x%lx " |
| 108 | "from %s for %s\n", (unsigned long) res->start, | 111 | "from %s for %s\n", (unsigned long) res->start, |
| @@ -115,23 +118,6 @@ setup_resource(struct acpi_resource *acpi_res, void *data) | |||
| 115 | } | 118 | } |
| 116 | 119 | ||
| 117 | static void | 120 | static void |
| 118 | adjust_transparent_bridge_resources(struct pci_bus *bus) | ||
| 119 | { | ||
| 120 | struct pci_dev *dev; | ||
| 121 | |||
| 122 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
| 123 | int i; | ||
| 124 | u16 class = dev->class >> 8; | ||
| 125 | |||
| 126 | if (class == PCI_CLASS_BRIDGE_PCI && dev->transparent) { | ||
| 127 | for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++) | ||
| 128 | dev->subordinate->resource[i] = | ||
| 129 | dev->bus->resource[i - 3]; | ||
| 130 | } | ||
| 131 | } | ||
| 132 | } | ||
| 133 | |||
| 134 | static void | ||
| 135 | get_current_resources(struct acpi_device *device, int busnum, | 121 | get_current_resources(struct acpi_device *device, int busnum, |
| 136 | int domain, struct pci_bus *bus) | 122 | int domain, struct pci_bus *bus) |
| 137 | { | 123 | { |
| @@ -158,8 +144,6 @@ get_current_resources(struct acpi_device *device, int busnum, | |||
| 158 | info.res_num = 0; | 144 | info.res_num = 0; |
| 159 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource, | 145 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource, |
| 160 | &info); | 146 | &info); |
| 161 | if (info.res_num) | ||
| 162 | adjust_transparent_bridge_resources(bus); | ||
| 163 | 147 | ||
| 164 | return; | 148 | return; |
| 165 | 149 | ||
| @@ -222,8 +206,15 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do | |||
| 222 | */ | 206 | */ |
| 223 | memcpy(bus->sysdata, sd, sizeof(*sd)); | 207 | memcpy(bus->sysdata, sd, sizeof(*sd)); |
| 224 | kfree(sd); | 208 | kfree(sd); |
| 225 | } else | 209 | } else { |
| 226 | bus = pci_scan_bus_parented(NULL, busnum, &pci_root_ops, sd); | 210 | bus = pci_create_bus(NULL, busnum, &pci_root_ops, sd); |
| 211 | if (bus) { | ||
| 212 | if (pci_probe & PCI_USE__CRS) | ||
| 213 | get_current_resources(device, busnum, domain, | ||
| 214 | bus); | ||
| 215 | bus->subordinate = pci_scan_child_bus(bus); | ||
| 216 | } | ||
| 217 | } | ||
| 227 | 218 | ||
| 228 | if (!bus) | 219 | if (!bus) |
| 229 | kfree(sd); | 220 | kfree(sd); |
| @@ -238,8 +229,6 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do | |||
| 238 | #endif | 229 | #endif |
| 239 | } | 230 | } |
| 240 | 231 | ||
| 241 | if (bus && (pci_probe & PCI_USE__CRS)) | ||
| 242 | get_current_resources(device, busnum, domain, bus); | ||
| 243 | return bus; | 232 | return bus; |
| 244 | } | 233 | } |
| 245 | 234 | ||
diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c index f893d6a6e803..3ffa10df20b9 100644 --- a/arch/x86/pci/amd_bus.c +++ b/arch/x86/pci/amd_bus.c | |||
| @@ -100,8 +100,9 @@ void x86_pci_root_bus_res_quirks(struct pci_bus *b) | |||
| 100 | int j; | 100 | int j; |
| 101 | struct pci_root_info *info; | 101 | struct pci_root_info *info; |
| 102 | 102 | ||
| 103 | /* don't go for it if _CRS is used */ | 103 | /* don't go for it if _CRS is used already */ |
| 104 | if (pci_probe & PCI_USE__CRS) | 104 | if (b->resource[0] != &ioport_resource || |
| 105 | b->resource[1] != &iomem_resource) | ||
| 105 | return; | 106 | return; |
| 106 | 107 | ||
| 107 | /* if only one root bus, don't need to anything */ | 108 | /* if only one root bus, don't need to anything */ |
| @@ -116,6 +117,9 @@ void x86_pci_root_bus_res_quirks(struct pci_bus *b) | |||
| 116 | if (i == pci_root_num) | 117 | if (i == pci_root_num) |
| 117 | return; | 118 | return; |
| 118 | 119 | ||
| 120 | printk(KERN_DEBUG "PCI: peer root bus %02x res updated from pci conf\n", | ||
| 121 | b->number); | ||
| 122 | |||
| 119 | info = &pci_root_info[i]; | 123 | info = &pci_root_info[i]; |
| 120 | for (j = 0; j < info->res_num; j++) { | 124 | for (j = 0; j < info->res_num; j++) { |
| 121 | struct resource *res; | 125 | struct resource *res; |
diff --git a/arch/x86/power/Makefile b/arch/x86/power/Makefile index de2abbd07544..a6a198c33623 100644 --- a/arch/x86/power/Makefile +++ b/arch/x86/power/Makefile | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | # __restore_processor_state() restores %gs after S3 resume and so should not | 1 | # __restore_processor_state() restores %gs after S3 resume and so should not |
| 2 | # itself be stack-protected | 2 | # itself be stack-protected |
| 3 | nostackp := $(call cc-option, -fno-stack-protector) | 3 | nostackp := $(call cc-option, -fno-stack-protector) |
| 4 | CFLAGS_cpu_$(BITS).o := $(nostackp) | 4 | CFLAGS_cpu.o := $(nostackp) |
| 5 | 5 | ||
| 6 | obj-$(CONFIG_PM_SLEEP) += cpu.o | 6 | obj-$(CONFIG_PM_SLEEP) += cpu.o |
| 7 | obj-$(CONFIG_HIBERNATION) += hibernate_$(BITS).o hibernate_asm_$(BITS).o | 7 | obj-$(CONFIG_HIBERNATION) += hibernate_$(BITS).o hibernate_asm_$(BITS).o |
diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c index d277ef1eea51..b3d20b9cac63 100644 --- a/arch/x86/power/cpu.c +++ b/arch/x86/power/cpu.c | |||
| @@ -244,7 +244,7 @@ static void __restore_processor_state(struct saved_context *ctxt) | |||
| 244 | do_fpu_end(); | 244 | do_fpu_end(); |
| 245 | mtrr_ap_init(); | 245 | mtrr_ap_init(); |
| 246 | 246 | ||
| 247 | #ifdef CONFIG_X86_32 | 247 | #ifdef CONFIG_X86_OLD_MCE |
| 248 | mcheck_init(&boot_cpu_data); | 248 | mcheck_init(&boot_cpu_data); |
| 249 | #endif | 249 | #endif |
| 250 | } | 250 | } |
