]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/x86/kernel/ds.c
x86, bts: fix unlock problem in ds.c
[linux-2.6-omap-h63xx.git] / arch / x86 / kernel / ds.c
1 /*
2  * Debug Store support
3  *
4  * This provides a low-level interface to the hardware's Debug Store
5  * feature that is used for branch trace store (BTS) and
6  * precise-event based sampling (PEBS).
7  *
8  * It manages:
9  * - per-thread and per-cpu allocation of BTS and PEBS
10  * - buffer memory allocation (optional)
11  * - buffer overflow handling
12  * - buffer access
13  *
14  * It assumes:
15  * - get_task_struct on all parameter tasks
16  * - current is allowed to trace parameter tasks
17  *
18  *
19  * Copyright (C) 2007-2008 Intel Corporation.
20  * Markus Metzger <markus.t.metzger@intel.com>, 2007-2008
21  */
22
23
24 #ifdef CONFIG_X86_DS
25
26 #include <asm/ds.h>
27
28 #include <linux/errno.h>
29 #include <linux/string.h>
30 #include <linux/slab.h>
31 #include <linux/sched.h>
32 #include <linux/mm.h>
33
34
35 /*
36  * The configuration for a particular DS hardware implementation.
37  */
38 struct ds_configuration {
39         /* the size of the DS structure in bytes */
40         unsigned char  sizeof_ds;
41         /* the size of one pointer-typed field in the DS structure in bytes;
42            this covers the first 8 fields related to buffer management. */
43         unsigned char  sizeof_field;
44         /* the size of a BTS/PEBS record in bytes */
45         unsigned char  sizeof_rec[2];
46 };
47 static struct ds_configuration ds_cfg;
48
49
50 /*
51  * Debug Store (DS) save area configuration (see Intel64 and IA32
52  * Architectures Software Developer's Manual, section 18.5)
53  *
54  * The DS configuration consists of the following fields; different
55  * architetures vary in the size of those fields.
56  * - double-word aligned base linear address of the BTS buffer
57  * - write pointer into the BTS buffer
58  * - end linear address of the BTS buffer (one byte beyond the end of
59  *   the buffer)
60  * - interrupt pointer into BTS buffer
61  *   (interrupt occurs when write pointer passes interrupt pointer)
62  * - double-word aligned base linear address of the PEBS buffer
63  * - write pointer into the PEBS buffer
64  * - end linear address of the PEBS buffer (one byte beyond the end of
65  *   the buffer)
66  * - interrupt pointer into PEBS buffer
67  *   (interrupt occurs when write pointer passes interrupt pointer)
68  * - value to which counter is reset following counter overflow
69  *
70  * Later architectures use 64bit pointers throughout, whereas earlier
71  * architectures use 32bit pointers in 32bit mode.
72  *
73  *
74  * We compute the base address for the first 8 fields based on:
75  * - the field size stored in the DS configuration
76  * - the relative field position
77  * - an offset giving the start of the respective region
78  *
79  * This offset is further used to index various arrays holding
80  * information for BTS and PEBS at the respective index.
81  *
82  * On later 32bit processors, we only access the lower 32bit of the
83  * 64bit pointer fields. The upper halves will be zeroed out.
84  */
85
86 enum ds_field {
87         ds_buffer_base = 0,
88         ds_index,
89         ds_absolute_maximum,
90         ds_interrupt_threshold,
91 };
92
93 enum ds_qualifier {
94         ds_bts  = 0,
95         ds_pebs
96 };
97
98 static inline unsigned long ds_get(const unsigned char *base,
99                                    enum ds_qualifier qual, enum ds_field field)
100 {
101         base += (ds_cfg.sizeof_field * (field + (4 * qual)));
102         return *(unsigned long *)base;
103 }
104
105 static inline void ds_set(unsigned char *base, enum ds_qualifier qual,
106                           enum ds_field field, unsigned long value)
107 {
108         base += (ds_cfg.sizeof_field * (field + (4 * qual)));
109         (*(unsigned long *)base) = value;
110 }
111
112
113 /*
114  * Locking is done only for allocating BTS or PEBS resources and for
115  * guarding context and buffer memory allocation.
116  *
117  * Most functions require the current task to own the ds context part
118  * they are going to access. All the locking is done when validating
119  * access to the context.
120  */
121 static spinlock_t ds_lock = __SPIN_LOCK_UNLOCKED(ds_lock);
122
123 /*
124  * Validate that the current task is allowed to access the BTS/PEBS
125  * buffer of the parameter task.
126  *
127  * Returns 0, if access is granted; -Eerrno, otherwise.
128  */
129 static inline int ds_validate_access(struct ds_context *context,
130                                      enum ds_qualifier qual)
131 {
132         if (!context)
133                 return -EPERM;
134
135         if (context->owner[qual] == current)
136                 return 0;
137
138         return -EPERM;
139 }
140
141
142 /*
143  * We either support (system-wide) per-cpu or per-thread allocation.
144  * We distinguish the two based on the task_struct pointer, where a
145  * NULL pointer indicates per-cpu allocation for the current cpu.
146  *
147  * Allocations are use-counted. As soon as resources are allocated,
148  * further allocations must be of the same type (per-cpu or
149  * per-thread). We model this by counting allocations (i.e. the number
150  * of tracers of a certain type) for one type negatively:
151  *   =0  no tracers
152  *   >0  number of per-thread tracers
153  *   <0  number of per-cpu tracers
154  *
155  * The below functions to get and put tracers and to check the
156  * allocation type require the ds_lock to be held by the caller.
157  *
158  * Tracers essentially gives the number of ds contexts for a certain
159  * type of allocation.
160  */
161 static long tracers;
162
163 static inline void get_tracer(struct task_struct *task)
164 {
165         tracers += (task ? 1 : -1);
166 }
167
168 static inline void put_tracer(struct task_struct *task)
169 {
170         tracers -= (task ? 1 : -1);
171 }
172
173 static inline int check_tracer(struct task_struct *task)
174 {
175         return (task ? (tracers >= 0) : (tracers <= 0));
176 }
177
178
179 /*
180  * The DS context is either attached to a thread or to a cpu:
181  * - in the former case, the thread_struct contains a pointer to the
182  *   attached context.
183  * - in the latter case, we use a static array of per-cpu context
184  *   pointers.
185  *
186  * Contexts are use-counted. They are allocated on first access and
187  * deallocated when the last user puts the context.
188  *
189  * We distinguish between an allocating and a non-allocating get of a
190  * context:
191  * - the allocating get is used for requesting BTS/PEBS resources. It
192  *   requires the caller to hold the global ds_lock.
193  * - the non-allocating get is used for all other cases. A
194  *   non-existing context indicates an error. It acquires and releases
195  *   the ds_lock itself for obtaining the context.
196  *
197  * A context and its DS configuration are allocated and deallocated
198  * together. A context always has a DS configuration of the
199  * appropriate size.
200  */
201 static DEFINE_PER_CPU(struct ds_context *, system_context);
202
203 #define this_system_context per_cpu(system_context, smp_processor_id())
204
205 /*
206  * Returns the pointer to the parameter task's context or to the
207  * system-wide context, if task is NULL.
208  *
209  * Increases the use count of the returned context, if not NULL.
210  */
211 static inline struct ds_context *ds_get_context(struct task_struct *task)
212 {
213         struct ds_context *context;
214
215         spin_lock(&ds_lock);
216
217         context = (task ? task->thread.ds_ctx : this_system_context);
218         if (context)
219                 context->count++;
220
221         spin_unlock(&ds_lock);
222
223         return context;
224 }
225
226 /*
227  * Same as ds_get_context, but allocates the context and it's DS
228  * structure, if necessary; returns NULL; if out of memory.
229  *
230  * pre: requires ds_lock to be held
231  */
232 static inline struct ds_context *ds_alloc_context(struct task_struct *task)
233 {
234         struct ds_context **p_context =
235                 (task ? &task->thread.ds_ctx : &this_system_context);
236         struct ds_context *context = *p_context;
237
238         if (!context) {
239                 context = kzalloc(sizeof(*context), GFP_KERNEL);
240
241                 if (!context)
242                         return NULL;
243
244                 context->ds = kzalloc(ds_cfg.sizeof_ds, GFP_KERNEL);
245                 if (!context->ds) {
246                         kfree(context);
247                         return NULL;
248                 }
249
250                 *p_context = context;
251
252                 context->this = p_context;
253                 context->task = task;
254
255                 if (task)
256                         set_tsk_thread_flag(task, TIF_DS_AREA_MSR);
257
258                 if (!task || (task == current))
259                         wrmsr(MSR_IA32_DS_AREA, (unsigned long)context->ds, 0);
260
261                 get_tracer(task);
262         }
263
264         context->count++;
265
266         return context;
267 }
268
269 /*
270  * Decreases the use count of the parameter context, if not NULL.
271  * Deallocates the context, if the use count reaches zero.
272  */
273 static inline void ds_put_context(struct ds_context *context)
274 {
275         if (!context)
276                 return;
277
278         spin_lock(&ds_lock);
279
280         if (--context->count)
281                 goto out;
282
283         *(context->this) = NULL;
284
285         if (context->task)
286                 clear_tsk_thread_flag(context->task, TIF_DS_AREA_MSR);
287
288         if (!context->task || (context->task == current))
289                 wrmsrl(MSR_IA32_DS_AREA, 0);
290
291         put_tracer(context->task);
292
293         /* free any leftover buffers from tracers that did not
294          * deallocate them properly. */
295         kfree(context->buffer[ds_bts]);
296         kfree(context->buffer[ds_pebs]);
297         kfree(context->ds);
298         kfree(context);
299  out:
300         spin_unlock(&ds_lock);
301 }
302
303
304 /*
305  * Handle a buffer overflow
306  *
307  * task: the task whose buffers are overflowing;
308  *       NULL for a buffer overflow on the current cpu
309  * context: the ds context
310  * qual: the buffer type
311  */
312 static void ds_overflow(struct task_struct *task, struct ds_context *context,
313                         enum ds_qualifier qual)
314 {
315         if (!context)
316                 return;
317
318         if (context->callback[qual])
319                 (*context->callback[qual])(task);
320
321         /* todo: do some more overflow handling */
322 }
323
324
325 /*
326  * Allocate a non-pageable buffer of the parameter size.
327  * Checks the memory and the locked memory rlimit.
328  *
329  * Returns the buffer, if successful;
330  *         NULL, if out of memory or rlimit exceeded.
331  *
332  * size: the requested buffer size in bytes
333  * pages (out): if not NULL, contains the number of pages reserved
334  */
335 static inline void *ds_allocate_buffer(size_t size, unsigned int *pages)
336 {
337         unsigned long rlim, vm, pgsz;
338         void *buffer;
339
340         pgsz = PAGE_ALIGN(size) >> PAGE_SHIFT;
341
342         rlim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
343         vm   = current->mm->total_vm  + pgsz;
344         if (rlim < vm)
345                 return NULL;
346
347         rlim = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
348         vm   = current->mm->locked_vm  + pgsz;
349         if (rlim < vm)
350                 return NULL;
351
352         buffer = kzalloc(size, GFP_KERNEL);
353         if (!buffer)
354                 return NULL;
355
356         current->mm->total_vm  += pgsz;
357         current->mm->locked_vm += pgsz;
358
359         if (pages)
360                 *pages = pgsz;
361
362         return buffer;
363 }
364
365 static int ds_request(struct task_struct *task, void *base, size_t size,
366                       ds_ovfl_callback_t ovfl, enum ds_qualifier qual)
367 {
368         struct ds_context *context;
369         unsigned long buffer, adj;
370         const unsigned long alignment = (1 << 3);
371         int error = 0;
372
373         if (!ds_cfg.sizeof_ds)
374                 return -EOPNOTSUPP;
375
376         /* we require some space to do alignment adjustments below */
377         if (size < (alignment + ds_cfg.sizeof_rec[qual]))
378                 return -EINVAL;
379
380         /* buffer overflow notification is not yet implemented */
381         if (ovfl)
382                 return -EOPNOTSUPP;
383
384
385         spin_lock(&ds_lock);
386
387         error = -EPERM;
388         if (!check_tracer(task))
389                 goto out_unlock;
390
391         error = -ENOMEM;
392         context = ds_alloc_context(task);
393         if (!context)
394                 goto out_unlock;
395
396         error = -EALREADY;
397         if (context->owner[qual] == current)
398                 goto out_unlock;
399         error = -EPERM;
400         if (context->owner[qual] != NULL)
401                 goto out_unlock;
402         context->owner[qual] = current;
403
404         spin_unlock(&ds_lock);
405
406
407         error = -ENOMEM;
408         if (!base) {
409                 base = ds_allocate_buffer(size, &context->pages[qual]);
410                 if (!base)
411                         goto out_release;
412
413                 context->buffer[qual]   = base;
414         }
415         error = 0;
416
417         context->callback[qual] = ovfl;
418
419         /* adjust the buffer address and size to meet alignment
420          * constraints:
421          * - buffer is double-word aligned
422          * - size is multiple of record size
423          *
424          * We checked the size at the very beginning; we have enough
425          * space to do the adjustment.
426          */
427         buffer = (unsigned long)base;
428
429         adj = ALIGN(buffer, alignment) - buffer;
430         buffer += adj;
431         size   -= adj;
432
433         size /= ds_cfg.sizeof_rec[qual];
434         size *= ds_cfg.sizeof_rec[qual];
435
436         ds_set(context->ds, qual, ds_buffer_base, buffer);
437         ds_set(context->ds, qual, ds_index, buffer);
438         ds_set(context->ds, qual, ds_absolute_maximum, buffer + size);
439
440         if (ovfl) {
441                 /* todo: select a suitable interrupt threshold */
442         } else
443                 ds_set(context->ds, qual,
444                        ds_interrupt_threshold, buffer + size + 1);
445
446         /* we keep the context until ds_release */
447         return error;
448
449  out_release:
450         context->owner[qual] = NULL;
451         ds_put_context(context);
452         return error;
453
454  out_unlock:
455         spin_unlock(&ds_lock);
456         ds_put_context(context);
457         return error;
458 }
459
460 int ds_request_bts(struct task_struct *task, void *base, size_t size,
461                    ds_ovfl_callback_t ovfl)
462 {
463         return ds_request(task, base, size, ovfl, ds_bts);
464 }
465
466 int ds_request_pebs(struct task_struct *task, void *base, size_t size,
467                     ds_ovfl_callback_t ovfl)
468 {
469         return ds_request(task, base, size, ovfl, ds_pebs);
470 }
471
472 static int ds_release(struct task_struct *task, enum ds_qualifier qual)
473 {
474         struct ds_context *context;
475         int error;
476
477         context = ds_get_context(task);
478         error = ds_validate_access(context, qual);
479         if (error < 0)
480                 goto out;
481
482         kfree(context->buffer[qual]);
483         context->buffer[qual] = NULL;
484
485         current->mm->total_vm  -= context->pages[qual];
486         current->mm->locked_vm -= context->pages[qual];
487         context->pages[qual] = 0;
488         context->owner[qual] = NULL;
489
490         /*
491          * we put the context twice:
492          *   once for the ds_get_context
493          *   once for the corresponding ds_request
494          */
495         ds_put_context(context);
496  out:
497         ds_put_context(context);
498         return error;
499 }
500
501 int ds_release_bts(struct task_struct *task)
502 {
503         return ds_release(task, ds_bts);
504 }
505
506 int ds_release_pebs(struct task_struct *task)
507 {
508         return ds_release(task, ds_pebs);
509 }
510
511 static int ds_get_index(struct task_struct *task, size_t *pos,
512                         enum ds_qualifier qual)
513 {
514         struct ds_context *context;
515         unsigned long base, index;
516         int error;
517
518         context = ds_get_context(task);
519         error = ds_validate_access(context, qual);
520         if (error < 0)
521                 goto out;
522
523         base  = ds_get(context->ds, qual, ds_buffer_base);
524         index = ds_get(context->ds, qual, ds_index);
525
526         error = ((index - base) / ds_cfg.sizeof_rec[qual]);
527         if (pos)
528                 *pos = error;
529  out:
530         ds_put_context(context);
531         return error;
532 }
533
534 int ds_get_bts_index(struct task_struct *task, size_t *pos)
535 {
536         return ds_get_index(task, pos, ds_bts);
537 }
538
539 int ds_get_pebs_index(struct task_struct *task, size_t *pos)
540 {
541         return ds_get_index(task, pos, ds_pebs);
542 }
543
544 static int ds_get_end(struct task_struct *task, size_t *pos,
545                       enum ds_qualifier qual)
546 {
547         struct ds_context *context;
548         unsigned long base, end;
549         int error;
550
551         context = ds_get_context(task);
552         error = ds_validate_access(context, qual);
553         if (error < 0)
554                 goto out;
555
556         base = ds_get(context->ds, qual, ds_buffer_base);
557         end  = ds_get(context->ds, qual, ds_absolute_maximum);
558
559         error = ((end - base) / ds_cfg.sizeof_rec[qual]);
560         if (pos)
561                 *pos = error;
562  out:
563         ds_put_context(context);
564         return error;
565 }
566
567 int ds_get_bts_end(struct task_struct *task, size_t *pos)
568 {
569         return ds_get_end(task, pos, ds_bts);
570 }
571
572 int ds_get_pebs_end(struct task_struct *task, size_t *pos)
573 {
574         return ds_get_end(task, pos, ds_pebs);
575 }
576
577 static int ds_access(struct task_struct *task, size_t index,
578                      const void **record, enum ds_qualifier qual)
579 {
580         struct ds_context *context;
581         unsigned long base, idx;
582         int error;
583
584         if (!record)
585                 return -EINVAL;
586
587         context = ds_get_context(task);
588         error = ds_validate_access(context, qual);
589         if (error < 0)
590                 goto out;
591
592         base = ds_get(context->ds, qual, ds_buffer_base);
593         idx = base + (index * ds_cfg.sizeof_rec[qual]);
594
595         error = -EINVAL;
596         if (idx > ds_get(context->ds, qual, ds_absolute_maximum))
597                 goto out;
598
599         *record = (const void *)idx;
600         error = ds_cfg.sizeof_rec[qual];
601  out:
602         ds_put_context(context);
603         return error;
604 }
605
606 int ds_access_bts(struct task_struct *task, size_t index, const void **record)
607 {
608         return ds_access(task, index, record, ds_bts);
609 }
610
611 int ds_access_pebs(struct task_struct *task, size_t index, const void **record)
612 {
613         return ds_access(task, index, record, ds_pebs);
614 }
615
616 static int ds_write(struct task_struct *task, const void *record, size_t size,
617                     enum ds_qualifier qual, int force)
618 {
619         struct ds_context *context;
620         int error;
621
622         if (!record)
623                 return -EINVAL;
624
625         error = -EPERM;
626         context = ds_get_context(task);
627         if (!context)
628                 goto out;
629
630         if (!force) {
631                 error = ds_validate_access(context, qual);
632                 if (error < 0)
633                         goto out;
634         }
635
636         error = 0;
637         while (size) {
638                 unsigned long base, index, end, write_end, int_th;
639                 unsigned long write_size, adj_write_size;
640
641                 /*
642                  * write as much as possible without producing an
643                  * overflow interrupt.
644                  *
645                  * interrupt_threshold must either be
646                  * - bigger than absolute_maximum or
647                  * - point to a record between buffer_base and absolute_maximum
648                  *
649                  * index points to a valid record.
650                  */
651                 base   = ds_get(context->ds, qual, ds_buffer_base);
652                 index  = ds_get(context->ds, qual, ds_index);
653                 end    = ds_get(context->ds, qual, ds_absolute_maximum);
654                 int_th = ds_get(context->ds, qual, ds_interrupt_threshold);
655
656                 write_end = min(end, int_th);
657
658                 /* if we are already beyond the interrupt threshold,
659                  * we fill the entire buffer */
660                 if (write_end <= index)
661                         write_end = end;
662
663                 if (write_end <= index)
664                         goto out;
665
666                 write_size = min((unsigned long) size, write_end - index);
667                 memcpy((void *)index, record, write_size);
668
669                 record = (const char *)record + write_size;
670                 size  -= write_size;
671                 error += write_size;
672
673                 adj_write_size = write_size / ds_cfg.sizeof_rec[qual];
674                 adj_write_size *= ds_cfg.sizeof_rec[qual];
675
676                 /* zero out trailing bytes */
677                 memset((char *)index + write_size, 0,
678                        adj_write_size - write_size);
679                 index += adj_write_size;
680
681                 if (index >= end)
682                         index = base;
683                 ds_set(context->ds, qual, ds_index, index);
684
685                 if (index >= int_th)
686                         ds_overflow(task, context, qual);
687         }
688
689  out:
690         ds_put_context(context);
691         return error;
692 }
693
694 int ds_write_bts(struct task_struct *task, const void *record, size_t size)
695 {
696         return ds_write(task, record, size, ds_bts, /* force = */ 0);
697 }
698
699 int ds_write_pebs(struct task_struct *task, const void *record, size_t size)
700 {
701         return ds_write(task, record, size, ds_pebs, /* force = */ 0);
702 }
703
704 int ds_unchecked_write_bts(struct task_struct *task,
705                            const void *record, size_t size)
706 {
707         return ds_write(task, record, size, ds_bts, /* force = */ 1);
708 }
709
710 int ds_unchecked_write_pebs(struct task_struct *task,
711                             const void *record, size_t size)
712 {
713         return ds_write(task, record, size, ds_pebs, /* force = */ 1);
714 }
715
716 static int ds_reset_or_clear(struct task_struct *task,
717                              enum ds_qualifier qual, int clear)
718 {
719         struct ds_context *context;
720         unsigned long base, end;
721         int error;
722
723         context = ds_get_context(task);
724         error = ds_validate_access(context, qual);
725         if (error < 0)
726                 goto out;
727
728         base = ds_get(context->ds, qual, ds_buffer_base);
729         end  = ds_get(context->ds, qual, ds_absolute_maximum);
730
731         if (clear)
732                 memset((void *)base, 0, end - base);
733
734         ds_set(context->ds, qual, ds_index, base);
735
736         error = 0;
737  out:
738         ds_put_context(context);
739         return error;
740 }
741
742 int ds_reset_bts(struct task_struct *task)
743 {
744         return ds_reset_or_clear(task, ds_bts, /* clear = */ 0);
745 }
746
747 int ds_reset_pebs(struct task_struct *task)
748 {
749         return ds_reset_or_clear(task, ds_pebs, /* clear = */ 0);
750 }
751
752 int ds_clear_bts(struct task_struct *task)
753 {
754         return ds_reset_or_clear(task, ds_bts, /* clear = */ 1);
755 }
756
757 int ds_clear_pebs(struct task_struct *task)
758 {
759         return ds_reset_or_clear(task, ds_pebs, /* clear = */ 1);
760 }
761
762 int ds_get_pebs_reset(struct task_struct *task, u64 *value)
763 {
764         struct ds_context *context;
765         int error;
766
767         if (!value)
768                 return -EINVAL;
769
770         context = ds_get_context(task);
771         error = ds_validate_access(context, ds_pebs);
772         if (error < 0)
773                 goto out;
774
775         *value = *(u64 *)(context->ds + (ds_cfg.sizeof_field * 8));
776
777         error = 0;
778  out:
779         ds_put_context(context);
780         return error;
781 }
782
783 int ds_set_pebs_reset(struct task_struct *task, u64 value)
784 {
785         struct ds_context *context;
786         int error;
787
788         context = ds_get_context(task);
789         error = ds_validate_access(context, ds_pebs);
790         if (error < 0)
791                 goto out;
792
793         *(u64 *)(context->ds + (ds_cfg.sizeof_field * 8)) = value;
794
795         error = 0;
796  out:
797         ds_put_context(context);
798         return error;
799 }
800
801 static const struct ds_configuration ds_cfg_var = {
802         .sizeof_ds    = sizeof(long) * 12,
803         .sizeof_field = sizeof(long),
804         .sizeof_rec[ds_bts]   = sizeof(long) * 3,
805         .sizeof_rec[ds_pebs]  = sizeof(long) * 10
806 };
807 static const struct ds_configuration ds_cfg_64 = {
808         .sizeof_ds    = 8 * 12,
809         .sizeof_field = 8,
810         .sizeof_rec[ds_bts]   = 8 * 3,
811         .sizeof_rec[ds_pebs]  = 8 * 10
812 };
813
814 static inline void
815 ds_configure(const struct ds_configuration *cfg)
816 {
817         ds_cfg = *cfg;
818 }
819
820 void __cpuinit ds_init_intel(struct cpuinfo_x86 *c)
821 {
822         switch (c->x86) {
823         case 0x6:
824                 switch (c->x86_model) {
825                 case 0xD:
826                 case 0xE: /* Pentium M */
827                         ds_configure(&ds_cfg_var);
828                         break;
829                 case 0xF: /* Core2 */
830                 case 0x1C: /* Atom */
831                         ds_configure(&ds_cfg_64);
832                         break;
833                 default:
834                         /* sorry, don't know about them */
835                         break;
836                 }
837                 break;
838         case 0xF:
839                 switch (c->x86_model) {
840                 case 0x0:
841                 case 0x1:
842                 case 0x2: /* Netburst */
843                         ds_configure(&ds_cfg_var);
844                         break;
845                 default:
846                         /* sorry, don't know about them */
847                         break;
848                 }
849                 break;
850         default:
851                 /* sorry, don't know about them */
852                 break;
853         }
854 }
855
856 void ds_free(struct ds_context *context)
857 {
858         /* This is called when the task owning the parameter context
859          * is dying. There should not be any user of that context left
860          * to disturb us, anymore. */
861         unsigned long leftovers = context->count;
862         while (leftovers--)
863                 ds_put_context(context);
864 }
865 #endif /* CONFIG_X86_DS */