Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

s390/mm: make hugepages_supported a boot time decision

There is a potential bug with KVM and hugetlbfs if the hardware does not
support hugepages (EDAT1). We fix this by making EDAT1 a hard requirement
for hugepages and therefore removing and simplifying code.

As s390, with the sw-emulated hugepages, was the only user of
arch_prepare/release_hugepage I also removed theses calls from common and
other architecture code.

This patch (of 5):

By dropping support for hugepages on machines which do not have the
hardware feature EDAT1, we fix a potential s390 KVM bug.

The bug would happen if a guest is backed by hugetlbfs (not supported
currently), but does not get pagetables with PGSTE. This would lead to
random memory overwrites.

Signed-off-by: Dominik Dingel <dingel@linux.vnet.ibm.com>
Acked-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Dominik Dingel and committed by
Linus Torvalds
bea41197 aefbef10

+8 -4
+4 -4
arch/s390/include/asm/page.h
··· 17 17 #define PAGE_DEFAULT_ACC 0 18 18 #define PAGE_DEFAULT_KEY (PAGE_DEFAULT_ACC << 4) 19 19 20 - #define HPAGE_SHIFT 20 20 + #include <asm/setup.h> 21 + #ifndef __ASSEMBLY__ 22 + 23 + extern unsigned int HPAGE_SHIFT; 21 24 #define HPAGE_SIZE (1UL << HPAGE_SHIFT) 22 25 #define HPAGE_MASK (~(HPAGE_SIZE - 1)) 23 26 #define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) ··· 29 26 #define ARCH_HAS_HUGE_PTE_TYPE 30 27 #define ARCH_HAS_PREPARE_HUGEPAGE 31 28 #define ARCH_HAS_HUGEPAGE_CLEAR_FLUSH 32 - 33 - #include <asm/setup.h> 34 - #ifndef __ASSEMBLY__ 35 29 36 30 static inline void storage_key_init_range(unsigned long start, unsigned long end) 37 31 {
+2
arch/s390/kernel/setup.c
··· 880 880 */ 881 881 setup_hwcaps(); 882 882 883 + HPAGE_SHIFT = MACHINE_HAS_HPAGE ? 20 : 0; 884 + 883 885 /* 884 886 * Create kernel page tables and switch to virtual addressing. 885 887 */
+2
arch/s390/mm/pgtable.c
··· 31 31 #define ALLOC_ORDER 2 32 32 #define FRAG_MASK 0x03 33 33 34 + unsigned int HPAGE_SHIFT; 35 + 34 36 unsigned long *crst_table_alloc(struct mm_struct *mm) 35 37 { 36 38 struct page *page = alloc_pages(GFP_KERNEL, ALLOC_ORDER);