aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/include/asm/pgtable.h
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2016-03-08 06:12:18 -0500
committerChristian Borntraeger <borntraeger@de.ibm.com>2016-06-20 03:54:04 -0400
commit4be130a08420d6918d80c1067f8078f425eb98df (patch)
treec3e323bf6597eea8e588586550e378acf7652ce2 /arch/s390/include/asm/pgtable.h
parent6ea427bbbd4078297bb1dbd6c5cb83f3f48aac46 (diff)
s390/mm: add shadow gmap support
For a nested KVM guest the outer KVM host needs to create shadow page tables for the nested guest. This patch adds the basic support to the guest address space (gmap) code. For each guest address space the inner KVM host creates, the first outer KVM host needs to create shadow page tables. The address space is identified by the ASCE loaded into the control register 1 at the time the inner SIE instruction for the second nested KVM guest is executed. The outer KVM host creates the shadow tables starting with the table identified by the ASCE on a on-demand basis. The outer KVM host will get repeated faults for all the shadow tables needed to run the second KVM guest. While a shadow page table for the second KVM guest is active the access to the origin region, segment and page tables needs to be restricted for the first KVM guest. For region and segment and page tables the first KVM guest may read the memory, but write attempt has to lead to an unshadow. This is done using the page invalid and read-only bits in the page table of the first KVM guest. If the first guest re-accesses one of the origin pages of a shadow, it gets a fault and the affected parts of the shadow page table hierarchy needs to be removed again. PGSTE tables don't have to be shadowed, as all interpretation assist can't deal with the invalid bits in the shadow pte being set differently than the original ones provided by the first KVM guest. Many bug fixes and improvements by David Hildenbrand. Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'arch/s390/include/asm/pgtable.h')
-rw-r--r--arch/s390/include/asm/pgtable.h10
1 files changed, 8 insertions, 2 deletions
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index 35dde6afffcf..a6e7fc8f5b49 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -256,6 +256,7 @@ static inline int is_module_addr(void *addr)
256/* Bits in the region table entry */ 256/* Bits in the region table entry */
257#define _REGION_ENTRY_ORIGIN ~0xfffUL/* region/segment table origin */ 257#define _REGION_ENTRY_ORIGIN ~0xfffUL/* region/segment table origin */
258#define _REGION_ENTRY_PROTECT 0x200 /* region protection bit */ 258#define _REGION_ENTRY_PROTECT 0x200 /* region protection bit */
259#define _REGION_ENTRY_OFFSET 0xc0 /* region table offset */
259#define _REGION_ENTRY_INVALID 0x20 /* invalid region table entry */ 260#define _REGION_ENTRY_INVALID 0x20 /* invalid region table entry */
260#define _REGION_ENTRY_TYPE_MASK 0x0c /* region/segment table type mask */ 261#define _REGION_ENTRY_TYPE_MASK 0x0c /* region/segment table type mask */
261#define _REGION_ENTRY_TYPE_R1 0x0c /* region first table type */ 262#define _REGION_ENTRY_TYPE_R1 0x0c /* region first table type */
@@ -327,6 +328,7 @@ static inline int is_module_addr(void *addr)
327#define PGSTE_GC_BIT 0x0002000000000000UL 328#define PGSTE_GC_BIT 0x0002000000000000UL
328#define PGSTE_UC_BIT 0x0000800000000000UL /* user dirty (migration) */ 329#define PGSTE_UC_BIT 0x0000800000000000UL /* user dirty (migration) */
329#define PGSTE_IN_BIT 0x0000400000000000UL /* IPTE notify bit */ 330#define PGSTE_IN_BIT 0x0000400000000000UL /* IPTE notify bit */
331#define PGSTE_VSIE_BIT 0x0000200000000000UL /* ref'd in a shadow table */
330 332
331/* Guest Page State used for virtualization */ 333/* Guest Page State used for virtualization */
332#define _PGSTE_GPS_ZERO 0x0000000080000000UL 334#define _PGSTE_GPS_ZERO 0x0000000080000000UL
@@ -885,12 +887,16 @@ static inline int ptep_set_access_flags(struct vm_area_struct *vma,
885void ptep_set_pte_at(struct mm_struct *mm, unsigned long addr, 887void ptep_set_pte_at(struct mm_struct *mm, unsigned long addr,
886 pte_t *ptep, pte_t entry); 888 pte_t *ptep, pte_t entry);
887void ptep_set_notify(struct mm_struct *mm, unsigned long addr, pte_t *ptep); 889void ptep_set_notify(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
888void ptep_notify(struct mm_struct *mm, unsigned long addr, pte_t *ptep); 890void ptep_notify(struct mm_struct *mm, unsigned long addr,
891 pte_t *ptep, unsigned long bits);
889int ptep_force_prot(struct mm_struct *mm, unsigned long gaddr, 892int ptep_force_prot(struct mm_struct *mm, unsigned long gaddr,
890 pte_t *ptep, int prot); 893 pte_t *ptep, int prot, unsigned long bit);
891void ptep_zap_unused(struct mm_struct *mm, unsigned long addr, 894void ptep_zap_unused(struct mm_struct *mm, unsigned long addr,
892 pte_t *ptep , int reset); 895 pte_t *ptep , int reset);
893void ptep_zap_key(struct mm_struct *mm, unsigned long addr, pte_t *ptep); 896void ptep_zap_key(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
897int ptep_shadow_pte(struct mm_struct *mm, unsigned long saddr,
898 pte_t *sptep, pte_t *tptep, int write);
899void ptep_unshadow_pte(struct mm_struct *mm, unsigned long saddr, pte_t *ptep);
894 900
895bool test_and_clear_guest_dirty(struct mm_struct *mm, unsigned long address); 901bool test_and_clear_guest_dirty(struct mm_struct *mm, unsigned long address);
896int set_guest_storage_key(struct mm_struct *mm, unsigned long addr, 902int set_guest_storage_key(struct mm_struct *mm, unsigned long addr,