blob: 704fc081c104b81852dfe8728f4a201f9b1fe9f6 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 * Re-map IO memory to kernel address space so that we can access it.
3 * This is needed for high PCI addresses that aren't mapped in the
4 * 640k-1MB IO memory area on PC's
5 *
6 * (C) Copyright 1995 1996 Linus Torvalds
7 */
8
Thomas Gleixnere9332ca2008-01-30 13:34:05 +01009#include <linux/bootmem.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070010#include <linux/init.h>
Haavard Skinnemoena148ecf2006-09-30 23:29:17 -070011#include <linux/io.h>
Ingo Molnar9de94db2017-01-27 13:08:42 +010012#include <linux/ioport.h>
Thomas Gleixner3cbd09e2008-01-30 13:34:05 +010013#include <linux/slab.h>
14#include <linux/vmalloc.h>
Pekka Paalanend61fc442008-05-12 21:20:57 +020015#include <linux/mmiotrace.h>
Tom Lendacky8f716c92017-07-17 16:10:16 -050016#include <linux/mem_encrypt.h>
17#include <linux/efi.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070018
Laura Abbottd1163652017-05-08 15:58:11 -070019#include <asm/set_memory.h>
Ingo Molnar66441bd2017-01-27 10:27:10 +010020#include <asm/e820/api.h>
Thomas Gleixner3cbd09e2008-01-30 13:34:05 +010021#include <asm/fixmap.h>
22#include <asm/pgtable.h>
23#include <asm/tlbflush.h>
Jeremy Fitzhardingef6df72e2008-01-30 13:34:11 +010024#include <asm/pgalloc.h>
venkatesh.pallipadi@intel.comd7677d42008-03-18 17:00:17 -070025#include <asm/pat.h>
Tom Lendacky8f716c92017-07-17 16:10:16 -050026#include <asm/setup.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070027
Jeremy Fitzhardinge78c86e52009-09-10 10:09:38 -070028#include "physaddr.h"
Thomas Gleixner240d3a72008-01-30 13:34:05 +010029
Linus Torvalds1da177e2005-04-16 15:20:36 -070030/*
Thomas Gleixnere9332ca2008-01-30 13:34:05 +010031 * Fix up the linear direct mapping of the kernel to avoid cache attribute
32 * conflicts.
33 */
venkatesh.pallipadi@intel.com3a96ce82008-03-18 17:00:16 -070034int ioremap_change_attr(unsigned long vaddr, unsigned long size,
Juergen Grossb14097b2014-11-03 14:01:58 +010035 enum page_cache_mode pcm)
Thomas Gleixnere9332ca2008-01-30 13:34:05 +010036{
Thomas Gleixnerd806e5e2008-01-30 13:34:06 +010037 unsigned long nrpages = size >> PAGE_SHIFT;
Harvey Harrison93809be2008-02-01 17:49:43 +010038 int err;
Thomas Gleixnere9332ca2008-01-30 13:34:05 +010039
Juergen Grossb14097b2014-11-03 14:01:58 +010040 switch (pcm) {
41 case _PAGE_CACHE_MODE_UC:
Thomas Gleixnerd806e5e2008-01-30 13:34:06 +010042 default:
venkatesh.pallipadi@intel.com12193332008-03-18 17:00:18 -070043 err = _set_memory_uc(vaddr, nrpages);
Thomas Gleixnerd806e5e2008-01-30 13:34:06 +010044 break;
Juergen Grossb14097b2014-11-03 14:01:58 +010045 case _PAGE_CACHE_MODE_WC:
venkatesh.pallipadi@intel.comb310f381d2008-03-18 17:00:24 -070046 err = _set_memory_wc(vaddr, nrpages);
47 break;
Toshi Kani623dffb2015-06-04 18:55:20 +020048 case _PAGE_CACHE_MODE_WT:
49 err = _set_memory_wt(vaddr, nrpages);
50 break;
Juergen Grossb14097b2014-11-03 14:01:58 +010051 case _PAGE_CACHE_MODE_WB:
venkatesh.pallipadi@intel.com12193332008-03-18 17:00:18 -070052 err = _set_memory_wb(vaddr, nrpages);
Thomas Gleixnerd806e5e2008-01-30 13:34:06 +010053 break;
54 }
Thomas Gleixnere9332ca2008-01-30 13:34:05 +010055
56 return err;
57}
58
Roland Dreierc81c8a12014-05-02 11:18:41 -070059static int __ioremap_check_ram(unsigned long start_pfn, unsigned long nr_pages,
60 void *arg)
61{
62 unsigned long i;
63
64 for (i = 0; i < nr_pages; ++i)
65 if (pfn_valid(start_pfn + i) &&
66 !PageReserved(pfn_to_page(start_pfn + i)))
67 return 1;
68
Roland Dreierc81c8a12014-05-02 11:18:41 -070069 return 0;
70}
71
Thomas Gleixnere9332ca2008-01-30 13:34:05 +010072/*
Linus Torvalds1da177e2005-04-16 15:20:36 -070073 * Remap an arbitrary physical address space into the kernel virtual
Toshi Kani5d72b4f2015-04-14 15:47:29 -070074 * address space. It transparently creates kernel huge I/O mapping when
75 * the physical address is aligned by a huge page size (1GB or 2MB) and
76 * the requested size is at least the huge page size.
77 *
78 * NOTE: MTRRs can override PAT memory types with a 4KB granularity.
79 * Therefore, the mapping code falls back to use a smaller page toward 4KB
80 * when a mapping range is covered by non-WB type of MTRRs.
Linus Torvalds1da177e2005-04-16 15:20:36 -070081 *
82 * NOTE! We need to allow non-page-aligned mappings too: we will obviously
83 * have to convert them into an offset in a page-aligned mapping, but the
84 * caller shouldn't need to know that small detail.
85 */
Christoph Lameter23016962008-04-28 02:12:42 -070086static void __iomem *__ioremap_caller(resource_size_t phys_addr,
Juergen Grossb14097b2014-11-03 14:01:58 +010087 unsigned long size, enum page_cache_mode pcm, void *caller)
Linus Torvalds1da177e2005-04-16 15:20:36 -070088{
Kenji Kaneshigeffa71f32010-06-18 12:22:40 +090089 unsigned long offset, vaddr;
90 resource_size_t pfn, last_pfn, last_addr;
Pekka Paalanen87e547f2008-05-12 21:21:03 +020091 const resource_size_t unaligned_phys_addr = phys_addr;
92 const unsigned long unaligned_size = size;
Thomas Gleixner91eebf42008-01-30 13:34:05 +010093 struct vm_struct *area;
Juergen Grossb14097b2014-11-03 14:01:58 +010094 enum page_cache_mode new_pcm;
Thomas Gleixnerd806e5e2008-01-30 13:34:06 +010095 pgprot_t prot;
Venki Pallipadidee7cbb2008-03-24 14:39:55 -070096 int retval;
Pekka Paalanend61fc442008-05-12 21:20:57 +020097 void __iomem *ret_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -070098
99 /* Don't allow wraparound or zero size */
100 last_addr = phys_addr + size - 1;
101 if (!size || last_addr < phys_addr)
102 return NULL;
103
Thomas Gleixnere3100c82008-02-27 20:57:40 +0100104 if (!phys_addr_valid(phys_addr)) {
venkatesh.pallipadi@intel.com6997ab42008-03-18 17:00:25 -0700105 printk(KERN_WARNING "ioremap: invalid physical address %llx\n",
Randy Dunlap4c8337a2008-04-10 15:09:50 -0700106 (unsigned long long)phys_addr);
Thomas Gleixnere3100c82008-02-27 20:57:40 +0100107 WARN_ON_ONCE(1);
108 return NULL;
109 }
110
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111 /*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112 * Don't allow anybody to remap normal RAM that we're using..
113 */
Toshi Kani9a58eeb2015-07-16 17:23:15 -0600114 pfn = phys_addr >> PAGE_SHIFT;
115 last_pfn = last_addr >> PAGE_SHIFT;
116 if (walk_system_ram_range(pfn, last_pfn - pfn + 1, NULL,
117 __ioremap_check_ram) == 1) {
Thomas Gleixner8a0a5da2015-07-24 16:13:43 +0200118 WARN_ONCE(1, "ioremap on RAM at %pa - %pa\n",
119 &phys_addr, &last_addr);
Roland Dreierc81c8a12014-05-02 11:18:41 -0700120 return NULL;
Mike Travis906e36c2014-10-13 15:54:05 -0700121 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122
venkatesh.pallipadi@intel.comd7677d42008-03-18 17:00:17 -0700123 /*
124 * Mappings have to be page-aligned
125 */
126 offset = phys_addr & ~PAGE_MASK;
Kenji Kaneshigeffa71f32010-06-18 12:22:40 +0900127 phys_addr &= PHYSICAL_PAGE_MASK;
venkatesh.pallipadi@intel.comd7677d42008-03-18 17:00:17 -0700128 size = PAGE_ALIGN(last_addr+1) - phys_addr;
129
Andi Kleene213e872008-08-15 18:12:47 +0200130 retval = reserve_memtype(phys_addr, (u64)phys_addr + size,
Juergen Grosse00c8cc2014-11-03 14:01:59 +0100131 pcm, &new_pcm);
Venki Pallipadidee7cbb2008-03-24 14:39:55 -0700132 if (retval) {
Venkatesh Pallipadi279e6692009-07-10 09:57:33 -0700133 printk(KERN_ERR "ioremap reserve_memtype failed %d\n", retval);
Venki Pallipadidee7cbb2008-03-24 14:39:55 -0700134 return NULL;
135 }
136
Juergen Grossb14097b2014-11-03 14:01:58 +0100137 if (pcm != new_pcm) {
138 if (!is_new_memtype_allowed(phys_addr, size, pcm, new_pcm)) {
Venkatesh Pallipadi279e6692009-07-10 09:57:33 -0700139 printk(KERN_ERR
Juergen Grossb14097b2014-11-03 14:01:58 +0100140 "ioremap error for 0x%llx-0x%llx, requested 0x%x, got 0x%x\n",
Randy Dunlap4c8337a2008-04-10 15:09:50 -0700141 (unsigned long long)phys_addr,
142 (unsigned long long)(phys_addr + size),
Juergen Grossb14097b2014-11-03 14:01:58 +0100143 pcm, new_pcm);
Xiaotian Fengde2a47c2009-11-05 10:43:51 +0800144 goto err_free_memtype;
venkatesh.pallipadi@intel.comd7677d42008-03-18 17:00:17 -0700145 }
Juergen Grossb14097b2014-11-03 14:01:58 +0100146 pcm = new_pcm;
venkatesh.pallipadi@intel.comd7677d42008-03-18 17:00:17 -0700147 }
148
Juergen Grossb14097b2014-11-03 14:01:58 +0100149 prot = PAGE_KERNEL_IO;
150 switch (pcm) {
151 case _PAGE_CACHE_MODE_UC:
Thomas Gleixnerd806e5e2008-01-30 13:34:06 +0100152 default:
Juergen Grossb14097b2014-11-03 14:01:58 +0100153 prot = __pgprot(pgprot_val(prot) |
154 cachemode2protval(_PAGE_CACHE_MODE_UC));
Thomas Gleixnerd806e5e2008-01-30 13:34:06 +0100155 break;
Juergen Grossb14097b2014-11-03 14:01:58 +0100156 case _PAGE_CACHE_MODE_UC_MINUS:
157 prot = __pgprot(pgprot_val(prot) |
158 cachemode2protval(_PAGE_CACHE_MODE_UC_MINUS));
Suresh Siddhade33c442008-04-25 17:07:22 -0700159 break;
Juergen Grossb14097b2014-11-03 14:01:58 +0100160 case _PAGE_CACHE_MODE_WC:
161 prot = __pgprot(pgprot_val(prot) |
162 cachemode2protval(_PAGE_CACHE_MODE_WC));
venkatesh.pallipadi@intel.comb310f381d2008-03-18 17:00:24 -0700163 break;
Toshi Kanid8382702015-06-04 18:55:15 +0200164 case _PAGE_CACHE_MODE_WT:
165 prot = __pgprot(pgprot_val(prot) |
166 cachemode2protval(_PAGE_CACHE_MODE_WT));
167 break;
Juergen Grossb14097b2014-11-03 14:01:58 +0100168 case _PAGE_CACHE_MODE_WB:
Thomas Gleixnerd806e5e2008-01-30 13:34:06 +0100169 break;
170 }
Haavard Skinnemoena148ecf2006-09-30 23:29:17 -0700171
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172 /*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173 * Ok, go for it..
174 */
Christoph Lameter23016962008-04-28 02:12:42 -0700175 area = get_vm_area_caller(size, VM_IOREMAP, caller);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700176 if (!area)
Xiaotian Fengde2a47c2009-11-05 10:43:51 +0800177 goto err_free_memtype;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700178 area->phys_addr = phys_addr;
Thomas Gleixnere66aadb2008-02-04 16:48:05 +0100179 vaddr = (unsigned long) area->addr;
Suresh Siddha43a432b2009-04-09 14:26:47 -0700180
Juergen Grossb14097b2014-11-03 14:01:58 +0100181 if (kernel_map_sync_memtype(phys_addr, size, pcm))
Xiaotian Fengde2a47c2009-11-05 10:43:51 +0800182 goto err_free_area;
Thomas Gleixnere9332ca2008-01-30 13:34:05 +0100183
Xiaotian Fengde2a47c2009-11-05 10:43:51 +0800184 if (ioremap_page_range(vaddr, vaddr + size, phys_addr, prot))
185 goto err_free_area;
Thomas Gleixnere9332ca2008-01-30 13:34:05 +0100186
Pekka Paalanend61fc442008-05-12 21:20:57 +0200187 ret_addr = (void __iomem *) (vaddr + offset);
Pekka Paalanen87e547f2008-05-12 21:21:03 +0200188 mmiotrace_ioremap(unaligned_phys_addr, unaligned_size, ret_addr);
Pekka Paalanend61fc442008-05-12 21:20:57 +0200189
Tim Gardnerc7a7b8142011-04-28 11:00:30 -0600190 /*
191 * Check if the request spans more than any BAR in the iomem resource
192 * tree.
193 */
Laura Abbott9abb0ec2015-12-21 12:01:14 -0800194 if (iomem_map_sanity_check(unaligned_phys_addr, unaligned_size))
195 pr_warn("caller %pS mapping multiple BARs\n", caller);
Tim Gardnerc7a7b8142011-04-28 11:00:30 -0600196
Pekka Paalanend61fc442008-05-12 21:20:57 +0200197 return ret_addr;
Xiaotian Fengde2a47c2009-11-05 10:43:51 +0800198err_free_area:
199 free_vm_area(area);
200err_free_memtype:
201 free_memtype(phys_addr, phys_addr + size);
202 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204
205/**
206 * ioremap_nocache - map bus memory into CPU space
Wanpeng Li9efc31b2012-06-10 10:50:52 +0800207 * @phys_addr: bus address of the memory
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208 * @size: size of the resource to map
209 *
210 * ioremap_nocache performs a platform specific sequence of operations to
211 * make bus memory CPU accessible via the readb/readw/readl/writeb/
212 * writew/writel functions and the other mmio helpers. The returned
213 * address is not guaranteed to be usable directly as a virtual
Thomas Gleixner91eebf42008-01-30 13:34:05 +0100214 * address.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215 *
216 * This version of ioremap ensures that the memory is marked uncachable
217 * on the CPU as well as honouring existing caching rules from things like
Thomas Gleixner91eebf42008-01-30 13:34:05 +0100218 * the PCI bus. Note that there are other caches and buffers on many
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219 * busses. In particular driver authors should read up on PCI writes
220 *
221 * It's useful if some control registers are in such an area and
222 * write combining or read caching is not desirable:
Thomas Gleixner91eebf42008-01-30 13:34:05 +0100223 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224 * Must be freed with iounmap.
225 */
Linus Torvaldsb9e76a02008-03-24 11:22:39 -0700226void __iomem *ioremap_nocache(resource_size_t phys_addr, unsigned long size)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227{
Suresh Siddhade33c442008-04-25 17:07:22 -0700228 /*
229 * Ideally, this should be:
Luis R. Rodriguezcb32edf2015-05-26 10:28:15 +0200230 * pat_enabled() ? _PAGE_CACHE_MODE_UC : _PAGE_CACHE_MODE_UC_MINUS;
Suresh Siddhade33c442008-04-25 17:07:22 -0700231 *
232 * Till we fix all X drivers to use ioremap_wc(), we will use
Luis R. Rodrigueze4b6be332015-05-11 10:15:53 +0200233 * UC MINUS. Drivers that are certain they need or can already
234 * be converted over to strong UC can use ioremap_uc().
Suresh Siddhade33c442008-04-25 17:07:22 -0700235 */
Juergen Grossb14097b2014-11-03 14:01:58 +0100236 enum page_cache_mode pcm = _PAGE_CACHE_MODE_UC_MINUS;
Suresh Siddhade33c442008-04-25 17:07:22 -0700237
Juergen Grossb14097b2014-11-03 14:01:58 +0100238 return __ioremap_caller(phys_addr, size, pcm,
Christoph Lameter23016962008-04-28 02:12:42 -0700239 __builtin_return_address(0));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700240}
Alexey Dobriyan129f6942005-06-23 00:08:33 -0700241EXPORT_SYMBOL(ioremap_nocache);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700242
venkatesh.pallipadi@intel.comb310f381d2008-03-18 17:00:24 -0700243/**
Luis R. Rodrigueze4b6be332015-05-11 10:15:53 +0200244 * ioremap_uc - map bus memory into CPU space as strongly uncachable
245 * @phys_addr: bus address of the memory
246 * @size: size of the resource to map
247 *
248 * ioremap_uc performs a platform specific sequence of operations to
249 * make bus memory CPU accessible via the readb/readw/readl/writeb/
250 * writew/writel functions and the other mmio helpers. The returned
251 * address is not guaranteed to be usable directly as a virtual
252 * address.
253 *
254 * This version of ioremap ensures that the memory is marked with a strong
255 * preference as completely uncachable on the CPU when possible. For non-PAT
256 * systems this ends up setting page-attribute flags PCD=1, PWT=1. For PAT
257 * systems this will set the PAT entry for the pages as strong UC. This call
258 * will honor existing caching rules from things like the PCI bus. Note that
259 * there are other caches and buffers on many busses. In particular driver
260 * authors should read up on PCI writes.
261 *
262 * It's useful if some control registers are in such an area and
263 * write combining or read caching is not desirable:
264 *
265 * Must be freed with iounmap.
266 */
267void __iomem *ioremap_uc(resource_size_t phys_addr, unsigned long size)
268{
269 enum page_cache_mode pcm = _PAGE_CACHE_MODE_UC;
270
271 return __ioremap_caller(phys_addr, size, pcm,
272 __builtin_return_address(0));
273}
274EXPORT_SYMBOL_GPL(ioremap_uc);
275
276/**
venkatesh.pallipadi@intel.comb310f381d2008-03-18 17:00:24 -0700277 * ioremap_wc - map memory into CPU space write combined
Wanpeng Li9efc31b2012-06-10 10:50:52 +0800278 * @phys_addr: bus address of the memory
venkatesh.pallipadi@intel.comb310f381d2008-03-18 17:00:24 -0700279 * @size: size of the resource to map
280 *
281 * This version of ioremap ensures that the memory is marked write combining.
282 * Write combining allows faster writes to some hardware devices.
283 *
284 * Must be freed with iounmap.
285 */
venkatesh.pallipadi@intel.comd639bab2009-01-09 16:13:13 -0800286void __iomem *ioremap_wc(resource_size_t phys_addr, unsigned long size)
venkatesh.pallipadi@intel.comb310f381d2008-03-18 17:00:24 -0700287{
Borislav Petkov7202fdb2015-06-04 18:55:11 +0200288 return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WC,
Christoph Lameter23016962008-04-28 02:12:42 -0700289 __builtin_return_address(0));
venkatesh.pallipadi@intel.comb310f381d2008-03-18 17:00:24 -0700290}
291EXPORT_SYMBOL(ioremap_wc);
292
Toshi Kanid8382702015-06-04 18:55:15 +0200293/**
294 * ioremap_wt - map memory into CPU space write through
295 * @phys_addr: bus address of the memory
296 * @size: size of the resource to map
297 *
298 * This version of ioremap ensures that the memory is marked write through.
299 * Write through stores data into memory while keeping the cache up-to-date.
300 *
301 * Must be freed with iounmap.
302 */
303void __iomem *ioremap_wt(resource_size_t phys_addr, unsigned long size)
304{
305 return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WT,
306 __builtin_return_address(0));
307}
308EXPORT_SYMBOL(ioremap_wt);
309
Linus Torvaldsb9e76a02008-03-24 11:22:39 -0700310void __iomem *ioremap_cache(resource_size_t phys_addr, unsigned long size)
Thomas Gleixner5f868152008-01-30 13:34:06 +0100311{
Juergen Grossb14097b2014-11-03 14:01:58 +0100312 return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WB,
Christoph Lameter23016962008-04-28 02:12:42 -0700313 __builtin_return_address(0));
Thomas Gleixner5f868152008-01-30 13:34:06 +0100314}
315EXPORT_SYMBOL(ioremap_cache);
316
Rik van Riel28b2ee22008-07-23 21:27:05 -0700317void __iomem *ioremap_prot(resource_size_t phys_addr, unsigned long size,
318 unsigned long prot_val)
319{
Juergen Grossb14097b2014-11-03 14:01:58 +0100320 return __ioremap_caller(phys_addr, size,
321 pgprot2cachemode(__pgprot(prot_val)),
Rik van Riel28b2ee22008-07-23 21:27:05 -0700322 __builtin_return_address(0));
323}
324EXPORT_SYMBOL(ioremap_prot);
325
Andi Kleenbf5421c2005-12-12 22:17:09 -0800326/**
327 * iounmap - Free a IO remapping
328 * @addr: virtual address from ioremap_*
329 *
330 * Caller must ensure there is only one unmapping for the same pointer.
331 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332void iounmap(volatile void __iomem *addr)
333{
Andi Kleenbf5421c2005-12-12 22:17:09 -0800334 struct vm_struct *p, *o;
Andrew Mortonc23a4e962005-07-07 17:56:02 -0700335
336 if ((void __force *)addr <= high_memory)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700337 return;
338
339 /*
Tom Lendacky33c2b802017-07-17 16:10:04 -0500340 * The PCI/ISA range special-casing was removed from __ioremap()
341 * so this check, in theory, can be removed. However, there are
342 * cases where iounmap() is called for addresses not obtained via
343 * ioremap() (vga16fb for example). Add a warning so that these
344 * cases can be caught and fixed.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700345 */
Thomas Gleixner6e92a5a2008-05-12 15:43:35 +0200346 if ((void __force *)addr >= phys_to_virt(ISA_START_ADDRESS) &&
Tom Lendacky33c2b802017-07-17 16:10:04 -0500347 (void __force *)addr < phys_to_virt(ISA_END_ADDRESS)) {
348 WARN(1, "iounmap() called for ISA range not obtained using ioremap()\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349 return;
Tom Lendacky33c2b802017-07-17 16:10:04 -0500350 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351
Thomas Gleixner91eebf42008-01-30 13:34:05 +0100352 addr = (volatile void __iomem *)
353 (PAGE_MASK & (unsigned long __force)addr);
Andi Kleenbf5421c2005-12-12 22:17:09 -0800354
Pekka Paalanend61fc442008-05-12 21:20:57 +0200355 mmiotrace_iounmap(addr);
356
Andi Kleenbf5421c2005-12-12 22:17:09 -0800357 /* Use the vm area unlocked, assuming the caller
358 ensures there isn't another iounmap for the same address
359 in parallel. Reuse of the virtual address is prevented by
360 leaving it in the global lists until we're done with it.
361 cpa takes care of the direct mappings. */
Joonsoo Kimef932472013-04-29 15:07:27 -0700362 p = find_vm_area((void __force *)addr);
Andi Kleenbf5421c2005-12-12 22:17:09 -0800363
364 if (!p) {
Thomas Gleixner91eebf42008-01-30 13:34:05 +0100365 printk(KERN_ERR "iounmap: bad address %p\n", addr);
Andrew Mortonc23a4e962005-07-07 17:56:02 -0700366 dump_stack();
Andi Kleenbf5421c2005-12-12 22:17:09 -0800367 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368 }
369
venkatesh.pallipadi@intel.comd7677d42008-03-18 17:00:17 -0700370 free_memtype(p->phys_addr, p->phys_addr + get_vm_area_size(p));
371
Andi Kleenbf5421c2005-12-12 22:17:09 -0800372 /* Finally remove it */
Thomas Gleixner6e92a5a2008-05-12 15:43:35 +0200373 o = remove_vm_area((void __force *)addr);
Andi Kleenbf5421c2005-12-12 22:17:09 -0800374 BUG_ON(p != o || o == NULL);
Thomas Gleixner91eebf42008-01-30 13:34:05 +0100375 kfree(p);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700376}
Alexey Dobriyan129f6942005-06-23 00:08:33 -0700377EXPORT_SYMBOL(iounmap);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378
Jan Beulich1e6277d2015-05-28 09:29:27 +0100379int __init arch_ioremap_pud_supported(void)
Toshi Kani5d72b4f2015-04-14 15:47:29 -0700380{
381#ifdef CONFIG_X86_64
Borislav Petkovb8291adc2016-03-29 17:41:58 +0200382 return boot_cpu_has(X86_FEATURE_GBPAGES);
Toshi Kani5d72b4f2015-04-14 15:47:29 -0700383#else
384 return 0;
385#endif
386}
387
Jan Beulich1e6277d2015-05-28 09:29:27 +0100388int __init arch_ioremap_pmd_supported(void)
Toshi Kani5d72b4f2015-04-14 15:47:29 -0700389{
Borislav Petkov16bf9222016-03-29 17:42:03 +0200390 return boot_cpu_has(X86_FEATURE_PSE);
Toshi Kani5d72b4f2015-04-14 15:47:29 -0700391}
392
venkatesh.pallipadi@intel.come045fb22008-03-18 17:00:15 -0700393/*
394 * Convert a physical pointer to a virtual kernel pointer for /dev/mem
395 * access
396 */
Thierry Reding4707a342014-07-28 17:20:33 +0200397void *xlate_dev_mem_ptr(phys_addr_t phys)
venkatesh.pallipadi@intel.come045fb22008-03-18 17:00:15 -0700398{
Ingo Molnar94d4b472012-11-23 19:19:07 +0100399 unsigned long start = phys & PAGE_MASK;
400 unsigned long offset = phys & ~PAGE_MASK;
Ingo Molnar562bfca2015-05-08 12:43:53 +0200401 void *vaddr;
venkatesh.pallipadi@intel.come045fb22008-03-18 17:00:15 -0700402
403 /* If page is RAM, we can use __va. Otherwise ioremap and unmap. */
404 if (page_is_ram(start >> PAGE_SHIFT))
405 return __va(phys);
406
Ingo Molnar562bfca2015-05-08 12:43:53 +0200407 vaddr = ioremap_cache(start, PAGE_SIZE);
Ingo Molnar94d4b472012-11-23 19:19:07 +0100408 /* Only add the offset on success and return NULL if the ioremap() failed: */
409 if (vaddr)
410 vaddr += offset;
venkatesh.pallipadi@intel.come045fb22008-03-18 17:00:15 -0700411
Ingo Molnar562bfca2015-05-08 12:43:53 +0200412 return vaddr;
venkatesh.pallipadi@intel.come045fb22008-03-18 17:00:15 -0700413}
414
Thierry Reding4707a342014-07-28 17:20:33 +0200415void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr)
venkatesh.pallipadi@intel.come045fb22008-03-18 17:00:15 -0700416{
417 if (page_is_ram(phys >> PAGE_SHIFT))
418 return;
419
420 iounmap((void __iomem *)((unsigned long)addr & PAGE_MASK));
venkatesh.pallipadi@intel.come045fb22008-03-18 17:00:15 -0700421}
422
Tom Lendacky8f716c92017-07-17 16:10:16 -0500423/*
424 * Examine the physical address to determine if it is an area of memory
425 * that should be mapped decrypted. If the memory is not part of the
426 * kernel usable area it was accessed and created decrypted, so these
Tom Lendacky1de32862017-07-17 16:10:18 -0500427 * areas should be mapped decrypted. And since the encryption key can
428 * change across reboots, persistent memory should also be mapped
429 * decrypted.
Tom Lendacky8f716c92017-07-17 16:10:16 -0500430 */
431static bool memremap_should_map_decrypted(resource_size_t phys_addr,
432 unsigned long size)
433{
Tom Lendacky1de32862017-07-17 16:10:18 -0500434 int is_pmem;
435
436 /*
437 * Check if the address is part of a persistent memory region.
438 * This check covers areas added by E820, EFI and ACPI.
439 */
440 is_pmem = region_intersects(phys_addr, size, IORESOURCE_MEM,
441 IORES_DESC_PERSISTENT_MEMORY);
442 if (is_pmem != REGION_DISJOINT)
443 return true;
444
445 /*
446 * Check if the non-volatile attribute is set for an EFI
447 * reserved area.
448 */
449 if (efi_enabled(EFI_BOOT)) {
450 switch (efi_mem_type(phys_addr)) {
451 case EFI_RESERVED_TYPE:
452 if (efi_mem_attributes(phys_addr) & EFI_MEMORY_NV)
453 return true;
454 break;
455 default:
456 break;
457 }
458 }
459
Tom Lendacky8f716c92017-07-17 16:10:16 -0500460 /* Check if the address is outside kernel usable area */
461 switch (e820__get_entry_type(phys_addr, phys_addr + size - 1)) {
462 case E820_TYPE_RESERVED:
463 case E820_TYPE_ACPI:
464 case E820_TYPE_NVS:
465 case E820_TYPE_UNUSABLE:
Tom Lendacky1de32862017-07-17 16:10:18 -0500466 case E820_TYPE_PRAM:
Tom Lendacky8f716c92017-07-17 16:10:16 -0500467 return true;
468 default:
469 break;
470 }
471
472 return false;
473}
474
475/*
476 * Examine the physical address to determine if it is EFI data. Check
477 * it against the boot params structure and EFI tables and memory types.
478 */
479static bool memremap_is_efi_data(resource_size_t phys_addr,
480 unsigned long size)
481{
482 u64 paddr;
483
484 /* Check if the address is part of EFI boot/runtime data */
485 if (!efi_enabled(EFI_BOOT))
486 return false;
487
488 paddr = boot_params.efi_info.efi_memmap_hi;
489 paddr <<= 32;
490 paddr |= boot_params.efi_info.efi_memmap;
491 if (phys_addr == paddr)
492 return true;
493
494 paddr = boot_params.efi_info.efi_systab_hi;
495 paddr <<= 32;
496 paddr |= boot_params.efi_info.efi_systab;
497 if (phys_addr == paddr)
498 return true;
499
500 if (efi_is_table_address(phys_addr))
501 return true;
502
503 switch (efi_mem_type(phys_addr)) {
504 case EFI_BOOT_SERVICES_DATA:
505 case EFI_RUNTIME_SERVICES_DATA:
506 return true;
507 default:
508 break;
509 }
510
511 return false;
512}
513
514/*
515 * Examine the physical address to determine if it is boot data by checking
516 * it against the boot params setup_data chain.
517 */
518static bool memremap_is_setup_data(resource_size_t phys_addr,
519 unsigned long size)
520{
521 struct setup_data *data;
522 u64 paddr, paddr_next;
523
524 paddr = boot_params.hdr.setup_data;
525 while (paddr) {
526 unsigned int len;
527
528 if (phys_addr == paddr)
529 return true;
530
531 data = memremap(paddr, sizeof(*data),
532 MEMREMAP_WB | MEMREMAP_DEC);
533
534 paddr_next = data->next;
535 len = data->len;
536
537 memunmap(data);
538
539 if ((phys_addr > paddr) && (phys_addr < (paddr + len)))
540 return true;
541
542 paddr = paddr_next;
543 }
544
545 return false;
546}
547
548/*
549 * Examine the physical address to determine if it is boot data by checking
550 * it against the boot params setup_data chain (early boot version).
551 */
552static bool __init early_memremap_is_setup_data(resource_size_t phys_addr,
553 unsigned long size)
554{
555 struct setup_data *data;
556 u64 paddr, paddr_next;
557
558 paddr = boot_params.hdr.setup_data;
559 while (paddr) {
560 unsigned int len;
561
562 if (phys_addr == paddr)
563 return true;
564
565 data = early_memremap_decrypted(paddr, sizeof(*data));
566
567 paddr_next = data->next;
568 len = data->len;
569
570 early_memunmap(data, sizeof(*data));
571
572 if ((phys_addr > paddr) && (phys_addr < (paddr + len)))
573 return true;
574
575 paddr = paddr_next;
576 }
577
578 return false;
579}
580
581/*
582 * Architecture function to determine if RAM remap is allowed. By default, a
583 * RAM remap will map the data as encrypted. Determine if a RAM remap should
584 * not be done so that the data will be mapped decrypted.
585 */
586bool arch_memremap_can_ram_remap(resource_size_t phys_addr, unsigned long size,
587 unsigned long flags)
588{
589 if (!sme_active())
590 return true;
591
592 if (flags & MEMREMAP_ENC)
593 return true;
594
595 if (flags & MEMREMAP_DEC)
596 return false;
597
598 if (memremap_is_setup_data(phys_addr, size) ||
599 memremap_is_efi_data(phys_addr, size) ||
600 memremap_should_map_decrypted(phys_addr, size))
601 return false;
602
603 return true;
604}
605
606/*
607 * Architecture override of __weak function to adjust the protection attributes
608 * used when remapping memory. By default, early_memremap() will map the data
609 * as encrypted. Determine if an encrypted mapping should not be done and set
610 * the appropriate protection attributes.
611 */
612pgprot_t __init early_memremap_pgprot_adjust(resource_size_t phys_addr,
613 unsigned long size,
614 pgprot_t prot)
615{
616 if (!sme_active())
617 return prot;
618
619 if (early_memremap_is_setup_data(phys_addr, size) ||
620 memremap_is_efi_data(phys_addr, size) ||
621 memremap_should_map_decrypted(phys_addr, size))
622 prot = pgprot_decrypted(prot);
623 else
624 prot = pgprot_encrypted(prot);
625
626 return prot;
627}
628
Tom Lendackyf88a68f2017-07-17 16:10:09 -0500629#ifdef CONFIG_ARCH_USE_MEMREMAP_PROT
630/* Remap memory with encryption */
631void __init *early_memremap_encrypted(resource_size_t phys_addr,
632 unsigned long size)
633{
634 return early_memremap_prot(phys_addr, size, __PAGE_KERNEL_ENC);
635}
636
637/*
638 * Remap memory with encryption and write-protected - cannot be called
639 * before pat_init() is called
640 */
641void __init *early_memremap_encrypted_wp(resource_size_t phys_addr,
642 unsigned long size)
643{
644 /* Be sure the write-protect PAT entry is set for write-protect */
645 if (__pte2cachemode_tbl[_PAGE_CACHE_MODE_WP] != _PAGE_CACHE_MODE_WP)
646 return NULL;
647
648 return early_memremap_prot(phys_addr, size, __PAGE_KERNEL_ENC_WP);
649}
650
651/* Remap memory without encryption */
652void __init *early_memremap_decrypted(resource_size_t phys_addr,
653 unsigned long size)
654{
655 return early_memremap_prot(phys_addr, size, __PAGE_KERNEL_NOENC);
656}
657
658/*
659 * Remap memory without encryption and write-protected - cannot be called
660 * before pat_init() is called
661 */
662void __init *early_memremap_decrypted_wp(resource_size_t phys_addr,
663 unsigned long size)
664{
665 /* Be sure the write-protect PAT entry is set for write-protect */
666 if (__pte2cachemode_tbl[_PAGE_CACHE_MODE_WP] != _PAGE_CACHE_MODE_WP)
667 return NULL;
668
669 return early_memremap_prot(phys_addr, size, __PAGE_KERNEL_NOENC_WP);
670}
671#endif /* CONFIG_ARCH_USE_MEMREMAP_PROT */
672
Jeremy Fitzhardinge45c7b282009-03-20 17:53:34 -0700673static pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)] __page_aligned_bss;
Huang, Ying0947b2f2008-01-30 13:33:44 +0100674
Ian Campbell551889a62008-02-09 23:24:09 +0100675static inline pmd_t * __init early_ioremap_pmd(unsigned long addr)
Huang, Ying0947b2f2008-01-30 13:33:44 +0100676{
Jeremy Fitzhardinge37cc8d72008-02-13 16:20:35 +0100677 /* Don't assume we're using swapper_pg_dir at this point */
Andy Lutomirski6c690ee2017-06-12 10:26:14 -0700678 pgd_t *base = __va(read_cr3_pa());
Jeremy Fitzhardinge37cc8d72008-02-13 16:20:35 +0100679 pgd_t *pgd = &base[pgd_index(addr)];
Kirill A. Shutemove0c4f672017-03-13 17:33:05 +0300680 p4d_t *p4d = p4d_offset(pgd, addr);
681 pud_t *pud = pud_offset(p4d, addr);
Ian Campbell551889a62008-02-09 23:24:09 +0100682 pmd_t *pmd = pmd_offset(pud, addr);
683
684 return pmd;
Huang, Ying0947b2f2008-01-30 13:33:44 +0100685}
686
Ian Campbell551889a62008-02-09 23:24:09 +0100687static inline pte_t * __init early_ioremap_pte(unsigned long addr)
Huang, Ying0947b2f2008-01-30 13:33:44 +0100688{
Ian Campbell551889a62008-02-09 23:24:09 +0100689 return &bm_pte[pte_index(addr)];
Huang, Ying0947b2f2008-01-30 13:33:44 +0100690}
691
Jeremy Fitzhardingefef5ba72010-10-13 16:02:24 -0700692bool __init is_early_ioremap_ptep(pte_t *ptep)
693{
694 return ptep >= &bm_pte[0] && ptep < &bm_pte[PAGE_SIZE/sizeof(pte_t)];
695}
696
Huang, Yingbeacfaa2008-01-30 13:33:44 +0100697void __init early_ioremap_init(void)
Huang, Ying0947b2f2008-01-30 13:33:44 +0100698{
Ian Campbell551889a62008-02-09 23:24:09 +0100699 pmd_t *pmd;
Huang, Ying0947b2f2008-01-30 13:33:44 +0100700
Andy Lutomirski73159fd2014-05-05 12:19:31 -0700701#ifdef CONFIG_X86_64
702 BUILD_BUG_ON((fix_to_virt(0) + PAGE_SIZE) & ((1 << PMD_SHIFT) - 1));
703#else
704 WARN_ON((fix_to_virt(0) + PAGE_SIZE) & ((1 << PMD_SHIFT) - 1));
705#endif
706
Mark Salter5b7c73e2014-04-07 15:39:49 -0700707 early_ioremap_setup();
Wang Chen88272472009-03-07 13:34:19 +0800708
Ian Campbell551889a62008-02-09 23:24:09 +0100709 pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN));
Jeremy Fitzhardinge45c7b282009-03-20 17:53:34 -0700710 memset(bm_pte, 0, sizeof(bm_pte));
711 pmd_populate_kernel(&init_mm, pmd, bm_pte);
Ian Campbell551889a62008-02-09 23:24:09 +0100712
Ingo Molnar0e3a9542008-01-30 13:33:49 +0100713 /*
Ian Campbell551889a62008-02-09 23:24:09 +0100714 * The boot-ioremap range spans multiple pmds, for which
Ingo Molnar0e3a9542008-01-30 13:33:49 +0100715 * we are not prepared:
716 */
Jan Beulich499a5f12009-12-18 16:05:51 +0000717#define __FIXADDR_TOP (-PAGE_SIZE)
718 BUILD_BUG_ON((__fix_to_virt(FIX_BTMAP_BEGIN) >> PMD_SHIFT)
719 != (__fix_to_virt(FIX_BTMAP_END) >> PMD_SHIFT));
720#undef __FIXADDR_TOP
Ian Campbell551889a62008-02-09 23:24:09 +0100721 if (pmd != early_ioremap_pmd(fix_to_virt(FIX_BTMAP_END))) {
Ingo Molnar0e3a9542008-01-30 13:33:49 +0100722 WARN_ON(1);
Ian Campbell551889a62008-02-09 23:24:09 +0100723 printk(KERN_WARNING "pmd %p != %p\n",
724 pmd, early_ioremap_pmd(fix_to_virt(FIX_BTMAP_END)));
Thomas Gleixner91eebf42008-01-30 13:34:05 +0100725 printk(KERN_WARNING "fix_to_virt(FIX_BTMAP_BEGIN): %08lx\n",
Ian Campbell551889a62008-02-09 23:24:09 +0100726 fix_to_virt(FIX_BTMAP_BEGIN));
Thomas Gleixner91eebf42008-01-30 13:34:05 +0100727 printk(KERN_WARNING "fix_to_virt(FIX_BTMAP_END): %08lx\n",
Ian Campbell551889a62008-02-09 23:24:09 +0100728 fix_to_virt(FIX_BTMAP_END));
Ingo Molnar0e3a9542008-01-30 13:33:49 +0100729
Thomas Gleixner91eebf42008-01-30 13:34:05 +0100730 printk(KERN_WARNING "FIX_BTMAP_END: %d\n", FIX_BTMAP_END);
731 printk(KERN_WARNING "FIX_BTMAP_BEGIN: %d\n",
732 FIX_BTMAP_BEGIN);
Ingo Molnar0e3a9542008-01-30 13:33:49 +0100733 }
Huang, Ying0947b2f2008-01-30 13:33:44 +0100734}
735
Mark Salter5b7c73e2014-04-07 15:39:49 -0700736void __init __early_set_fixmap(enum fixed_addresses idx,
737 phys_addr_t phys, pgprot_t flags)
Huang, Ying0947b2f2008-01-30 13:33:44 +0100738{
Ian Campbell551889a62008-02-09 23:24:09 +0100739 unsigned long addr = __fix_to_virt(idx);
740 pte_t *pte;
Huang, Ying0947b2f2008-01-30 13:33:44 +0100741
742 if (idx >= __end_of_fixed_addresses) {
743 BUG();
744 return;
745 }
Huang, Yingbeacfaa2008-01-30 13:33:44 +0100746 pte = early_ioremap_pte(addr);
Jeremy Fitzhardinge4583ed52008-06-25 00:19:03 -0400747
Huang, Ying0947b2f2008-01-30 13:33:44 +0100748 if (pgprot_val(flags))
Ian Campbell551889a62008-02-09 23:24:09 +0100749 set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, flags));
Huang, Ying0947b2f2008-01-30 13:33:44 +0100750 else
Jeremy Fitzhardinge4f9c11d2008-06-25 00:19:19 -0400751 pte_clear(&init_mm, addr, pte);
Huang, Ying0947b2f2008-01-30 13:33:44 +0100752 __flush_tlb_one(addr);
753}