diff options
Diffstat (limited to 'arch/x86/mm/ioremap.c')
-rw-r--r-- | arch/x86/mm/ioremap.c | 71 |
1 files changed, 45 insertions, 26 deletions
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index 4b6423e7bd21..e500f1df1140 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c | |||
@@ -28,9 +28,11 @@ | |||
28 | 28 | ||
29 | #include "physaddr.h" | 29 | #include "physaddr.h" |
30 | 30 | ||
31 | struct ioremap_mem_flags { | 31 | /* |
32 | bool system_ram; | 32 | * Descriptor controlling ioremap() behavior. |
33 | bool desc_other; | 33 | */ |
34 | struct ioremap_desc { | ||
35 | unsigned int flags; | ||
34 | }; | 36 | }; |
35 | 37 | ||
36 | /* | 38 | /* |
@@ -62,13 +64,14 @@ int ioremap_change_attr(unsigned long vaddr, unsigned long size, | |||
62 | return err; | 64 | return err; |
63 | } | 65 | } |
64 | 66 | ||
65 | static bool __ioremap_check_ram(struct resource *res) | 67 | /* Does the range (or a subset of) contain normal RAM? */ |
68 | static unsigned int __ioremap_check_ram(struct resource *res) | ||
66 | { | 69 | { |
67 | unsigned long start_pfn, stop_pfn; | 70 | unsigned long start_pfn, stop_pfn; |
68 | unsigned long i; | 71 | unsigned long i; |
69 | 72 | ||
70 | if ((res->flags & IORESOURCE_SYSTEM_RAM) != IORESOURCE_SYSTEM_RAM) | 73 | if ((res->flags & IORESOURCE_SYSTEM_RAM) != IORESOURCE_SYSTEM_RAM) |
71 | return false; | 74 | return 0; |
72 | 75 | ||
73 | start_pfn = (res->start + PAGE_SIZE - 1) >> PAGE_SHIFT; | 76 | start_pfn = (res->start + PAGE_SIZE - 1) >> PAGE_SHIFT; |
74 | stop_pfn = (res->end + 1) >> PAGE_SHIFT; | 77 | stop_pfn = (res->end + 1) >> PAGE_SHIFT; |
@@ -76,28 +79,44 @@ static bool __ioremap_check_ram(struct resource *res) | |||
76 | for (i = 0; i < (stop_pfn - start_pfn); ++i) | 79 | for (i = 0; i < (stop_pfn - start_pfn); ++i) |
77 | if (pfn_valid(start_pfn + i) && | 80 | if (pfn_valid(start_pfn + i) && |
78 | !PageReserved(pfn_to_page(start_pfn + i))) | 81 | !PageReserved(pfn_to_page(start_pfn + i))) |
79 | return true; | 82 | return IORES_MAP_SYSTEM_RAM; |
80 | } | 83 | } |
81 | 84 | ||
82 | return false; | 85 | return 0; |
83 | } | 86 | } |
84 | 87 | ||
85 | static int __ioremap_check_desc_other(struct resource *res) | 88 | /* |
89 | * In a SEV guest, NONE and RESERVED should not be mapped encrypted because | ||
90 | * there the whole memory is already encrypted. | ||
91 | */ | ||
92 | static unsigned int __ioremap_check_encrypted(struct resource *res) | ||
86 | { | 93 | { |
87 | return (res->desc != IORES_DESC_NONE); | 94 | if (!sev_active()) |
95 | return 0; | ||
96 | |||
97 | switch (res->desc) { | ||
98 | case IORES_DESC_NONE: | ||
99 | case IORES_DESC_RESERVED: | ||
100 | break; | ||
101 | default: | ||
102 | return IORES_MAP_ENCRYPTED; | ||
103 | } | ||
104 | |||
105 | return 0; | ||
88 | } | 106 | } |
89 | 107 | ||
90 | static int __ioremap_res_check(struct resource *res, void *arg) | 108 | static int __ioremap_collect_map_flags(struct resource *res, void *arg) |
91 | { | 109 | { |
92 | struct ioremap_mem_flags *flags = arg; | 110 | struct ioremap_desc *desc = arg; |
93 | 111 | ||
94 | if (!flags->system_ram) | 112 | if (!(desc->flags & IORES_MAP_SYSTEM_RAM)) |
95 | flags->system_ram = __ioremap_check_ram(res); | 113 | desc->flags |= __ioremap_check_ram(res); |
96 | 114 | ||
97 | if (!flags->desc_other) | 115 | if (!(desc->flags & IORES_MAP_ENCRYPTED)) |
98 | flags->desc_other = __ioremap_check_desc_other(res); | 116 | desc->flags |= __ioremap_check_encrypted(res); |
99 | 117 | ||
100 | return flags->system_ram && flags->desc_other; | 118 | return ((desc->flags & (IORES_MAP_SYSTEM_RAM | IORES_MAP_ENCRYPTED)) == |
119 | (IORES_MAP_SYSTEM_RAM | IORES_MAP_ENCRYPTED)); | ||
101 | } | 120 | } |
102 | 121 | ||
103 | /* | 122 | /* |
@@ -106,15 +125,15 @@ static int __ioremap_res_check(struct resource *res, void *arg) | |||
106 | * resource described not as IORES_DESC_NONE (e.g. IORES_DESC_ACPI_TABLES). | 125 | * resource described not as IORES_DESC_NONE (e.g. IORES_DESC_ACPI_TABLES). |
107 | */ | 126 | */ |
108 | static void __ioremap_check_mem(resource_size_t addr, unsigned long size, | 127 | static void __ioremap_check_mem(resource_size_t addr, unsigned long size, |
109 | struct ioremap_mem_flags *flags) | 128 | struct ioremap_desc *desc) |
110 | { | 129 | { |
111 | u64 start, end; | 130 | u64 start, end; |
112 | 131 | ||
113 | start = (u64)addr; | 132 | start = (u64)addr; |
114 | end = start + size - 1; | 133 | end = start + size - 1; |
115 | memset(flags, 0, sizeof(*flags)); | 134 | memset(desc, 0, sizeof(struct ioremap_desc)); |
116 | 135 | ||
117 | walk_mem_res(start, end, flags, __ioremap_res_check); | 136 | walk_mem_res(start, end, desc, __ioremap_collect_map_flags); |
118 | } | 137 | } |
119 | 138 | ||
120 | /* | 139 | /* |
@@ -131,15 +150,15 @@ static void __ioremap_check_mem(resource_size_t addr, unsigned long size, | |||
131 | * have to convert them into an offset in a page-aligned mapping, but the | 150 | * have to convert them into an offset in a page-aligned mapping, but the |
132 | * caller shouldn't need to know that small detail. | 151 | * caller shouldn't need to know that small detail. |
133 | */ | 152 | */ |
134 | static void __iomem *__ioremap_caller(resource_size_t phys_addr, | 153 | static void __iomem * |
135 | unsigned long size, enum page_cache_mode pcm, | 154 | __ioremap_caller(resource_size_t phys_addr, unsigned long size, |
136 | void *caller, bool encrypted) | 155 | enum page_cache_mode pcm, void *caller, bool encrypted) |
137 | { | 156 | { |
138 | unsigned long offset, vaddr; | 157 | unsigned long offset, vaddr; |
139 | resource_size_t last_addr; | 158 | resource_size_t last_addr; |
140 | const resource_size_t unaligned_phys_addr = phys_addr; | 159 | const resource_size_t unaligned_phys_addr = phys_addr; |
141 | const unsigned long unaligned_size = size; | 160 | const unsigned long unaligned_size = size; |
142 | struct ioremap_mem_flags mem_flags; | 161 | struct ioremap_desc io_desc; |
143 | struct vm_struct *area; | 162 | struct vm_struct *area; |
144 | enum page_cache_mode new_pcm; | 163 | enum page_cache_mode new_pcm; |
145 | pgprot_t prot; | 164 | pgprot_t prot; |
@@ -158,12 +177,12 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr, | |||
158 | return NULL; | 177 | return NULL; |
159 | } | 178 | } |
160 | 179 | ||
161 | __ioremap_check_mem(phys_addr, size, &mem_flags); | 180 | __ioremap_check_mem(phys_addr, size, &io_desc); |
162 | 181 | ||
163 | /* | 182 | /* |
164 | * Don't allow anybody to remap normal RAM that we're using.. | 183 | * Don't allow anybody to remap normal RAM that we're using.. |
165 | */ | 184 | */ |
166 | if (mem_flags.system_ram) { | 185 | if (io_desc.flags & IORES_MAP_SYSTEM_RAM) { |
167 | WARN_ONCE(1, "ioremap on RAM at %pa - %pa\n", | 186 | WARN_ONCE(1, "ioremap on RAM at %pa - %pa\n", |
168 | &phys_addr, &last_addr); | 187 | &phys_addr, &last_addr); |
169 | return NULL; | 188 | return NULL; |
@@ -201,7 +220,7 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr, | |||
201 | * resulting mapping. | 220 | * resulting mapping. |
202 | */ | 221 | */ |
203 | prot = PAGE_KERNEL_IO; | 222 | prot = PAGE_KERNEL_IO; |
204 | if ((sev_active() && mem_flags.desc_other) || encrypted) | 223 | if ((io_desc.flags & IORES_MAP_ENCRYPTED) || encrypted) |
205 | prot = pgprot_encrypted(prot); | 224 | prot = pgprot_encrypted(prot); |
206 | 225 | ||
207 | switch (pcm) { | 226 | switch (pcm) { |