Commit 6b70a920 authored by Heiko Carstens's avatar Heiko Carstens Committed by Martin Schwidefsky

s390/memory hotplug: use pfmf instruction to initialize storage keys

Move and rename init_storage_keys() to pageattr.c, so it can also be
used from the sclp memory hotplug code in order to initialize
storage keys.
Signed-off-by: default avatarHeiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 1e466fcf
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
#include <asm/setup.h> #include <asm/setup.h>
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
void storage_key_init_range(unsigned long start, unsigned long end);
static unsigned long pfmf(unsigned long function, unsigned long address) static unsigned long pfmf(unsigned long function, unsigned long address)
{ {
asm volatile( asm volatile(
......
...@@ -777,40 +777,6 @@ static void __init reserve_crashkernel(void) ...@@ -777,40 +777,6 @@ static void __init reserve_crashkernel(void)
#endif #endif
} }
static void __init init_storage_keys(unsigned long start, unsigned long end)
{
unsigned long boundary, function, size;
while (start < end) {
if (MACHINE_HAS_EDAT2) {
/* set storage keys for a 2GB frame */
function = 0x22000 | PAGE_DEFAULT_KEY;
size = 1UL << 31;
boundary = (start + size) & ~(size - 1);
if (boundary <= end) {
do {
start = pfmf(function, start);
} while (start < boundary);
continue;
}
}
if (MACHINE_HAS_EDAT1) {
/* set storage keys for a 1MB frame */
function = 0x21000 | PAGE_DEFAULT_KEY;
size = 1UL << 20;
boundary = (start + size) & ~(size - 1);
if (boundary <= end) {
do {
start = pfmf(function, start);
} while (start < boundary);
continue;
}
}
page_set_storage_key(start, PAGE_DEFAULT_KEY, 0);
start += PAGE_SIZE;
}
}
static void __init setup_memory(void) static void __init setup_memory(void)
{ {
unsigned long bootmap_size; unsigned long bootmap_size;
...@@ -889,7 +855,7 @@ static void __init setup_memory(void) ...@@ -889,7 +855,7 @@ static void __init setup_memory(void)
memblock_add_node(PFN_PHYS(start_chunk), memblock_add_node(PFN_PHYS(start_chunk),
PFN_PHYS(end_chunk - start_chunk), 0); PFN_PHYS(end_chunk - start_chunk), 0);
pfn = max(start_chunk, start_pfn); pfn = max(start_chunk, start_pfn);
init_storage_keys(PFN_PHYS(pfn), PFN_PHYS(end_chunk)); storage_key_init_range(PFN_PHYS(pfn), PFN_PHYS(end_chunk));
} }
psw_set_key(PAGE_DEFAULT_KEY); psw_set_key(PAGE_DEFAULT_KEY);
......
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
# Makefile for the linux s390-specific parts of the memory manager. # Makefile for the linux s390-specific parts of the memory manager.
# #
obj-y := init.o fault.o extmem.o mmap.o vmem.o pgtable.o maccess.o \ obj-y := init.o fault.o extmem.o mmap.o vmem.o pgtable.o maccess.o
page-states.o gup.o extable.o obj-y += page-states.o gup.o extable.o pageattr.o
obj-$(CONFIG_CMM) += cmm.o
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o obj-$(CONFIG_CMM) += cmm.o
obj-$(CONFIG_DEBUG_SET_MODULE_RONX) += pageattr.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
obj-$(CONFIG_S390_PTDUMP) += dump_pagetables.o obj-$(CONFIG_S390_PTDUMP) += dump_pagetables.o
...@@ -2,11 +2,46 @@ ...@@ -2,11 +2,46 @@
* Copyright IBM Corp. 2011 * Copyright IBM Corp. 2011
* Author(s): Jan Glauber <jang@linux.vnet.ibm.com> * Author(s): Jan Glauber <jang@linux.vnet.ibm.com>
*/ */
#include <linux/hugetlb.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/hugetlb.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/page.h>
void storage_key_init_range(unsigned long start, unsigned long end)
{
unsigned long boundary, function, size;
while (start < end) {
if (MACHINE_HAS_EDAT2) {
/* set storage keys for a 2GB frame */
function = 0x22000 | PAGE_DEFAULT_KEY;
size = 1UL << 31;
boundary = (start + size) & ~(size - 1);
if (boundary <= end) {
do {
start = pfmf(function, start);
} while (start < boundary);
continue;
}
}
if (MACHINE_HAS_EDAT1) {
/* set storage keys for a 1MB frame */
function = 0x21000 | PAGE_DEFAULT_KEY;
size = 1UL << 20;
boundary = (start + size) & ~(size - 1);
if (boundary <= end) {
do {
start = pfmf(function, start);
} while (start < boundary);
continue;
}
}
page_set_storage_key(start, PAGE_DEFAULT_KEY, 0);
start += PAGE_SIZE;
}
}
static pte_t *walk_page_table(unsigned long addr) static pte_t *walk_page_table(unsigned long addr)
{ {
......
...@@ -19,10 +19,11 @@ ...@@ -19,10 +19,11 @@
#include <linux/memory.h> #include <linux/memory.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <asm/ctl_reg.h>
#include <asm/chpid.h> #include <asm/chpid.h>
#include <asm/sclp.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/ctl_reg.h> #include <asm/page.h>
#include <asm/sclp.h>
#include "sclp.h" #include "sclp.h"
...@@ -400,17 +401,15 @@ static int do_assign_storage(sclp_cmdw_t cmd, u16 rn) ...@@ -400,17 +401,15 @@ static int do_assign_storage(sclp_cmdw_t cmd, u16 rn)
static int sclp_assign_storage(u16 rn) static int sclp_assign_storage(u16 rn)
{ {
unsigned long long start, address; unsigned long long start;
int rc; int rc;
rc = do_assign_storage(0x000d0001, rn); rc = do_assign_storage(0x000d0001, rn);
if (rc) if (rc)
goto out; return rc;
start = address = rn2addr(rn); start = rn2addr(rn);
for (; address < start + rzm; address += PAGE_SIZE) storage_key_init_range(start, start + rzm);
page_set_storage_key(address, PAGE_DEFAULT_KEY, 0); return 0;
out:
return rc;
} }
static int sclp_unassign_storage(u16 rn) static int sclp_unassign_storage(u16 rn)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment