aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/mm/ioremap.c71
-rw-r--r--include/linux/ioport.h9
2 files changed, 54 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
31struct ioremap_mem_flags { 31/*
32 bool system_ram; 32 * Descriptor controlling ioremap() behavior.
33 bool desc_other; 33 */
34struct 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
65static bool __ioremap_check_ram(struct resource *res) 67/* Does the range (or a subset of) contain normal RAM? */
68static 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
85static 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 */
92static 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
90static int __ioremap_res_check(struct resource *res, void *arg) 108static 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 */
108static void __ioremap_check_mem(resource_size_t addr, unsigned long size, 127static 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 */
134static void __iomem *__ioremap_caller(resource_size_t phys_addr, 153static 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) {
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 6ed59de48bd5..5db386cfc2d4 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -12,6 +12,7 @@
12#ifndef __ASSEMBLY__ 12#ifndef __ASSEMBLY__
13#include <linux/compiler.h> 13#include <linux/compiler.h>
14#include <linux/types.h> 14#include <linux/types.h>
15#include <linux/bits.h>
15/* 16/*
16 * Resources are tree-like, allowing 17 * Resources are tree-like, allowing
17 * nesting etc.. 18 * nesting etc..
@@ -136,6 +137,14 @@ enum {
136 IORES_DESC_RESERVED = 8, 137 IORES_DESC_RESERVED = 8,
137}; 138};
138 139
140/*
141 * Flags controlling ioremap() behavior.
142 */
143enum {
144 IORES_MAP_SYSTEM_RAM = BIT(0),
145 IORES_MAP_ENCRYPTED = BIT(1),
146};
147
139/* helpers to define resources */ 148/* helpers to define resources */
140#define DEFINE_RES_NAMED(_start, _size, _name, _flags) \ 149#define DEFINE_RES_NAMED(_start, _size, _name, _flags) \
141 { \ 150 { \