Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 58b7e200 authored by Janosch Frank's avatar Janosch Frank
Browse files

s390/mm: Add gmap pmd linking



Let's allow pmds to be linked into gmap for the upcoming s390 KVM huge
page support.

Before this patch we copied the full userspace pmd entry. This is not
correct, as it contains SW defined bits that might be interpreted
differently in the GMAP context. Now we only copy over all hardware
relevant information leaving out the software bits.

Signed-off-by: default avatarJanosch Frank <frankja@linux.ibm.com>
Reviewed-by: default avatarDavid Hildenbrand <david@redhat.com>
parent 2c46e974
Loading
Loading
Loading
Loading
+4 −2
Original line number Original line Diff line number Diff line
@@ -270,6 +270,8 @@ static inline int is_module_addr(void *addr)
/* Bits in the segment table entry */
/* Bits in the segment table entry */
#define _SEGMENT_ENTRY_BITS			0xfffffffffffffe33UL
#define _SEGMENT_ENTRY_BITS			0xfffffffffffffe33UL
#define _SEGMENT_ENTRY_BITS_LARGE		0xfffffffffff0ff33UL
#define _SEGMENT_ENTRY_BITS_LARGE		0xfffffffffff0ff33UL
#define _SEGMENT_ENTRY_HARDWARE_BITS		0xfffffffffffffe30UL
#define _SEGMENT_ENTRY_HARDWARE_BITS_LARGE	0xfffffffffff00730UL
#define _SEGMENT_ENTRY_ORIGIN_LARGE ~0xfffffUL /* large page address	    */
#define _SEGMENT_ENTRY_ORIGIN_LARGE ~0xfffffUL /* large page address	    */
#define _SEGMENT_ENTRY_ORIGIN	~0x7ffUL/* page table origin		    */
#define _SEGMENT_ENTRY_ORIGIN	~0x7ffUL/* page table origin		    */
#define _SEGMENT_ENTRY_PROTECT	0x200	/* segment protection bit	    */
#define _SEGMENT_ENTRY_PROTECT	0x200	/* segment protection bit	    */
+9 −4
Original line number Original line Diff line number Diff line
@@ -596,10 +596,15 @@ int __gmap_link(struct gmap *gmap, unsigned long gaddr, unsigned long vmaddr)
	if (*table == _SEGMENT_ENTRY_EMPTY) {
	if (*table == _SEGMENT_ENTRY_EMPTY) {
		rc = radix_tree_insert(&gmap->host_to_guest,
		rc = radix_tree_insert(&gmap->host_to_guest,
				       vmaddr >> PMD_SHIFT, table);
				       vmaddr >> PMD_SHIFT, table);
		if (!rc)
		if (!rc) {
			*table = pmd_val(*pmd);
			if (pmd_large(*pmd)) {
				*table = pmd_val(*pmd) &
					_SEGMENT_ENTRY_HARDWARE_BITS_LARGE;
			} else
			} else
		rc = 0;
				*table = pmd_val(*pmd) &
					_SEGMENT_ENTRY_HARDWARE_BITS;
		}
	}
	spin_unlock(&gmap->guest_table_lock);
	spin_unlock(&gmap->guest_table_lock);
	spin_unlock(ptl);
	spin_unlock(ptl);
	radix_tree_preload_end();
	radix_tree_preload_end();