diff options
Diffstat (limited to 'arch/x86/kernel')
| -rw-r--r-- | arch/x86/kernel/amd_iommu.c | 5 | ||||
| -rw-r--r-- | arch/x86/kernel/amd_iommu_init.c | 7 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/Makefile | 5 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce_64.c | 3 | ||||
| -rw-r--r-- | arch/x86/kernel/ds.c | 11 | ||||
| -rw-r--r-- | arch/x86/kernel/microcode_core.c | 19 | ||||
| -rw-r--r-- | arch/x86/kernel/microcode_intel.c | 6 | ||||
| -rw-r--r-- | arch/x86/kernel/pci-gart_64.c | 4 | ||||
| -rw-r--r-- | arch/x86/kernel/process_32.c | 20 | ||||
| -rw-r--r-- | arch/x86/kernel/process_64.c | 20 | ||||
| -rw-r--r-- | arch/x86/kernel/ptrace.c | 93 | ||||
| -rw-r--r-- | arch/x86/kernel/smpboot.c | 2 | 
12 files changed, 138 insertions, 57 deletions
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index a7b6dec6fc3f..0a60d60ed036 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c  | |||
| @@ -235,8 +235,9 @@ static int iommu_completion_wait(struct amd_iommu *iommu) | |||
| 235 | status &= ~MMIO_STATUS_COM_WAIT_INT_MASK; | 235 | status &= ~MMIO_STATUS_COM_WAIT_INT_MASK; | 
| 236 | writel(status, iommu->mmio_base + MMIO_STATUS_OFFSET); | 236 | writel(status, iommu->mmio_base + MMIO_STATUS_OFFSET); | 
| 237 | 237 | ||
| 238 | if (unlikely((i == EXIT_LOOP_COUNT) && printk_ratelimit())) | 238 | if (unlikely(i == EXIT_LOOP_COUNT)) | 
| 239 | printk(KERN_WARNING "AMD IOMMU: Completion wait loop failed\n"); | 239 | panic("AMD IOMMU: Completion wait loop failed\n"); | 
| 240 | |||
| 240 | out: | 241 | out: | 
| 241 | spin_unlock_irqrestore(&iommu->lock, flags); | 242 | spin_unlock_irqrestore(&iommu->lock, flags); | 
| 242 | 243 | ||
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index 30ae2701b3df..c6cc22815d35 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c  | |||
| @@ -427,6 +427,10 @@ static u8 * __init alloc_command_buffer(struct amd_iommu *iommu) | |||
| 427 | memcpy_toio(iommu->mmio_base + MMIO_CMD_BUF_OFFSET, | 427 | memcpy_toio(iommu->mmio_base + MMIO_CMD_BUF_OFFSET, | 
| 428 | &entry, sizeof(entry)); | 428 | &entry, sizeof(entry)); | 
| 429 | 429 | ||
| 430 | /* set head and tail to zero manually */ | ||
| 431 | writel(0x00, iommu->mmio_base + MMIO_CMD_HEAD_OFFSET); | ||
| 432 | writel(0x00, iommu->mmio_base + MMIO_CMD_TAIL_OFFSET); | ||
| 433 | |||
| 430 | iommu_feature_enable(iommu, CONTROL_CMDBUF_EN); | 434 | iommu_feature_enable(iommu, CONTROL_CMDBUF_EN); | 
| 431 | 435 | ||
| 432 | return cmd_buf; | 436 | return cmd_buf; | 
| @@ -1074,7 +1078,8 @@ int __init amd_iommu_init(void) | |||
| 1074 | goto free; | 1078 | goto free; | 
| 1075 | 1079 | ||
| 1076 | /* IOMMU rlookup table - find the IOMMU for a specific device */ | 1080 | /* IOMMU rlookup table - find the IOMMU for a specific device */ | 
| 1077 | amd_iommu_rlookup_table = (void *)__get_free_pages(GFP_KERNEL, | 1081 | amd_iommu_rlookup_table = (void *)__get_free_pages( | 
| 1082 | GFP_KERNEL | __GFP_ZERO, | ||
| 1078 | get_order(rlookup_table_size)); | 1083 | get_order(rlookup_table_size)); | 
| 1079 | if (amd_iommu_rlookup_table == NULL) | 1084 | if (amd_iommu_rlookup_table == NULL) | 
| 1080 | goto free; | 1085 | goto free; | 
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index 82ec6075c057..4ae495a313f3 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile  | |||
| @@ -2,6 +2,11 @@ | |||
| 2 | # Makefile for x86-compatible CPU details and quirks | 2 | # Makefile for x86-compatible CPU details and quirks | 
| 3 | # | 3 | # | 
| 4 | 4 | ||
| 5 | # Don't trace early stages of a secondary CPU boot | ||
| 6 | ifdef CONFIG_FUNCTION_TRACER | ||
| 7 | CFLAGS_REMOVE_common.o = -pg | ||
| 8 | endif | ||
| 9 | |||
| 5 | obj-y := intel_cacheinfo.o addon_cpuid_features.o | 10 | obj-y := intel_cacheinfo.o addon_cpuid_features.o | 
| 6 | obj-y += proc.o capflags.o powerflags.o common.o | 11 | obj-y += proc.o capflags.o powerflags.o common.o | 
| 7 | 12 | ||
diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c index 4b031a4ac856..1c838032fd37 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_64.c  | |||
| @@ -510,12 +510,9 @@ static void __cpuinit mce_cpu_features(struct cpuinfo_x86 *c) | |||
| 510 | */ | 510 | */ | 
| 511 | void __cpuinit mcheck_init(struct cpuinfo_x86 *c) | 511 | void __cpuinit mcheck_init(struct cpuinfo_x86 *c) | 
| 512 | { | 512 | { | 
| 513 | static cpumask_t mce_cpus = CPU_MASK_NONE; | ||
| 514 | |||
| 515 | mce_cpu_quirks(c); | 513 | mce_cpu_quirks(c); | 
| 516 | 514 | ||
| 517 | if (mce_dont_init || | 515 | if (mce_dont_init || | 
| 518 | cpu_test_and_set(smp_processor_id(), mce_cpus) || | ||
| 519 | !mce_available(c)) | 516 | !mce_available(c)) | 
| 520 | return; | 517 | return; | 
| 521 | 518 | ||
diff --git a/arch/x86/kernel/ds.c b/arch/x86/kernel/ds.c index 98d271e60e08..da91701a2348 100644 --- a/arch/x86/kernel/ds.c +++ b/arch/x86/kernel/ds.c  | |||
| @@ -1017,3 +1017,14 @@ void ds_switch_to(struct task_struct *prev, struct task_struct *next) | |||
| 1017 | 1017 | ||
| 1018 | update_debugctlmsr(next->thread.debugctlmsr); | 1018 | update_debugctlmsr(next->thread.debugctlmsr); | 
| 1019 | } | 1019 | } | 
| 1020 | |||
| 1021 | void ds_copy_thread(struct task_struct *tsk, struct task_struct *father) | ||
| 1022 | { | ||
| 1023 | clear_tsk_thread_flag(tsk, TIF_DS_AREA_MSR); | ||
| 1024 | tsk->thread.ds_ctx = NULL; | ||
| 1025 | } | ||
| 1026 | |||
| 1027 | void ds_exit_thread(struct task_struct *tsk) | ||
| 1028 | { | ||
| 1029 | WARN_ON(tsk->thread.ds_ctx); | ||
| 1030 | } | ||
diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c index 82fb2809ce32..c4b5b24e0217 100644 --- a/arch/x86/kernel/microcode_core.c +++ b/arch/x86/kernel/microcode_core.c  | |||
| @@ -272,13 +272,18 @@ static struct attribute_group mc_attr_group = { | |||
| 272 | .name = "microcode", | 272 | .name = "microcode", | 
| 273 | }; | 273 | }; | 
| 274 | 274 | ||
| 275 | static void microcode_fini_cpu(int cpu) | 275 | static void __microcode_fini_cpu(int cpu) | 
| 276 | { | 276 | { | 
| 277 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | 277 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | 
| 278 | 278 | ||
| 279 | mutex_lock(µcode_mutex); | ||
| 280 | microcode_ops->microcode_fini_cpu(cpu); | 279 | microcode_ops->microcode_fini_cpu(cpu); | 
| 281 | uci->valid = 0; | 280 | uci->valid = 0; | 
| 281 | } | ||
| 282 | |||
| 283 | static void microcode_fini_cpu(int cpu) | ||
| 284 | { | ||
| 285 | mutex_lock(µcode_mutex); | ||
| 286 | __microcode_fini_cpu(cpu); | ||
| 282 | mutex_unlock(µcode_mutex); | 287 | mutex_unlock(µcode_mutex); | 
| 283 | } | 288 | } | 
| 284 | 289 | ||
| @@ -306,12 +311,16 @@ static int microcode_resume_cpu(int cpu) | |||
| 306 | * to this cpu (a bit of paranoia): | 311 | * to this cpu (a bit of paranoia): | 
| 307 | */ | 312 | */ | 
| 308 | if (microcode_ops->collect_cpu_info(cpu, &nsig)) { | 313 | if (microcode_ops->collect_cpu_info(cpu, &nsig)) { | 
| 309 | microcode_fini_cpu(cpu); | 314 | __microcode_fini_cpu(cpu); | 
| 315 | printk(KERN_ERR "failed to collect_cpu_info for resuming cpu #%d\n", | ||
| 316 | cpu); | ||
| 310 | return -1; | 317 | return -1; | 
| 311 | } | 318 | } | 
| 312 | 319 | ||
| 313 | if (memcmp(&nsig, &uci->cpu_sig, sizeof(nsig))) { | 320 | if ((nsig.sig != uci->cpu_sig.sig) || (nsig.pf != uci->cpu_sig.pf)) { | 
| 314 | microcode_fini_cpu(cpu); | 321 | __microcode_fini_cpu(cpu); | 
| 322 | printk(KERN_ERR "cached ucode doesn't match the resuming cpu #%d\n", | ||
| 323 | cpu); | ||
| 315 | /* Should we look for a new ucode here? */ | 324 | /* Should we look for a new ucode here? */ | 
| 316 | return 1; | 325 | return 1; | 
| 317 | } | 326 | } | 
diff --git a/arch/x86/kernel/microcode_intel.c b/arch/x86/kernel/microcode_intel.c index 622dc4a21784..a8e62792d171 100644 --- a/arch/x86/kernel/microcode_intel.c +++ b/arch/x86/kernel/microcode_intel.c  | |||
| @@ -155,6 +155,7 @@ static DEFINE_SPINLOCK(microcode_update_lock); | |||
| 155 | static int collect_cpu_info(int cpu_num, struct cpu_signature *csig) | 155 | static int collect_cpu_info(int cpu_num, struct cpu_signature *csig) | 
| 156 | { | 156 | { | 
| 157 | struct cpuinfo_x86 *c = &cpu_data(cpu_num); | 157 | struct cpuinfo_x86 *c = &cpu_data(cpu_num); | 
| 158 | unsigned long flags; | ||
| 158 | unsigned int val[2]; | 159 | unsigned int val[2]; | 
| 159 | 160 | ||
| 160 | memset(csig, 0, sizeof(*csig)); | 161 | memset(csig, 0, sizeof(*csig)); | 
| @@ -174,11 +175,16 @@ static int collect_cpu_info(int cpu_num, struct cpu_signature *csig) | |||
| 174 | csig->pf = 1 << ((val[1] >> 18) & 7); | 175 | csig->pf = 1 << ((val[1] >> 18) & 7); | 
| 175 | } | 176 | } | 
| 176 | 177 | ||
| 178 | /* serialize access to the physical write to MSR 0x79 */ | ||
| 179 | spin_lock_irqsave(µcode_update_lock, flags); | ||
| 180 | |||
| 177 | wrmsr(MSR_IA32_UCODE_REV, 0, 0); | 181 | wrmsr(MSR_IA32_UCODE_REV, 0, 0); | 
| 178 | /* see notes above for revision 1.07. Apparent chip bug */ | 182 | /* see notes above for revision 1.07. Apparent chip bug */ | 
| 179 | sync_core(); | 183 | sync_core(); | 
| 180 | /* get the current revision from MSR 0x8B */ | 184 | /* get the current revision from MSR 0x8B */ | 
| 181 | rdmsr(MSR_IA32_UCODE_REV, val[0], csig->rev); | 185 | rdmsr(MSR_IA32_UCODE_REV, val[0], csig->rev); | 
| 186 | spin_unlock_irqrestore(µcode_update_lock, flags); | ||
| 187 | |||
| 182 | pr_debug("microcode: collect_cpu_info : sig=0x%x, pf=0x%x, rev=0x%x\n", | 188 | pr_debug("microcode: collect_cpu_info : sig=0x%x, pf=0x%x, rev=0x%x\n", | 
| 183 | csig->sig, csig->pf, csig->rev); | 189 | csig->sig, csig->pf, csig->rev); | 
| 184 | 190 | ||
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index ba7ad83e20a8..a35eaa379ff6 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c  | |||
| @@ -745,10 +745,8 @@ void __init gart_iommu_init(void) | |||
| 745 | unsigned long scratch; | 745 | unsigned long scratch; | 
| 746 | long i; | 746 | long i; | 
| 747 | 747 | ||
| 748 | if (cache_k8_northbridges() < 0 || num_k8_northbridges == 0) { | 748 | if (cache_k8_northbridges() < 0 || num_k8_northbridges == 0) | 
| 749 | printk(KERN_INFO "PCI-GART: No AMD GART found.\n"); | ||
| 750 | return; | 749 | return; | 
| 751 | } | ||
| 752 | 750 | ||
| 753 | #ifndef CONFIG_AGP_AMD64 | 751 | #ifndef CONFIG_AGP_AMD64 | 
| 754 | no_agp = 1; | 752 | no_agp = 1; | 
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 605eff9a8ac0..3ba155d24884 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c  | |||
| @@ -60,6 +60,7 @@ | |||
| 60 | #include <asm/idle.h> | 60 | #include <asm/idle.h> | 
| 61 | #include <asm/syscalls.h> | 61 | #include <asm/syscalls.h> | 
| 62 | #include <asm/smp.h> | 62 | #include <asm/smp.h> | 
| 63 | #include <asm/ds.h> | ||
| 63 | 64 | ||
| 64 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); | 65 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); | 
| 65 | 66 | ||
| @@ -251,17 +252,8 @@ void exit_thread(void) | |||
| 251 | tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET; | 252 | tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET; | 
| 252 | put_cpu(); | 253 | put_cpu(); | 
| 253 | } | 254 | } | 
| 254 | #ifdef CONFIG_X86_DS | 255 | |
| 255 | /* Free any BTS tracers that have not been properly released. */ | 256 | ds_exit_thread(current); | 
| 256 | if (unlikely(current->bts)) { | ||
| 257 | ds_release_bts(current->bts); | ||
| 258 | current->bts = NULL; | ||
| 259 | |||
| 260 | kfree(current->bts_buffer); | ||
| 261 | current->bts_buffer = NULL; | ||
| 262 | current->bts_size = 0; | ||
| 263 | } | ||
| 264 | #endif /* CONFIG_X86_DS */ | ||
| 265 | } | 257 | } | 
| 266 | 258 | ||
| 267 | void flush_thread(void) | 259 | void flush_thread(void) | 
| @@ -343,6 +335,12 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, | |||
| 343 | kfree(p->thread.io_bitmap_ptr); | 335 | kfree(p->thread.io_bitmap_ptr); | 
| 344 | p->thread.io_bitmap_max = 0; | 336 | p->thread.io_bitmap_max = 0; | 
| 345 | } | 337 | } | 
| 338 | |||
| 339 | ds_copy_thread(p, current); | ||
| 340 | |||
| 341 | clear_tsk_thread_flag(p, TIF_DEBUGCTLMSR); | ||
| 342 | p->thread.debugctlmsr = 0; | ||
| 343 | |||
| 346 | return err; | 344 | return err; | 
| 347 | } | 345 | } | 
| 348 | 346 | ||
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 1cfd2a4bf853..416fb9282f4f 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c  | |||
| @@ -53,6 +53,7 @@ | |||
| 53 | #include <asm/ia32.h> | 53 | #include <asm/ia32.h> | 
| 54 | #include <asm/idle.h> | 54 | #include <asm/idle.h> | 
| 55 | #include <asm/syscalls.h> | 55 | #include <asm/syscalls.h> | 
| 56 | #include <asm/ds.h> | ||
| 56 | 57 | ||
| 57 | asmlinkage extern void ret_from_fork(void); | 58 | asmlinkage extern void ret_from_fork(void); | 
| 58 | 59 | ||
| @@ -236,17 +237,8 @@ void exit_thread(void) | |||
| 236 | t->io_bitmap_max = 0; | 237 | t->io_bitmap_max = 0; | 
| 237 | put_cpu(); | 238 | put_cpu(); | 
| 238 | } | 239 | } | 
| 239 | #ifdef CONFIG_X86_DS | 240 | |
| 240 | /* Free any BTS tracers that have not been properly released. */ | 241 | ds_exit_thread(current); | 
| 241 | if (unlikely(current->bts)) { | ||
| 242 | ds_release_bts(current->bts); | ||
| 243 | current->bts = NULL; | ||
| 244 | |||
| 245 | kfree(current->bts_buffer); | ||
| 246 | current->bts_buffer = NULL; | ||
| 247 | current->bts_size = 0; | ||
| 248 | } | ||
| 249 | #endif /* CONFIG_X86_DS */ | ||
| 250 | } | 242 | } | 
| 251 | 243 | ||
| 252 | void flush_thread(void) | 244 | void flush_thread(void) | 
| @@ -376,6 +368,12 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, | |||
| 376 | if (err) | 368 | if (err) | 
| 377 | goto out; | 369 | goto out; | 
| 378 | } | 370 | } | 
| 371 | |||
| 372 | ds_copy_thread(p, me); | ||
| 373 | |||
| 374 | clear_tsk_thread_flag(p, TIF_DEBUGCTLMSR); | ||
| 375 | p->thread.debugctlmsr = 0; | ||
| 376 | |||
| 379 | err = 0; | 377 | err = 0; | 
| 380 | out: | 378 | out: | 
| 381 | if (err && p->thread.io_bitmap_ptr) { | 379 | if (err && p->thread.io_bitmap_ptr) { | 
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 45e9855da2d2..0a5df5f82fb9 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c  | |||
| @@ -650,6 +650,24 @@ static int ptrace_bts_drain(struct task_struct *child, | |||
| 650 | return drained; | 650 | return drained; | 
| 651 | } | 651 | } | 
| 652 | 652 | ||
| 653 | static int ptrace_bts_allocate_buffer(struct task_struct *child, size_t size) | ||
| 654 | { | ||
| 655 | child->bts_buffer = alloc_locked_buffer(size); | ||
| 656 | if (!child->bts_buffer) | ||
| 657 | return -ENOMEM; | ||
| 658 | |||
| 659 | child->bts_size = size; | ||
| 660 | |||
| 661 | return 0; | ||
| 662 | } | ||
| 663 | |||
| 664 | static void ptrace_bts_free_buffer(struct task_struct *child) | ||
| 665 | { | ||
| 666 | free_locked_buffer(child->bts_buffer, child->bts_size); | ||
| 667 | child->bts_buffer = NULL; | ||
| 668 | child->bts_size = 0; | ||
| 669 | } | ||
| 670 | |||
| 653 | static int ptrace_bts_config(struct task_struct *child, | 671 | static int ptrace_bts_config(struct task_struct *child, | 
| 654 | long cfg_size, | 672 | long cfg_size, | 
| 655 | const struct ptrace_bts_config __user *ucfg) | 673 | const struct ptrace_bts_config __user *ucfg) | 
| @@ -679,14 +697,13 @@ static int ptrace_bts_config(struct task_struct *child, | |||
| 679 | 697 | ||
| 680 | if ((cfg.flags & PTRACE_BTS_O_ALLOC) && | 698 | if ((cfg.flags & PTRACE_BTS_O_ALLOC) && | 
| 681 | (cfg.size != child->bts_size)) { | 699 | (cfg.size != child->bts_size)) { | 
| 682 | kfree(child->bts_buffer); | 700 | int error; | 
| 683 | 701 | ||
| 684 | child->bts_size = cfg.size; | 702 | ptrace_bts_free_buffer(child); | 
| 685 | child->bts_buffer = kzalloc(cfg.size, GFP_KERNEL); | 703 | |
| 686 | if (!child->bts_buffer) { | 704 | error = ptrace_bts_allocate_buffer(child, cfg.size); | 
| 687 | child->bts_size = 0; | 705 | if (error < 0) | 
| 688 | return -ENOMEM; | 706 | return error; | 
| 689 | } | ||
| 690 | } | 707 | } | 
| 691 | 708 | ||
| 692 | if (cfg.flags & PTRACE_BTS_O_TRACE) | 709 | if (cfg.flags & PTRACE_BTS_O_TRACE) | 
| @@ -701,10 +718,8 @@ static int ptrace_bts_config(struct task_struct *child, | |||
| 701 | if (IS_ERR(child->bts)) { | 718 | if (IS_ERR(child->bts)) { | 
| 702 | int error = PTR_ERR(child->bts); | 719 | int error = PTR_ERR(child->bts); | 
| 703 | 720 | ||
| 704 | kfree(child->bts_buffer); | 721 | ptrace_bts_free_buffer(child); | 
| 705 | child->bts = NULL; | 722 | child->bts = NULL; | 
| 706 | child->bts_buffer = NULL; | ||
| 707 | child->bts_size = 0; | ||
| 708 | 723 | ||
| 709 | return error; | 724 | return error; | 
| 710 | } | 725 | } | 
| @@ -769,8 +784,55 @@ static int ptrace_bts_size(struct task_struct *child) | |||
| 769 | 784 | ||
| 770 | return (trace->ds.top - trace->ds.begin) / trace->ds.size; | 785 | return (trace->ds.top - trace->ds.begin) / trace->ds.size; | 
| 771 | } | 786 | } | 
| 787 | |||
| 788 | static void ptrace_bts_fork(struct task_struct *tsk) | ||
| 789 | { | ||
| 790 | tsk->bts = NULL; | ||
| 791 | tsk->bts_buffer = NULL; | ||
| 792 | tsk->bts_size = 0; | ||
| 793 | tsk->thread.bts_ovfl_signal = 0; | ||
| 794 | } | ||
| 795 | |||
| 796 | static void ptrace_bts_untrace(struct task_struct *child) | ||
| 797 | { | ||
| 798 | if (unlikely(child->bts)) { | ||
| 799 | ds_release_bts(child->bts); | ||
| 800 | child->bts = NULL; | ||
| 801 | |||
| 802 | /* We cannot update total_vm and locked_vm since | ||
| 803 | child's mm is already gone. But we can reclaim the | ||
| 804 | memory. */ | ||
| 805 | kfree(child->bts_buffer); | ||
| 806 | child->bts_buffer = NULL; | ||
| 807 | child->bts_size = 0; | ||
| 808 | } | ||
| 809 | } | ||
| 810 | |||
| 811 | static void ptrace_bts_detach(struct task_struct *child) | ||
| 812 | { | ||
| 813 | if (unlikely(child->bts)) { | ||
| 814 | ds_release_bts(child->bts); | ||
| 815 | child->bts = NULL; | ||
| 816 | |||
| 817 | ptrace_bts_free_buffer(child); | ||
| 818 | } | ||
| 819 | } | ||
| 820 | #else | ||
| 821 | static inline void ptrace_bts_fork(struct task_struct *tsk) {} | ||
| 822 | static inline void ptrace_bts_detach(struct task_struct *child) {} | ||
| 823 | static inline void ptrace_bts_untrace(struct task_struct *child) {} | ||
| 772 | #endif /* CONFIG_X86_PTRACE_BTS */ | 824 | #endif /* CONFIG_X86_PTRACE_BTS */ | 
| 773 | 825 | ||
| 826 | void x86_ptrace_fork(struct task_struct *child, unsigned long clone_flags) | ||
| 827 | { | ||
| 828 | ptrace_bts_fork(child); | ||
| 829 | } | ||
| 830 | |||
| 831 | void x86_ptrace_untrace(struct task_struct *child) | ||
| 832 | { | ||
| 833 | ptrace_bts_untrace(child); | ||
| 834 | } | ||
| 835 | |||
| 774 | /* | 836 | /* | 
| 775 | * Called by kernel/ptrace.c when detaching.. | 837 | * Called by kernel/ptrace.c when detaching.. | 
| 776 | * | 838 | * | 
| @@ -782,16 +844,7 @@ void ptrace_disable(struct task_struct *child) | |||
| 782 | #ifdef TIF_SYSCALL_EMU | 844 | #ifdef TIF_SYSCALL_EMU | 
| 783 | clear_tsk_thread_flag(child, TIF_SYSCALL_EMU); | 845 | clear_tsk_thread_flag(child, TIF_SYSCALL_EMU); | 
| 784 | #endif | 846 | #endif | 
| 785 | #ifdef CONFIG_X86_PTRACE_BTS | 847 | ptrace_bts_detach(child); | 
| 786 | if (child->bts) { | ||
| 787 | ds_release_bts(child->bts); | ||
| 788 | child->bts = NULL; | ||
| 789 | |||
| 790 | kfree(child->bts_buffer); | ||
| 791 | child->bts_buffer = NULL; | ||
| 792 | child->bts_size = 0; | ||
| 793 | } | ||
| 794 | #endif /* CONFIG_X86_PTRACE_BTS */ | ||
| 795 | } | 848 | } | 
| 796 | 849 | ||
| 797 | #if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION | 850 | #if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION | 
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index f71f96fc9e62..f6174d229024 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c  | |||
| @@ -287,7 +287,7 @@ static int __cpuinitdata unsafe_smp; | |||
| 287 | /* | 287 | /* | 
| 288 | * Activate a secondary processor. | 288 | * Activate a secondary processor. | 
| 289 | */ | 289 | */ | 
| 290 | static void __cpuinit start_secondary(void *unused) | 290 | notrace static void __cpuinit start_secondary(void *unused) | 
| 291 | { | 291 | { | 
| 292 | /* | 292 | /* | 
| 293 | * Don't put *anything* before cpu_init(), SMP booting is too | 293 | * Don't put *anything* before cpu_init(), SMP booting is too | 
