]> err.no Git - linux-2.6/blob - arch/x86/mm/pat.c
320d644a8107fa56e829248cb3be84b7167985bf
[linux-2.6] / arch / x86 / mm / pat.c
1 /*
2  * Handle caching attributes in page tables (PAT)
3  *
4  * Authors: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
5  *          Suresh B Siddha <suresh.b.siddha@intel.com>
6  *
7  * Loosely based on earlier PAT patchset from Eric Biederman and Andi Kleen.
8  */
9
10 #include <linux/mm.h>
11 #include <linux/kernel.h>
12 #include <linux/gfp.h>
13 #include <linux/fs.h>
14 #include <linux/bootmem.h>
15
16 #include <asm/msr.h>
17 #include <asm/tlbflush.h>
18 #include <asm/processor.h>
19 #include <asm/page.h>
20 #include <asm/pgtable.h>
21 #include <asm/pat.h>
22 #include <asm/e820.h>
23 #include <asm/cacheflush.h>
24 #include <asm/fcntl.h>
25 #include <asm/mtrr.h>
26 #include <asm/io.h>
27
28 #ifdef CONFIG_X86_PAT
29 int __read_mostly pat_wc_enabled = 1;
30
31 void __cpuinit pat_disable(char *reason)
32 {
33         pat_wc_enabled = 0;
34         printk(KERN_INFO "%s\n", reason);
35 }
36
37 static int nopat(char *str)
38 {
39         pat_disable("PAT support disabled.");
40         return 0;
41 }
42 early_param("nopat", nopat);
43 #endif
44
45
46 static int debug_enable;
47 static int __init pat_debug_setup(char *str)
48 {
49         debug_enable = 1;
50         return 0;
51 }
52 __setup("debugpat", pat_debug_setup);
53
54 #define dprintk(fmt, arg...) \
55         do { if (debug_enable) printk(KERN_INFO fmt, ##arg); } while (0)
56
57
58 static u64 __read_mostly boot_pat_state;
59
60 enum {
61         PAT_UC = 0,             /* uncached */
62         PAT_WC = 1,             /* Write combining */
63         PAT_WT = 4,             /* Write Through */
64         PAT_WP = 5,             /* Write Protected */
65         PAT_WB = 6,             /* Write Back (default) */
66         PAT_UC_MINUS = 7,       /* UC, but can be overriden by MTRR */
67 };
68
69 #define PAT(x,y)        ((u64)PAT_ ## y << ((x)*8))
70
71 void pat_init(void)
72 {
73         u64 pat;
74
75         if (!pat_wc_enabled)
76                 return;
77
78         /* Paranoia check. */
79         if (!cpu_has_pat) {
80                 printk(KERN_ERR "PAT enabled, but CPU feature cleared\n");
81                 /*
82                  * Panic if this happens on the secondary CPU, and we
83                  * switched to PAT on the boot CPU. We have no way to
84                  * undo PAT.
85                 */
86                 BUG_ON(boot_pat_state);
87         }
88
89         /* Set PWT to Write-Combining. All other bits stay the same */
90         /*
91          * PTE encoding used in Linux:
92          *      PAT
93          *      |PCD
94          *      ||PWT
95          *      |||
96          *      000 WB          _PAGE_CACHE_WB
97          *      001 WC          _PAGE_CACHE_WC
98          *      010 UC-         _PAGE_CACHE_UC_MINUS
99          *      011 UC          _PAGE_CACHE_UC
100          * PAT bit unused
101          */
102         pat = PAT(0,WB) | PAT(1,WC) | PAT(2,UC_MINUS) | PAT(3,UC) |
103               PAT(4,WB) | PAT(5,WC) | PAT(6,UC_MINUS) | PAT(7,UC);
104
105         /* Boot CPU check */
106         if (!boot_pat_state)
107                 rdmsrl(MSR_IA32_CR_PAT, boot_pat_state);
108
109         wrmsrl(MSR_IA32_CR_PAT, pat);
110         printk(KERN_INFO "x86 PAT enabled: cpu %d, old 0x%Lx, new 0x%Lx\n",
111                smp_processor_id(), boot_pat_state, pat);
112 }
113
114 #undef PAT
115
116 static char *cattr_name(unsigned long flags)
117 {
118         switch (flags & _PAGE_CACHE_MASK) {
119                 case _PAGE_CACHE_UC:            return "uncached";
120                 case _PAGE_CACHE_UC_MINUS:      return "uncached-minus";
121                 case _PAGE_CACHE_WB:            return "write-back";
122                 case _PAGE_CACHE_WC:            return "write-combining";
123                 default:                        return "broken";
124         }
125 }
126
127 /*
128  * The global memtype list keeps track of memory type for specific
129  * physical memory areas. Conflicting memory types in different
130  * mappings can cause CPU cache corruption. To avoid this we keep track.
131  *
132  * The list is sorted based on starting address and can contain multiple
133  * entries for each address (this allows reference counting for overlapping
134  * areas). All the aliases have the same cache attributes of course.
135  * Zero attributes are represented as holes.
136  *
137  * Currently the data structure is a list because the number of mappings
138  * are expected to be relatively small. If this should be a problem
139  * it could be changed to a rbtree or similar.
140  *
141  * memtype_lock protects the whole list.
142  */
143
144 struct memtype {
145         u64 start;
146         u64 end;
147         unsigned long type;
148         struct list_head nd;
149 };
150
151 static LIST_HEAD(memtype_list);
152 static DEFINE_SPINLOCK(memtype_lock);   /* protects memtype list */
153
154 /*
155  * Does intersection of PAT memory type and MTRR memory type and returns
156  * the resulting memory type as PAT understands it.
157  * (Type in pat and mtrr will not have same value)
158  * The intersection is based on "Effective Memory Type" tables in IA-32
159  * SDM vol 3a
160  */
161 static int pat_x_mtrr_type(u64 start, u64 end, unsigned long prot,
162                                 unsigned long *ret_prot)
163 {
164         unsigned long pat_type;
165         u8 mtrr_type;
166
167         pat_type = prot & _PAGE_CACHE_MASK;
168         prot &= (~_PAGE_CACHE_MASK);
169
170         /*
171          * We return the PAT request directly for types where PAT takes
172          * precedence with respect to MTRR and for UC_MINUS.
173          * Consistency checks with other PAT requests is done later
174          * while going through memtype list.
175          */
176         if (pat_type == _PAGE_CACHE_WC) {
177                 *ret_prot = prot | _PAGE_CACHE_WC;
178                 return 0;
179         } else if (pat_type == _PAGE_CACHE_UC_MINUS) {
180                 *ret_prot = prot | _PAGE_CACHE_UC_MINUS;
181                 return 0;
182         } else if (pat_type == _PAGE_CACHE_UC) {
183                 *ret_prot = prot | _PAGE_CACHE_UC;
184                 return 0;
185         }
186
187         /*
188          * Look for MTRR hint to get the effective type in case where PAT
189          * request is for WB.
190          */
191         mtrr_type = mtrr_type_lookup(start, end);
192
193         if (mtrr_type == MTRR_TYPE_UNCACHABLE) {
194                 *ret_prot = prot | _PAGE_CACHE_UC;
195         } else if (mtrr_type == MTRR_TYPE_WRCOMB) {
196                 *ret_prot = prot | _PAGE_CACHE_WC;
197         } else {
198                 *ret_prot = prot | _PAGE_CACHE_WB;
199         }
200
201         return 0;
202 }
203
204 /*
205  * req_type typically has one of the:
206  * - _PAGE_CACHE_WB
207  * - _PAGE_CACHE_WC
208  * - _PAGE_CACHE_UC_MINUS
209  * - _PAGE_CACHE_UC
210  *
211  * req_type will have a special case value '-1', when requester want to inherit
212  * the memory type from mtrr (if WB), existing PAT, defaulting to UC_MINUS.
213  *
214  * If ret_type is NULL, function will return an error if it cannot reserve the
215  * region with req_type. If ret_type is non-null, function will return
216  * available type in ret_type in case of no error. In case of any error
217  * it will return a negative return value.
218  */
219 int reserve_memtype(u64 start, u64 end, unsigned long req_type,
220                         unsigned long *ret_type)
221 {
222         struct memtype *new_entry = NULL;
223         struct memtype *parse;
224         unsigned long actual_type;
225         int err = 0;
226
227         /* Only track when pat_wc_enabled */
228         if (!pat_wc_enabled) {
229                 /* This is identical to page table setting without PAT */
230                 if (ret_type) {
231                         if (req_type == -1) {
232                                 *ret_type = _PAGE_CACHE_WB;
233                         } else {
234                                 *ret_type = req_type;
235                         }
236                 }
237                 return 0;
238         }
239
240         /* Low ISA region is always mapped WB in page table. No need to track */
241         if (start >= ISA_START_ADDRESS && (end - 1) <= ISA_END_ADDRESS) {
242                 if (ret_type)
243                         *ret_type = _PAGE_CACHE_WB;
244
245                 return 0;
246         }
247
248         if (req_type == -1) {
249                 /*
250                  * Call mtrr_lookup to get the type hint. This is an
251                  * optimization for /dev/mem mmap'ers into WB memory (BIOS
252                  * tools and ACPI tools). Use WB request for WB memory and use
253                  * UC_MINUS otherwise.
254                  */
255                 u8 mtrr_type = mtrr_type_lookup(start, end);
256
257                 if (mtrr_type == MTRR_TYPE_WRBACK) {
258                         req_type = _PAGE_CACHE_WB;
259                         actual_type = _PAGE_CACHE_WB;
260                 } else {
261                         req_type = _PAGE_CACHE_UC_MINUS;
262                         actual_type = _PAGE_CACHE_UC_MINUS;
263                 }
264         } else {
265                 req_type &= _PAGE_CACHE_MASK;
266                 err = pat_x_mtrr_type(start, end, req_type, &actual_type);
267         }
268
269         if (err) {
270                 if (ret_type)
271                         *ret_type = actual_type;
272
273                 return -EINVAL;
274         }
275
276         new_entry  = kmalloc(sizeof(struct memtype), GFP_KERNEL);
277         if (!new_entry)
278                 return -ENOMEM;
279
280         new_entry->start = start;
281         new_entry->end = end;
282         new_entry->type = actual_type;
283
284         if (ret_type)
285                 *ret_type = actual_type;
286
287         spin_lock(&memtype_lock);
288
289         /* Search for existing mapping that overlaps the current range */
290         list_for_each_entry(parse, &memtype_list, nd) {
291                 struct memtype *saved_ptr;
292
293                 if (parse->start >= end) {
294                         dprintk("New Entry\n");
295                         list_add(&new_entry->nd, parse->nd.prev);
296                         new_entry = NULL;
297                         break;
298                 }
299
300                 if (start <= parse->start && end >= parse->start) {
301                         if (actual_type != parse->type && ret_type) {
302                                 actual_type = parse->type;
303                                 *ret_type = actual_type;
304                                 new_entry->type = actual_type;
305                         }
306
307                         if (actual_type != parse->type) {
308                                 printk(
309                 KERN_INFO "%s:%d conflicting memory types %Lx-%Lx %s<->%s\n",
310                                         current->comm, current->pid,
311                                         start, end,
312                                         cattr_name(actual_type),
313                                         cattr_name(parse->type));
314                                 err = -EBUSY;
315                                 break;
316                         }
317
318                         saved_ptr = parse;
319                         /*
320                          * Check to see whether the request overlaps more
321                          * than one entry in the list
322                          */
323                         list_for_each_entry_continue(parse, &memtype_list, nd) {
324                                 if (end <= parse->start) {
325                                         break;
326                                 }
327
328                                 if (actual_type != parse->type) {
329                                         printk(
330                 KERN_INFO "%s:%d conflicting memory types %Lx-%Lx %s<->%s\n",
331                                                 current->comm, current->pid,
332                                                 start, end,
333                                                 cattr_name(actual_type),
334                                                 cattr_name(parse->type));
335                                         err = -EBUSY;
336                                         break;
337                                 }
338                         }
339
340                         if (err) {
341                                 break;
342                         }
343
344                         dprintk("Overlap at 0x%Lx-0x%Lx\n",
345                                saved_ptr->start, saved_ptr->end);
346                         /* No conflict. Go ahead and add this new entry */
347                         list_add(&new_entry->nd, saved_ptr->nd.prev);
348                         new_entry = NULL;
349                         break;
350                 }
351
352                 if (start < parse->end) {
353                         if (actual_type != parse->type && ret_type) {
354                                 actual_type = parse->type;
355                                 *ret_type = actual_type;
356                                 new_entry->type = actual_type;
357                         }
358
359                         if (actual_type != parse->type) {
360                                 printk(
361                 KERN_INFO "%s:%d conflicting memory types %Lx-%Lx %s<->%s\n",
362                                         current->comm, current->pid,
363                                         start, end,
364                                         cattr_name(actual_type),
365                                         cattr_name(parse->type));
366                                 err = -EBUSY;
367                                 break;
368                         }
369
370                         saved_ptr = parse;
371                         /*
372                          * Check to see whether the request overlaps more
373                          * than one entry in the list
374                          */
375                         list_for_each_entry_continue(parse, &memtype_list, nd) {
376                                 if (end <= parse->start) {
377                                         break;
378                                 }
379
380                                 if (actual_type != parse->type) {
381                                         printk(
382                 KERN_INFO "%s:%d conflicting memory types %Lx-%Lx %s<->%s\n",
383                                                 current->comm, current->pid,
384                                                 start, end,
385                                                 cattr_name(actual_type),
386                                                 cattr_name(parse->type));
387                                         err = -EBUSY;
388                                         break;
389                                 }
390                         }
391
392                         if (err) {
393                                 break;
394                         }
395
396                         dprintk("Overlap at 0x%Lx-0x%Lx\n",
397                                  saved_ptr->start, saved_ptr->end);
398                         /* No conflict. Go ahead and add this new entry */
399                         list_add(&new_entry->nd, &saved_ptr->nd);
400                         new_entry = NULL;
401                         break;
402                 }
403         }
404
405         if (err) {
406                 printk(KERN_INFO
407         "reserve_memtype failed 0x%Lx-0x%Lx, track %s, req %s\n",
408                         start, end, cattr_name(new_entry->type),
409                         cattr_name(req_type));
410                 kfree(new_entry);
411                 spin_unlock(&memtype_lock);
412                 return err;
413         }
414
415         if (new_entry) {
416                 /* No conflict. Not yet added to the list. Add to the tail */
417                 list_add_tail(&new_entry->nd, &memtype_list);
418                 dprintk("New Entry\n");
419         }
420
421         if (ret_type) {
422                 dprintk(
423         "reserve_memtype added 0x%Lx-0x%Lx, track %s, req %s, ret %s\n",
424                         start, end, cattr_name(actual_type),
425                         cattr_name(req_type), cattr_name(*ret_type));
426         } else {
427                 dprintk(
428         "reserve_memtype added 0x%Lx-0x%Lx, track %s, req %s\n",
429                         start, end, cattr_name(actual_type),
430                         cattr_name(req_type));
431         }
432
433         spin_unlock(&memtype_lock);
434         return err;
435 }
436
437 int free_memtype(u64 start, u64 end)
438 {
439         struct memtype *ml;
440         int err = -EINVAL;
441
442         /* Only track when pat_wc_enabled */
443         if (!pat_wc_enabled) {
444                 return 0;
445         }
446
447         /* Low ISA region is always mapped WB. No need to track */
448         if (start >= ISA_START_ADDRESS && end <= ISA_END_ADDRESS) {
449                 return 0;
450         }
451
452         spin_lock(&memtype_lock);
453         list_for_each_entry(ml, &memtype_list, nd) {
454                 if (ml->start == start && ml->end == end) {
455                         list_del(&ml->nd);
456                         kfree(ml);
457                         err = 0;
458                         break;
459                 }
460         }
461         spin_unlock(&memtype_lock);
462
463         if (err) {
464                 printk(KERN_INFO "%s:%d freeing invalid memtype %Lx-%Lx\n",
465                         current->comm, current->pid, start, end);
466         }
467
468         dprintk("free_memtype request 0x%Lx-0x%Lx\n", start, end);
469         return err;
470 }
471
472
473 /*
474  * /dev/mem mmap interface. The memtype used for mapping varies:
475  * - Use UC for mappings with O_SYNC flag
476  * - Without O_SYNC flag, if there is any conflict in reserve_memtype,
477  *   inherit the memtype from existing mapping.
478  * - Else use UC_MINUS memtype (for backward compatibility with existing
479  *   X drivers.
480  */
481 pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
482                                 unsigned long size, pgprot_t vma_prot)
483 {
484         return vma_prot;
485 }
486
487 #ifdef CONFIG_NONPROMISC_DEVMEM
488 /* This check is done in drivers/char/mem.c in case of NONPROMISC_DEVMEM*/
489 static inline int range_is_allowed(unsigned long pfn, unsigned long size)
490 {
491         return 1;
492 }
493 #else
494 static inline int range_is_allowed(unsigned long pfn, unsigned long size)
495 {
496         u64 from = ((u64)pfn) << PAGE_SHIFT;
497         u64 to = from + size;
498         u64 cursor = from;
499
500         while (cursor < to) {
501                 if (!devmem_is_allowed(pfn)) {
502                         printk(KERN_INFO
503                 "Program %s tried to access /dev/mem between %Lx->%Lx.\n",
504                                 current->comm, from, to);
505                         return 0;
506                 }
507                 cursor += PAGE_SIZE;
508                 pfn++;
509         }
510         return 1;
511 }
512 #endif /* CONFIG_NONPROMISC_DEVMEM */
513
514 int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
515                                 unsigned long size, pgprot_t *vma_prot)
516 {
517         u64 offset = ((u64) pfn) << PAGE_SHIFT;
518         unsigned long flags = _PAGE_CACHE_UC_MINUS;
519         int retval;
520
521         if (!range_is_allowed(pfn, size))
522                 return 0;
523
524         if (file->f_flags & O_SYNC) {
525                 flags = _PAGE_CACHE_UC;
526         }
527
528 #ifdef CONFIG_X86_32
529         /*
530          * On the PPro and successors, the MTRRs are used to set
531          * memory types for physical addresses outside main memory,
532          * so blindly setting UC or PWT on those pages is wrong.
533          * For Pentiums and earlier, the surround logic should disable
534          * caching for the high addresses through the KEN pin, but
535          * we maintain the tradition of paranoia in this code.
536          */
537         if (!pat_wc_enabled &&
538             ! ( boot_cpu_has(X86_FEATURE_MTRR) ||
539                 boot_cpu_has(X86_FEATURE_K6_MTRR) ||
540                 boot_cpu_has(X86_FEATURE_CYRIX_ARR) ||
541                 boot_cpu_has(X86_FEATURE_CENTAUR_MCR)) &&
542            (pfn << PAGE_SHIFT) >= __pa(high_memory)) {
543                 flags = _PAGE_CACHE_UC;
544         }
545 #endif
546
547         /*
548          * With O_SYNC, we can only take UC mapping. Fail if we cannot.
549          * Without O_SYNC, we want to get
550          * - WB for WB-able memory and no other conflicting mappings
551          * - UC_MINUS for non-WB-able memory with no other conflicting mappings
552          * - Inherit from confliting mappings otherwise
553          */
554         if (flags != _PAGE_CACHE_UC_MINUS) {
555                 retval = reserve_memtype(offset, offset + size, flags, NULL);
556         } else {
557                 retval = reserve_memtype(offset, offset + size, -1, &flags);
558         }
559
560         if (retval < 0)
561                 return 0;
562
563         if (pfn <= max_pfn_mapped &&
564             ioremap_change_attr((unsigned long)__va(offset), size, flags) < 0) {
565                 free_memtype(offset, offset + size);
566                 printk(KERN_INFO
567                 "%s:%d /dev/mem ioremap_change_attr failed %s for %Lx-%Lx\n",
568                         current->comm, current->pid,
569                         cattr_name(flags),
570                         offset, (unsigned long long)(offset + size));
571                 return 0;
572         }
573
574         *vma_prot = __pgprot((pgprot_val(*vma_prot) & ~_PAGE_CACHE_MASK) |
575                              flags);
576         return 1;
577 }
578
579 void map_devmem(unsigned long pfn, unsigned long size, pgprot_t vma_prot)
580 {
581         u64 addr = (u64)pfn << PAGE_SHIFT;
582         unsigned long flags;
583         unsigned long want_flags = (pgprot_val(vma_prot) & _PAGE_CACHE_MASK);
584
585         reserve_memtype(addr, addr + size, want_flags, &flags);
586         if (flags != want_flags) {
587                 printk(KERN_INFO
588                 "%s:%d /dev/mem expected mapping type %s for %Lx-%Lx, got %s\n",
589                         current->comm, current->pid,
590                         cattr_name(want_flags),
591                         addr, (unsigned long long)(addr + size),
592                         cattr_name(flags));
593         }
594 }
595
596 void unmap_devmem(unsigned long pfn, unsigned long size, pgprot_t vma_prot)
597 {
598         u64 addr = (u64)pfn << PAGE_SHIFT;
599
600         free_memtype(addr, addr + size);
601 }
602