diff options
Diffstat (limited to 'arch/s390/include/asm/page-states.h')
-rw-r--r-- | arch/s390/include/asm/page-states.h | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/arch/s390/include/asm/page-states.h b/arch/s390/include/asm/page-states.h index 659e3c963ce6..1eae4046c07d 100644 --- a/arch/s390/include/asm/page-states.h +++ b/arch/s390/include/asm/page-states.h @@ -8,6 +8,7 @@ #define PAGE_STATES_H #include <asm/sections.h> +#include <asm/page.h> #define ESSA_GET_STATE 0 #define ESSA_SET_STABLE 1 @@ -22,4 +23,41 @@ extern int __bootdata_preserved(cmma_flag); +static __always_inline unsigned long essa(unsigned long paddr, unsigned char cmd) +{ + unsigned long rc; + + asm volatile( + " .insn rrf,0xb9ab0000,%[rc],%[paddr],%[cmd],0" + : [rc] "=d" (rc) + : [paddr] "d" (paddr), + [cmd] "i" (cmd)); + return rc; +} + +static __always_inline void __set_page_state(void *addr, unsigned long num_pages, unsigned char cmd) +{ + unsigned long paddr = __pa(addr) & PAGE_MASK; + + while (num_pages--) { + essa(paddr, cmd); + paddr += PAGE_SIZE; + } +} + +static inline void __set_page_unused(void *addr, unsigned long num_pages) +{ + __set_page_state(addr, num_pages, ESSA_SET_UNUSED); +} + +static inline void __set_page_stable_dat(void *addr, unsigned long num_pages) +{ + __set_page_state(addr, num_pages, ESSA_SET_STABLE); +} + +static inline void __set_page_stable_nodat(void *addr, unsigned long num_pages) +{ + __set_page_state(addr, num_pages, ESSA_SET_STABLE_NODAT); +} + #endif |