diff options
| -rw-r--r-- | drivers/base/cpu.c | 2 | ||||
| -rw-r--r-- | include/linux/percpu.h | 1 | ||||
| -rw-r--r-- | mm/percpu.c | 22 |
3 files changed, 24 insertions, 1 deletions
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index e62a4ccea54d..69ee5b7517ec 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c | |||
| @@ -97,7 +97,7 @@ static ssize_t show_crash_notes(struct sys_device *dev, struct sysdev_attribute | |||
| 97 | * boot up and this data does not change there after. Hence this | 97 | * boot up and this data does not change there after. Hence this |
| 98 | * operation should be safe. No locking required. | 98 | * operation should be safe. No locking required. |
| 99 | */ | 99 | */ |
| 100 | addr = __pa(per_cpu_ptr(crash_notes, cpunum)); | 100 | addr = per_cpu_ptr_to_phys(per_cpu_ptr(crash_notes, cpunum)); |
| 101 | rc = sprintf(buf, "%Lx\n", addr); | 101 | rc = sprintf(buf, "%Lx\n", addr); |
| 102 | return rc; | 102 | return rc; |
| 103 | } | 103 | } |
diff --git a/include/linux/percpu.h b/include/linux/percpu.h index 878836ca999c..6ac984fa34f8 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h | |||
| @@ -154,6 +154,7 @@ struct percpu_data { | |||
| 154 | 154 | ||
| 155 | extern void *__alloc_percpu(size_t size, size_t align); | 155 | extern void *__alloc_percpu(size_t size, size_t align); |
| 156 | extern void free_percpu(void *__pdata); | 156 | extern void free_percpu(void *__pdata); |
| 157 | extern phys_addr_t per_cpu_ptr_to_phys(void *addr); | ||
| 157 | 158 | ||
| 158 | #ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA | 159 | #ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA |
| 159 | extern void __init setup_per_cpu_areas(void); | 160 | extern void __init setup_per_cpu_areas(void); |
diff --git a/mm/percpu.c b/mm/percpu.c index 5adfc268b408..008fbd9e6fa4 100644 --- a/mm/percpu.c +++ b/mm/percpu.c | |||
| @@ -74,6 +74,7 @@ | |||
| 74 | #include <asm/cacheflush.h> | 74 | #include <asm/cacheflush.h> |
| 75 | #include <asm/sections.h> | 75 | #include <asm/sections.h> |
| 76 | #include <asm/tlbflush.h> | 76 | #include <asm/tlbflush.h> |
| 77 | #include <asm/io.h> | ||
| 77 | 78 | ||
| 78 | #define PCPU_SLOT_BASE_SHIFT 5 /* 1-31 shares the same slot */ | 79 | #define PCPU_SLOT_BASE_SHIFT 5 /* 1-31 shares the same slot */ |
| 79 | #define PCPU_DFL_MAP_ALLOC 16 /* start a map with 16 ents */ | 80 | #define PCPU_DFL_MAP_ALLOC 16 /* start a map with 16 ents */ |
| @@ -1302,6 +1303,27 @@ void free_percpu(void *ptr) | |||
| 1302 | } | 1303 | } |
| 1303 | EXPORT_SYMBOL_GPL(free_percpu); | 1304 | EXPORT_SYMBOL_GPL(free_percpu); |
| 1304 | 1305 | ||
| 1306 | /** | ||
| 1307 | * per_cpu_ptr_to_phys - convert translated percpu address to physical address | ||
| 1308 | * @addr: the address to be converted to physical address | ||
| 1309 | * | ||
| 1310 | * Given @addr which is dereferenceable address obtained via one of | ||
| 1311 | * percpu access macros, this function translates it into its physical | ||
| 1312 | * address. The caller is responsible for ensuring @addr stays valid | ||
| 1313 | * until this function finishes. | ||
| 1314 | * | ||
| 1315 | * RETURNS: | ||
| 1316 | * The physical address for @addr. | ||
| 1317 | */ | ||
| 1318 | phys_addr_t per_cpu_ptr_to_phys(void *addr) | ||
| 1319 | { | ||
| 1320 | if ((unsigned long)addr < VMALLOC_START || | ||
| 1321 | (unsigned long)addr >= VMALLOC_END) | ||
| 1322 | return __pa(addr); | ||
| 1323 | else | ||
| 1324 | return page_to_phys(vmalloc_to_page(addr)); | ||
| 1325 | } | ||
| 1326 | |||
| 1305 | static inline size_t pcpu_calc_fc_sizes(size_t static_size, | 1327 | static inline size_t pcpu_calc_fc_sizes(size_t static_size, |
| 1306 | size_t reserved_size, | 1328 | size_t reserved_size, |
| 1307 | ssize_t *dyn_sizep) | 1329 | ssize_t *dyn_sizep) |
