Commit 0d65528c authored by Ma Wupeng's avatar Ma Wupeng Committed by Wupeng Ma
Browse files

arm64: mm: Detect and enable PBHA bit0 at early startup

hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I7ZC0H



--------------------------------

Enable PBHA bit0 via FDT table at startup. PBHA bit 0 is currently needed
initialized.

Here is an example to enable PBHA bit0 in FDT table:

    cpus {
        arm,pbha-performance-only = <0x01000000 0x00000000 0x00000000 0x00000000>;
    };
    chosen {
        linux,pbha-bit0 = [0/1];
    };

Signed-off-by: default avatarMa Wupeng <mawupeng1@huawei.com>
parent f43933b3
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -1704,6 +1704,12 @@ config ARM64_PBHA
	  The behaviour of each PBHA bit is not defined. Say no unless you
	  are very sure you want this

	  For PBHA_BIT0: It has the following features:
	  a) kernel pte entry will be set PBHA 59 bit during pagetable startup
	  b) Introduce VM_PBHA_BIT0 for feature use.
	  c) User pte entry will be set PBHA 59 bit for vma with VM_PBHA_BIT0.
	  d) Introduce /proc/<pid>/pbha_bit0 to update whole user task.

endmenu

menu "ARMv8.3 architectural features"
+3 −0
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@
#include <linux/cpu.h>
#include <linux/init.h>
#include <linux/libfdt.h>
#include <linux/pbha.h>

#include <asm/cpu.h>
#include <asm/cpufeature.h>
@@ -1755,6 +1756,8 @@ void __init early_pbha_init(void)

	pbha_enabled = true;

	early_pbha_bit0_init();

unlock:
	spin_unlock(&pbha_dt_lock);
}
+52 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@

#include <linux/efi.h>
#include <linux/libfdt.h>
#include <linux/pbha.h>
#include <asm/efi.h>

#include "efistub.h"
@@ -27,6 +28,54 @@ static void fdt_update_cell_size(void *fdt)
	fdt_setprop_u32(fdt, offset, "#size-cells",    EFI_DT_SIZE_CELLS_DEFAULT);
}

#ifdef CONFIG_ARM64_PBHA
static efi_status_t fdt_init_hbm_mode(void *fdt, int node)
{
	efi_guid_t oem_config_guid = EFI_OEMCONFIG_VARIABLE_GUID;
	unsigned long size;
	efi_status_t efi_status;
	u8 hbm_mode;
	int status;
	u8 fdt_val32;
	u8 arr[16] = { 0x1 };

	efi_status = get_efi_var(L"HBMMode", &oem_config_guid, NULL, &size,
				 &hbm_mode);
	if (efi_status != EFI_SUCCESS)
		goto out;

	if (hbm_mode != HBM_MODE_CACHE)
		goto out;

	fdt_val32 = 1;
	status = fdt_setprop_var(fdt, node, "linux,pbha-bit0", fdt_val32);
	if (status)
		return EFI_LOAD_ERROR;

	node = fdt_subnode_offset(fdt, 0, "cpus");
	if (node < 0) {
		node = fdt_add_subnode(fdt, 0, "cpus");
		if (node < 0)
			return EFI_LOAD_ERROR;
	}

	/* Current PBHA bit59 is need to enable PBHA bit0 mode. */
	status = fdt_setprop_var(fdt, node, "arm,pbha-performance-only", arr);
	if (status) {
		efi_err("PBHA: arm,pbha-performance-only failed\n");
		return EFI_LOAD_ERROR;
	}

out:
	return EFI_SUCCESS;
}
#else
static inline efi_status_t fdt_init_hbm_mode(void *fdt, int node)
{
	return EFI_SUCCESS;
}
#endif

static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size,
			       void *fdt, int new_fdt_size, char *cmdline_ptr,
			       u64 initrd_addr, u64 initrd_size)
@@ -148,6 +197,9 @@ static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size,
		}
	}

	if (fdt_init_hbm_mode(fdt, node) != EFI_SUCCESS)
		goto fdt_set_fail;

	/* Shrink the FDT back to its minimum size: */
	fdt_pack(fdt);

+1 −0
Original line number Diff line number Diff line
@@ -3,3 +3,4 @@ obj-$(CONFIG_KUNPENG_HCCS) += kunpeng_hccs.o

obj-$(CONFIG_HISI_HBMDEV)	+= hisi_hbmdev.o
obj-$(CONFIG_HISI_HBMCACHE)	+= hisi_hbmcache.o
obj-$(CONFIG_ARM64_PBHA)		+= pbha.o
+42 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (C) Huawei Technologies Co., Ltd. 2023. All rights reserved.
 */

#define pr_fmt(fmt)	"pbha: " fmt

#include <linux/init.h>
#include <linux/libfdt.h>
#include <linux/printk.h>
#include <linux/cpufeature.h>

#include <asm/setup.h>

#define HBM_MODE_CACHE	1

bool __ro_after_init pbha_bit0_enabled;

void __init early_pbha_bit0_init(void)
{
	const u8 *prop;
	void *fdt;
	int node;

	/* Check whether PBHA is enabled or not. */
	if (!system_supports_pbha())
		return;

	fdt = get_early_fdt_ptr();
	if (!fdt)
		return;

	node = fdt_path_offset(fdt, "/chosen");
	if (node < 0)
		return;

	prop = fdt_getprop(fdt, node, "linux,pbha-bit0", NULL);
	if (!prop)
		return;
	if (*prop == HBM_MODE_CACHE)
		pbha_bit0_enabled = true;
}
Loading