Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
x86: Fix serialization in pit_expect_msb()

+22 -7
+22 -7
arch/x86/kernel/tsc.c
··· 275 275 * use the TSC value at the transitions to calculate a pretty 276 276 * good value for the TSC frequencty. 277 277 */ 278 + static inline int pit_verify_msb(unsigned char val) 279 + { 280 + /* Ignore LSB */ 281 + inb(0x42); 282 + return inb(0x42) == val; 283 + } 284 + 278 285 static inline int pit_expect_msb(unsigned char val, u64 *tscp, unsigned long *deltap) 279 286 { 280 287 int count; 281 288 u64 tsc = 0; 282 289 283 290 for (count = 0; count < 50000; count++) { 284 - /* Ignore LSB */ 285 - inb(0x42); 286 - if (inb(0x42) != val) 291 + if (!pit_verify_msb(val)) 287 292 break; 288 293 tsc = get_cycles(); 289 294 } ··· 341 336 * to do that is to just read back the 16-bit counter 342 337 * once from the PIT. 343 338 */ 344 - inb(0x42); 345 - inb(0x42); 339 + pit_verify_msb(0); 346 340 347 341 if (pit_expect_msb(0xff, &tsc, &d1)) { 348 342 for (i = 1; i <= MAX_QUICK_PIT_ITERATIONS; i++) { ··· 352 348 * Iterate until the error is less than 500 ppm 353 349 */ 354 350 delta -= tsc; 355 - if (d1+d2 < delta >> 11) 356 - goto success; 351 + if (d1+d2 >= delta >> 11) 352 + continue; 353 + 354 + /* 355 + * Check the PIT one more time to verify that 356 + * all TSC reads were stable wrt the PIT. 357 + * 358 + * This also guarantees serialization of the 359 + * last cycle read ('d2') in pit_expect_msb. 360 + */ 361 + if (!pit_verify_msb(0xfe - i)) 362 + break; 363 + goto success; 357 364 } 358 365 } 359 366 printk("Fast TSC calibration failed\n");