s390/cpufeature: Convert MACHINE_HAS_EDAT1 to cpu_has_edat1()

Convert MACHINE_HAS_... to cpu_has_...() which uses test_facility() instead
of testing the machine_flags lowcore member if the feature is present.

test_facility() generates better code since it results in a static branch
without accessing memory. The branch is patched via alternatives by the
decompressor depending on the availability of the required facility.

Reviewed-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
This commit is contained in:
Heiko Carstens
2025-02-07 15:48:53 +01:00
committed by Vasily Gorbik
parent 5643195f26
commit 2e2ff71feb
13 changed files with 17 additions and 20 deletions

View File

@@ -12,7 +12,6 @@
#include <asm/physmem_info.h>
struct machine_info {
unsigned char has_edat1 : 1;
unsigned char has_edat2 : 1;
};

View File

@@ -50,10 +50,8 @@ void error(char *x)
static void detect_facilities(void)
{
if (test_facility(8)) {
machine.has_edat1 = 1;
if (cpu_has_edat1())
local_ctl_set_bit(0, CR0_EDAT_BIT);
}
if (test_facility(78))
machine.has_edat2 = 1;
page_noexec_mask = -1UL;

View File

@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#define boot_fmt(fmt) "vmem: " fmt
#include <linux/cpufeature.h>
#include <linux/sched/task.h>
#include <linux/pgtable.h>
#include <linux/kasan.h>
@@ -330,7 +331,7 @@ static unsigned long try_get_large_pmd_pa(pmd_t *pm_dir, unsigned long addr, uns
{
unsigned long pa, size = end - addr;
if (!machine.has_edat1 || !large_page_mapping_allowed(mode) ||
if (!cpu_has_edat1() || !large_page_mapping_allowed(mode) ||
!IS_ALIGNED(addr, PMD_SIZE) || (size < PMD_SIZE))
return INVALID_PHYS_ADDR;

View File

@@ -22,6 +22,7 @@ enum {
int cpu_have_feature(unsigned int nr);
#define cpu_has_edat1() test_facility(8)
#define cpu_has_gs() test_facility(133)
#define cpu_has_nx() test_facility(130)
#define cpu_has_rdp() test_facility(194)

View File

@@ -9,12 +9,13 @@
#ifndef _ASM_S390_HUGETLB_H
#define _ASM_S390_HUGETLB_H
#include <linux/cpufeature.h>
#include <linux/pgtable.h>
#include <linux/swap.h>
#include <linux/swapops.h>
#include <asm/page.h>
#define hugepages_supported() (MACHINE_HAS_EDAT1)
#define hugepages_supported() cpu_has_edat1()
#define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT
void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,

View File

@@ -1891,7 +1891,7 @@ static inline int pmd_trans_huge(pmd_t pmd)
#define has_transparent_hugepage has_transparent_hugepage
static inline int has_transparent_hugepage(void)
{
return MACHINE_HAS_EDAT1 ? 1 : 0;
return cpu_has_edat1() ? 1 : 0;
}
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */

View File

@@ -23,7 +23,6 @@
#define MACHINE_FLAG_DIAG9C BIT(3)
#define MACHINE_FLAG_ESOP BIT(4)
#define MACHINE_FLAG_IDTE BIT(5)
#define MACHINE_FLAG_EDAT1 BIT(7)
#define MACHINE_FLAG_EDAT2 BIT(8)
#define MACHINE_FLAG_TE BIT(11)
#define MACHINE_FLAG_TLB_GUEST BIT(14)
@@ -79,7 +78,6 @@ extern unsigned long mio_wb_bit_mask;
#define MACHINE_HAS_DIAG9C (get_lowcore()->machine_flags & MACHINE_FLAG_DIAG9C)
#define MACHINE_HAS_ESOP (get_lowcore()->machine_flags & MACHINE_FLAG_ESOP)
#define MACHINE_HAS_IDTE (get_lowcore()->machine_flags & MACHINE_FLAG_IDTE)
#define MACHINE_HAS_EDAT1 (get_lowcore()->machine_flags & MACHINE_FLAG_EDAT1)
#define MACHINE_HAS_EDAT2 (get_lowcore()->machine_flags & MACHINE_FLAG_EDAT2)
#define MACHINE_HAS_TE (get_lowcore()->machine_flags & MACHINE_FLAG_TE)
#define MACHINE_HAS_TLB_GUEST (get_lowcore()->machine_flags & MACHINE_FLAG_TLB_GUEST)

View File

@@ -237,10 +237,6 @@ static __init void detect_diag9c(void)
static __init void detect_machine_facilities(void)
{
if (test_facility(8)) {
get_lowcore()->machine_flags |= MACHINE_FLAG_EDAT1;
system_ctl_set_bit(0, CR0_EDAT_BIT);
}
if (test_facility(78))
get_lowcore()->machine_flags |= MACHINE_FLAG_EDAT2;
if (test_facility(3))

View File

@@ -210,7 +210,7 @@ static int __init setup_hwcaps(void)
elf_hwcap |= HWCAP_DFP;
/* huge page support */
if (MACHINE_HAS_EDAT1)
if (cpu_has_edat1())
elf_hwcap |= HWCAP_HPAGE;
/* 64-bit register support for 31-bit processes */

View File

@@ -9,12 +9,13 @@
#define KMSG_COMPONENT "hugetlb"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#include <asm/pgalloc.h>
#include <linux/cpufeature.h>
#include <linux/mm.h>
#include <linux/hugetlb.h>
#include <linux/mman.h>
#include <linux/sched/mm.h>
#include <linux/security.h>
#include <asm/pgalloc.h>
/*
* If the bit selected by single-bit bitmask "a" is set within "x", move
@@ -248,7 +249,7 @@ pte_t *huge_pte_offset(struct mm_struct *mm,
bool __init arch_hugetlb_valid_size(unsigned long size)
{
if (MACHINE_HAS_EDAT1 && size == PMD_SIZE)
if (cpu_has_edat1() && size == PMD_SIZE)
return true;
else if (MACHINE_HAS_EDAT2 && size == PUD_SIZE)
return true;

View File

@@ -28,7 +28,7 @@ void __storage_key_init_range(unsigned long start, unsigned long end)
unsigned long boundary, size;
while (start < end) {
if (MACHINE_HAS_EDAT1) {
if (cpu_has_edat1()) {
/* set storage keys for a 1MB frame */
size = 1UL << 20;
boundary = (start + size) & ~(size - 1);

View File

@@ -4,6 +4,7 @@
*/
#include <linux/memory_hotplug.h>
#include <linux/cpufeature.h>
#include <linux/memblock.h>
#include <linux/pfn.h>
#include <linux/mm.h>
@@ -249,12 +250,12 @@ static int __ref modify_pmd_table(pud_t *pud, unsigned long addr,
} else if (pmd_none(*pmd)) {
if (IS_ALIGNED(addr, PMD_SIZE) &&
IS_ALIGNED(next, PMD_SIZE) &&
MACHINE_HAS_EDAT1 && direct &&
cpu_has_edat1() && direct &&
!debug_pagealloc_enabled()) {
set_pmd(pmd, __pmd(__pa(addr) | prot));
pages++;
continue;
} else if (!direct && MACHINE_HAS_EDAT1) {
} else if (!direct && cpu_has_edat1()) {
void *new_page;
/*

View File

@@ -8,6 +8,7 @@
#define KMSG_COMPONENT "sclp_cmd"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#include <linux/cpufeature.h>
#include <linux/completion.h>
#include <linux/init.h>
#include <linux/errno.h>
@@ -428,7 +429,7 @@ static void __init add_memory_merged(u16 rn)
goto skip_add;
for (addr = start; addr < start + size; addr += block_size)
add_memory(0, addr, block_size,
MACHINE_HAS_EDAT1 ?
cpu_has_edat1() ?
MHP_MEMMAP_ON_MEMORY | MHP_OFFLINE_INACCESSIBLE : MHP_NONE);
skip_add:
first_rn = rn;