From: Ma Wupeng mawupeng1@huawei.com
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I7ZC0H
--------------------------------
Introduce kernel param pbha to control the overall PBHA and PBHA bit0 behavior. If pbha is added in bootarg, PBHA and PBHA bit 0 will be initialized.
For PBHA bit 0, it accepts the following arg:
enable: kernel and user will update PBHA bit0 for their pte entry. user: only select user task will update PBHA bit0 for pte entry.
Signed-off-by: Ma Wupeng mawupeng1@huawei.com --- .../admin-guide/kernel-parameters.txt | 8 +++++++ .../firmware/efi/libstub/efi-stub-helper.c | 3 +++ drivers/firmware/efi/libstub/fdt.c | 5 +++++ drivers/soc/hisilicon/pbha.c | 22 ++++++++++++++++++- include/linux/pbha.h | 6 +++-- 5 files changed, 41 insertions(+), 3 deletions(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 71567aa7eca9..eab29f749a5f 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -6446,3 +6446,11 @@ memory, and other data can't be written using xmon commands. off xmon is disabled. + + pbha= [ARM64] + Format: { enable | user } + Enabled PBHA bit0. + enable kernel and user will update PBHA bit0 for their + pte entry. + user only select user task will update PBHA bit0 for + their pte entry. diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c index 537db49c31b9..8670654bf561 100644 --- a/drivers/firmware/efi/libstub/efi-stub-helper.c +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c @@ -23,6 +23,7 @@ bool efi_nokaslr = !IS_ENABLED(CONFIG_RANDOMIZE_BASE); bool efi_noinitrd; int efi_loglevel = CONSOLE_LOGLEVEL_DEFAULT; bool efi_novamap = IS_ENABLED(CONFIG_LOONGARCH); /* LoongArch call svam() in kernel */; +bool efi_pbha;
static bool efi_nosoftreserve; static bool efi_disable_pci_dma = IS_ENABLED(CONFIG_EFI_DISABLE_PCI_DMA); @@ -234,6 +235,8 @@ efi_status_t efi_parse_options(char const *cmdline) efi_parse_option_graphics(val + strlen("efifb:")); } else if (!strcmp(param, "memmap") && val) { efi_parse_option_memmap(val); + } else if (!strcmp(param, "pbha")) { + efi_pbha = true; } } efi_bs_call(free_pool, buf); diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c index d212bd2ad418..cb8e8e4e3f63 100644 --- a/drivers/firmware/efi/libstub/fdt.c +++ b/drivers/firmware/efi/libstub/fdt.c @@ -29,6 +29,8 @@ static void fdt_update_cell_size(void *fdt) }
#ifdef CONFIG_ARM64_PBHA +extern bool efi_pbha; + static efi_status_t fdt_init_hbm_mode(void *fdt, int node) { efi_guid_t oem_config_guid = EFI_OEMCONFIG_VARIABLE_GUID; @@ -39,6 +41,9 @@ static efi_status_t fdt_init_hbm_mode(void *fdt, int node) u8 fdt_val32; u8 arr[16] = { 0x1 };
+ if (!efi_pbha) + goto out; + efi_status = get_efi_var(L"HBMMode", &oem_config_guid, NULL, &size, &hbm_mode); if (efi_status != EFI_SUCCESS) diff --git a/drivers/soc/hisilicon/pbha.c b/drivers/soc/hisilicon/pbha.c index d26f2c32cecb..8914ebbca4cf 100644 --- a/drivers/soc/hisilicon/pbha.c +++ b/drivers/soc/hisilicon/pbha.c @@ -18,6 +18,8 @@ #define HBM_MODE_CACHE 1
bool __ro_after_init pbha_bit0_enabled; +bool __ro_after_init pbha_bit0_kernel_enabled; +static bool pbha_enabled_phase_1;
void __init early_pbha_bit0_init(void) { @@ -41,7 +43,7 @@ void __init early_pbha_bit0_init(void) if (!prop) return; if (*prop == HBM_MODE_CACHE) - pbha_bit0_enabled = true; + pbha_enabled_phase_1 = true; }
#define pte_pbha_bit0(pte) \ @@ -182,3 +184,21 @@ int pbha_bit0_update_vma(struct mm_struct *mm, int val) mmap_write_unlock(mm); return 0; } + +static int __init setup_pbha(char *str) +{ + if (!pbha_enabled_phase_1) + return 0; + + if (strcmp(str, "enable") == 0) { + pbha_bit0_enabled = true; + pbha_bit0_kernel_enabled = true; + } else if (strcmp(str, "user") == 0) { + pbha_bit0_enabled = true; + } + + pr_info("pbha bit_0 enabled, kernel: %d\n", pbha_bit0_kernel_enabled); + + return 0; +} +early_param("pbha", setup_pbha); diff --git a/include/linux/pbha.h b/include/linux/pbha.h index f6b764ae3fa7..25cb88aa3d1c 100644 --- a/include/linux/pbha.h +++ b/include/linux/pbha.h @@ -21,6 +21,7 @@
#ifdef CONFIG_ARM64_PBHA extern bool __ro_after_init pbha_bit0_enabled; +extern bool __ro_after_init pbha_bit0_kernel_enabled; extern struct mm_walk_ops pbha_bit0_walk_ops; extern void __init early_pbha_bit0_init(void); extern int pbha_bit0_update_vma(struct mm_struct *mm, int val); @@ -32,7 +33,7 @@ static inline bool system_support_pbha_bit0(void)
static inline pgprot_t pgprot_pbha_bit0(pgprot_t prot) { - if (!system_support_pbha_bit0()) + if (!system_support_pbha_bit0() || !pbha_bit0_kernel_enabled) return prot;
return pgprot_pbha(prot, PBHA_VAL_BIT0); @@ -43,7 +44,8 @@ static inline pte_t maybe_mk_pbha_bit0(pte_t pte, struct vm_area_struct *vma) if (!system_support_pbha_bit0()) return pte;
- if (unlikely(is_global_init(current)) && + /* global init task will update pbha bit0 iff kernel can do this */ + if (unlikely(is_global_init(current)) && pbha_bit0_kernel_enabled && !(vma->vm_flags & VM_PBHA_BIT0)) vma->vm_flags |= VM_PBHA_BIT0;