mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-07 09:14:07 -04:00
Merge tag 'riscv-mw2-6.15-rc1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/alexghiti/linux into for-next
riscv patches for 6.15-rc1, part 2 * A bunch of fixes: - 2 fixes in the purgatory code which prevented kexec to work - Workaround an issue with gcc-15 * tag 'riscv-mw2-6.15-rc1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/alexghiti/linux: riscv: Add norvc after .option arch in runtime const riscv: Make sure toolchain supports zba before using zba instructions riscv/purgatory: 4B align purgatory_start riscv/kexec_file: Handle R_RISCV_64 in purgatory relocator selftests: riscv: fix v_exec_initval_nolibc.c riscv: Fix hugetlb retrieval of number of ptes in case of !present pte riscv: print hartid on bringup dt-bindings: riscv: document vector crypto requirements dt-bindings: riscv: add vector sub-extension dependencies dt-bindings: riscv: d requires f RISC-V: add f & d extension validation checks RISC-V: add vector crypto extension validation checks RISC-V: add vector extension validation checks
This commit is contained in:
@@ -669,6 +669,12 @@ properties:
|
||||
https://github.com/T-head-Semi/thead-extension-spec/blob/95358cb2cca9489361c61d335e03d3134b14133f/xtheadvector.adoc.
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
contains:
|
||||
const: d
|
||||
then:
|
||||
contains:
|
||||
const: f
|
||||
# Zcb depends on Zca
|
||||
- if:
|
||||
contains:
|
||||
@@ -738,6 +744,85 @@ properties:
|
||||
contains:
|
||||
const: zaamo
|
||||
|
||||
- if:
|
||||
contains:
|
||||
const: zve32x
|
||||
then:
|
||||
contains:
|
||||
const: zicsr
|
||||
|
||||
- if:
|
||||
contains:
|
||||
const: zve32f
|
||||
then:
|
||||
allOf:
|
||||
- contains:
|
||||
const: f
|
||||
- contains:
|
||||
const: zve32x
|
||||
|
||||
- if:
|
||||
contains:
|
||||
const: zve64x
|
||||
then:
|
||||
contains:
|
||||
const: zve32x
|
||||
|
||||
- if:
|
||||
contains:
|
||||
const: zve64f
|
||||
then:
|
||||
allOf:
|
||||
- contains:
|
||||
const: f
|
||||
- contains:
|
||||
const: zve32f
|
||||
- contains:
|
||||
const: zve64x
|
||||
|
||||
- if:
|
||||
contains:
|
||||
const: zve64d
|
||||
then:
|
||||
allOf:
|
||||
- contains:
|
||||
const: d
|
||||
- contains:
|
||||
const: zve64f
|
||||
|
||||
- if:
|
||||
contains:
|
||||
anyOf:
|
||||
- const: zvbc
|
||||
- const: zvkn
|
||||
- const: zvknc
|
||||
- const: zvkng
|
||||
- const: zvknhb
|
||||
- const: zvksc
|
||||
then:
|
||||
contains:
|
||||
anyOf:
|
||||
- const: v
|
||||
- const: zve64x
|
||||
|
||||
- if:
|
||||
contains:
|
||||
anyOf:
|
||||
- const: zvbb
|
||||
- const: zvkb
|
||||
- const: zvkg
|
||||
- const: zvkned
|
||||
- const: zvknha
|
||||
- const: zvksed
|
||||
- const: zvksh
|
||||
- const: zvks
|
||||
- const: zvkt
|
||||
then:
|
||||
contains:
|
||||
anyOf:
|
||||
- const: v
|
||||
- const: zve32x
|
||||
|
||||
allOf:
|
||||
# Zcf extension does not exist on rv64
|
||||
- if:
|
||||
|
||||
@@ -729,6 +729,14 @@ config TOOLCHAIN_HAS_VECTOR_CRYPTO
|
||||
def_bool $(as-instr, .option arch$(comma) +v$(comma) +zvkb)
|
||||
depends on AS_HAS_OPTION_ARCH
|
||||
|
||||
config TOOLCHAIN_HAS_ZBA
|
||||
bool
|
||||
default y
|
||||
depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64ima_zba)
|
||||
depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32ima_zba)
|
||||
depends on LLD_VERSION >= 150000 || LD_VERSION >= 23900
|
||||
depends on AS_HAS_OPTION_ARCH
|
||||
|
||||
config RISCV_ISA_ZBA
|
||||
bool "Zba extension support for bit manipulation instructions"
|
||||
default y
|
||||
|
||||
@@ -56,6 +56,9 @@ void __init riscv_user_isa_enable(void);
|
||||
#define __RISCV_ISA_EXT_BUNDLE(_name, _bundled_exts) \
|
||||
_RISCV_ISA_EXT_DATA(_name, RISCV_ISA_EXT_INVALID, _bundled_exts, \
|
||||
ARRAY_SIZE(_bundled_exts), NULL)
|
||||
#define __RISCV_ISA_EXT_BUNDLE_VALIDATE(_name, _bundled_exts, _validate) \
|
||||
_RISCV_ISA_EXT_DATA(_name, RISCV_ISA_EXT_INVALID, _bundled_exts, \
|
||||
ARRAY_SIZE(_bundled_exts), _validate)
|
||||
|
||||
/* Used to declare extensions that are a superset of other extensions (Zvbb for instance) */
|
||||
#define __RISCV_ISA_EXT_SUPERSET(_name, _id, _sub_exts) \
|
||||
|
||||
@@ -79,7 +79,8 @@
|
||||
".long 1b - .\n\t" \
|
||||
".popsection" \
|
||||
|
||||
#if defined(CONFIG_RISCV_ISA_ZBA) && defined(CONFIG_RISCV_ISA_ZBKB)
|
||||
#if defined(CONFIG_RISCV_ISA_ZBA) && defined(CONFIG_TOOLCHAIN_HAS_ZBA) \
|
||||
&& defined(CONFIG_RISCV_ISA_ZBKB)
|
||||
#define runtime_const_ptr(sym) \
|
||||
({ \
|
||||
typeof(sym) __ret, __tmp; \
|
||||
@@ -95,7 +96,7 @@
|
||||
: [__ret] "=r" (__ret), [__tmp] "=r" (__tmp)); \
|
||||
__ret; \
|
||||
})
|
||||
#elif defined(CONFIG_RISCV_ISA_ZBA)
|
||||
#elif defined(CONFIG_RISCV_ISA_ZBA) && defined(CONFIG_TOOLCHAIN_HAS_ZBA)
|
||||
#define runtime_const_ptr(sym) \
|
||||
({ \
|
||||
typeof(sym) __ret, __tmp; \
|
||||
|
||||
@@ -119,6 +119,82 @@ static int riscv_ext_zicboz_validate(const struct riscv_isa_ext_data *data,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int riscv_ext_f_validate(const struct riscv_isa_ext_data *data,
|
||||
const unsigned long *isa_bitmap)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_FPU))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Due to extension ordering, d is checked before f, so no deferral
|
||||
* is required.
|
||||
*/
|
||||
if (!__riscv_isa_extension_available(isa_bitmap, RISCV_ISA_EXT_d)) {
|
||||
pr_warn_once("This kernel does not support systems with F but not D\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int riscv_ext_d_validate(const struct riscv_isa_ext_data *data,
|
||||
const unsigned long *isa_bitmap)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_FPU))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int riscv_ext_vector_x_validate(const struct riscv_isa_ext_data *data,
|
||||
const unsigned long *isa_bitmap)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_RISCV_ISA_V))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int riscv_ext_vector_float_validate(const struct riscv_isa_ext_data *data,
|
||||
const unsigned long *isa_bitmap)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_RISCV_ISA_V))
|
||||
return -EINVAL;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_FPU))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* The kernel doesn't support systems that don't implement both of
|
||||
* F and D, so if any of the vector extensions that do floating point
|
||||
* are to be usable, both floating point extensions need to be usable.
|
||||
*
|
||||
* Since this function validates vector only, and v/Zve* are probed
|
||||
* after f/d, there's no need for a deferral here.
|
||||
*/
|
||||
if (!__riscv_isa_extension_available(isa_bitmap, RISCV_ISA_EXT_d))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int riscv_ext_vector_crypto_validate(const struct riscv_isa_ext_data *data,
|
||||
const unsigned long *isa_bitmap)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_RISCV_ISA_V))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* It isn't the kernel's job to check that the binding is correct, so
|
||||
* it should be enough to check that any of the vector extensions are
|
||||
* enabled, which in-turn means that vector is usable in this kernel
|
||||
*/
|
||||
if (!__riscv_isa_extension_available(isa_bitmap, RISCV_ISA_EXT_ZVE32X))
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int riscv_ext_zca_depends(const struct riscv_isa_ext_data *data,
|
||||
const unsigned long *isa_bitmap)
|
||||
{
|
||||
@@ -359,16 +435,14 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
|
||||
__RISCV_ISA_EXT_DATA(i, RISCV_ISA_EXT_i),
|
||||
__RISCV_ISA_EXT_DATA(m, RISCV_ISA_EXT_m),
|
||||
__RISCV_ISA_EXT_SUPERSET(a, RISCV_ISA_EXT_a, riscv_a_exts),
|
||||
__RISCV_ISA_EXT_DATA(f, RISCV_ISA_EXT_f),
|
||||
__RISCV_ISA_EXT_DATA(d, RISCV_ISA_EXT_d),
|
||||
__RISCV_ISA_EXT_DATA_VALIDATE(f, RISCV_ISA_EXT_f, riscv_ext_f_validate),
|
||||
__RISCV_ISA_EXT_DATA_VALIDATE(d, RISCV_ISA_EXT_d, riscv_ext_d_validate),
|
||||
__RISCV_ISA_EXT_DATA(q, RISCV_ISA_EXT_q),
|
||||
__RISCV_ISA_EXT_SUPERSET(c, RISCV_ISA_EXT_c, riscv_c_exts),
|
||||
__RISCV_ISA_EXT_SUPERSET(v, RISCV_ISA_EXT_v, riscv_v_exts),
|
||||
__RISCV_ISA_EXT_SUPERSET_VALIDATE(v, RISCV_ISA_EXT_v, riscv_v_exts, riscv_ext_vector_float_validate),
|
||||
__RISCV_ISA_EXT_DATA(h, RISCV_ISA_EXT_h),
|
||||
__RISCV_ISA_EXT_SUPERSET_VALIDATE(zicbom, RISCV_ISA_EXT_ZICBOM, riscv_xlinuxenvcfg_exts,
|
||||
riscv_ext_zicbom_validate),
|
||||
__RISCV_ISA_EXT_SUPERSET_VALIDATE(zicboz, RISCV_ISA_EXT_ZICBOZ, riscv_xlinuxenvcfg_exts,
|
||||
riscv_ext_zicboz_validate),
|
||||
__RISCV_ISA_EXT_SUPERSET_VALIDATE(zicbom, RISCV_ISA_EXT_ZICBOM, riscv_xlinuxenvcfg_exts, riscv_ext_zicbom_validate),
|
||||
__RISCV_ISA_EXT_SUPERSET_VALIDATE(zicboz, RISCV_ISA_EXT_ZICBOZ, riscv_xlinuxenvcfg_exts, riscv_ext_zicboz_validate),
|
||||
__RISCV_ISA_EXT_DATA(ziccrse, RISCV_ISA_EXT_ZICCRSE),
|
||||
__RISCV_ISA_EXT_DATA(zicntr, RISCV_ISA_EXT_ZICNTR),
|
||||
__RISCV_ISA_EXT_DATA(zicond, RISCV_ISA_EXT_ZICOND),
|
||||
@@ -410,32 +484,31 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
|
||||
__RISCV_ISA_EXT_DATA(zksed, RISCV_ISA_EXT_ZKSED),
|
||||
__RISCV_ISA_EXT_DATA(zksh, RISCV_ISA_EXT_ZKSH),
|
||||
__RISCV_ISA_EXT_DATA(ztso, RISCV_ISA_EXT_ZTSO),
|
||||
__RISCV_ISA_EXT_SUPERSET(zvbb, RISCV_ISA_EXT_ZVBB, riscv_zvbb_exts),
|
||||
__RISCV_ISA_EXT_DATA(zvbc, RISCV_ISA_EXT_ZVBC),
|
||||
__RISCV_ISA_EXT_SUPERSET(zve32f, RISCV_ISA_EXT_ZVE32F, riscv_zve32f_exts),
|
||||
__RISCV_ISA_EXT_DATA(zve32x, RISCV_ISA_EXT_ZVE32X),
|
||||
__RISCV_ISA_EXT_SUPERSET(zve64d, RISCV_ISA_EXT_ZVE64D, riscv_zve64d_exts),
|
||||
__RISCV_ISA_EXT_SUPERSET(zve64f, RISCV_ISA_EXT_ZVE64F, riscv_zve64f_exts),
|
||||
__RISCV_ISA_EXT_SUPERSET(zve64x, RISCV_ISA_EXT_ZVE64X, riscv_zve64x_exts),
|
||||
__RISCV_ISA_EXT_SUPERSET_VALIDATE(zvbb, RISCV_ISA_EXT_ZVBB, riscv_zvbb_exts, riscv_ext_vector_crypto_validate),
|
||||
__RISCV_ISA_EXT_DATA_VALIDATE(zvbc, RISCV_ISA_EXT_ZVBC, riscv_ext_vector_crypto_validate),
|
||||
__RISCV_ISA_EXT_SUPERSET_VALIDATE(zve32f, RISCV_ISA_EXT_ZVE32F, riscv_zve32f_exts, riscv_ext_vector_float_validate),
|
||||
__RISCV_ISA_EXT_DATA_VALIDATE(zve32x, RISCV_ISA_EXT_ZVE32X, riscv_ext_vector_x_validate),
|
||||
__RISCV_ISA_EXT_SUPERSET_VALIDATE(zve64d, RISCV_ISA_EXT_ZVE64D, riscv_zve64d_exts, riscv_ext_vector_float_validate),
|
||||
__RISCV_ISA_EXT_SUPERSET_VALIDATE(zve64f, RISCV_ISA_EXT_ZVE64F, riscv_zve64f_exts, riscv_ext_vector_float_validate),
|
||||
__RISCV_ISA_EXT_SUPERSET_VALIDATE(zve64x, RISCV_ISA_EXT_ZVE64X, riscv_zve64x_exts, riscv_ext_vector_x_validate),
|
||||
__RISCV_ISA_EXT_DATA_VALIDATE(zvfbfmin, RISCV_ISA_EXT_ZVFBFMIN, riscv_vector_f_validate),
|
||||
__RISCV_ISA_EXT_DATA_VALIDATE(zvfbfwma, RISCV_ISA_EXT_ZVFBFWMA,
|
||||
riscv_ext_zvfbfwma_validate),
|
||||
__RISCV_ISA_EXT_DATA_VALIDATE(zvfbfwma, RISCV_ISA_EXT_ZVFBFWMA, riscv_ext_zvfbfwma_validate),
|
||||
__RISCV_ISA_EXT_DATA(zvfh, RISCV_ISA_EXT_ZVFH),
|
||||
__RISCV_ISA_EXT_DATA(zvfhmin, RISCV_ISA_EXT_ZVFHMIN),
|
||||
__RISCV_ISA_EXT_DATA(zvkb, RISCV_ISA_EXT_ZVKB),
|
||||
__RISCV_ISA_EXT_DATA(zvkg, RISCV_ISA_EXT_ZVKG),
|
||||
__RISCV_ISA_EXT_BUNDLE(zvkn, riscv_zvkn_bundled_exts),
|
||||
__RISCV_ISA_EXT_BUNDLE(zvknc, riscv_zvknc_bundled_exts),
|
||||
__RISCV_ISA_EXT_DATA(zvkned, RISCV_ISA_EXT_ZVKNED),
|
||||
__RISCV_ISA_EXT_BUNDLE(zvkng, riscv_zvkng_bundled_exts),
|
||||
__RISCV_ISA_EXT_DATA(zvknha, RISCV_ISA_EXT_ZVKNHA),
|
||||
__RISCV_ISA_EXT_DATA(zvknhb, RISCV_ISA_EXT_ZVKNHB),
|
||||
__RISCV_ISA_EXT_BUNDLE(zvks, riscv_zvks_bundled_exts),
|
||||
__RISCV_ISA_EXT_BUNDLE(zvksc, riscv_zvksc_bundled_exts),
|
||||
__RISCV_ISA_EXT_DATA(zvksed, RISCV_ISA_EXT_ZVKSED),
|
||||
__RISCV_ISA_EXT_DATA(zvksh, RISCV_ISA_EXT_ZVKSH),
|
||||
__RISCV_ISA_EXT_BUNDLE(zvksg, riscv_zvksg_bundled_exts),
|
||||
__RISCV_ISA_EXT_DATA(zvkt, RISCV_ISA_EXT_ZVKT),
|
||||
__RISCV_ISA_EXT_DATA_VALIDATE(zvkb, RISCV_ISA_EXT_ZVKB, riscv_ext_vector_crypto_validate),
|
||||
__RISCV_ISA_EXT_DATA_VALIDATE(zvkg, RISCV_ISA_EXT_ZVKG, riscv_ext_vector_crypto_validate),
|
||||
__RISCV_ISA_EXT_BUNDLE_VALIDATE(zvkn, riscv_zvkn_bundled_exts, riscv_ext_vector_crypto_validate),
|
||||
__RISCV_ISA_EXT_BUNDLE_VALIDATE(zvknc, riscv_zvknc_bundled_exts, riscv_ext_vector_crypto_validate),
|
||||
__RISCV_ISA_EXT_DATA_VALIDATE(zvkned, RISCV_ISA_EXT_ZVKNED, riscv_ext_vector_crypto_validate),
|
||||
__RISCV_ISA_EXT_BUNDLE_VALIDATE(zvkng, riscv_zvkng_bundled_exts, riscv_ext_vector_crypto_validate),
|
||||
__RISCV_ISA_EXT_DATA_VALIDATE(zvknha, RISCV_ISA_EXT_ZVKNHA, riscv_ext_vector_crypto_validate),
|
||||
__RISCV_ISA_EXT_DATA_VALIDATE(zvknhb, RISCV_ISA_EXT_ZVKNHB, riscv_ext_vector_crypto_validate),
|
||||
__RISCV_ISA_EXT_BUNDLE_VALIDATE(zvks, riscv_zvks_bundled_exts, riscv_ext_vector_crypto_validate),
|
||||
__RISCV_ISA_EXT_BUNDLE_VALIDATE(zvksc, riscv_zvksc_bundled_exts, riscv_ext_vector_crypto_validate),
|
||||
__RISCV_ISA_EXT_DATA_VALIDATE(zvksed, RISCV_ISA_EXT_ZVKSED, riscv_ext_vector_crypto_validate),
|
||||
__RISCV_ISA_EXT_DATA_VALIDATE(zvksh, RISCV_ISA_EXT_ZVKSH, riscv_ext_vector_crypto_validate),
|
||||
__RISCV_ISA_EXT_BUNDLE_VALIDATE(zvksg, riscv_zvksg_bundled_exts, riscv_ext_vector_crypto_validate),
|
||||
__RISCV_ISA_EXT_DATA_VALIDATE(zvkt, RISCV_ISA_EXT_ZVKT, riscv_ext_vector_crypto_validate),
|
||||
__RISCV_ISA_EXT_DATA(smaia, RISCV_ISA_EXT_SMAIA),
|
||||
__RISCV_ISA_EXT_DATA(smmpm, RISCV_ISA_EXT_SMMPM),
|
||||
__RISCV_ISA_EXT_SUPERSET(smnpm, RISCV_ISA_EXT_SMNPM, riscv_xlinuxenvcfg_exts),
|
||||
@@ -1003,16 +1076,6 @@ void __init riscv_fill_hwcap(void)
|
||||
riscv_v_setup_vsize();
|
||||
}
|
||||
|
||||
if (elf_hwcap & COMPAT_HWCAP_ISA_V) {
|
||||
/*
|
||||
* ISA string in device tree might have 'v' flag, but
|
||||
* CONFIG_RISCV_ISA_V is disabled in kernel.
|
||||
* Clear V flag in elf_hwcap if CONFIG_RISCV_ISA_V is disabled.
|
||||
*/
|
||||
if (!IS_ENABLED(CONFIG_RISCV_ISA_V))
|
||||
elf_hwcap &= ~COMPAT_HWCAP_ISA_V;
|
||||
}
|
||||
|
||||
memset(print_str, 0, sizeof(print_str));
|
||||
for (i = 0, j = 0; i < NUM_ALPHA_EXTS; i++)
|
||||
if (riscv_isa[0] & BIT_MASK(i))
|
||||
|
||||
@@ -468,6 +468,9 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
|
||||
case R_RISCV_ALIGN:
|
||||
case R_RISCV_RELAX:
|
||||
break;
|
||||
case R_RISCV_64:
|
||||
*(u64 *)loc = val;
|
||||
break;
|
||||
default:
|
||||
pr_err("Unknown rela relocation: %d\n", r_type);
|
||||
return -ENOEXEC;
|
||||
|
||||
@@ -48,6 +48,8 @@ EXPORT_SYMBOL_GPL(__cpuid_to_hartid_map);
|
||||
void __init smp_setup_processor_id(void)
|
||||
{
|
||||
cpuid_to_hartid_map(0) = boot_cpu_hartid;
|
||||
|
||||
pr_info("Booting Linux on hartid %lu\n", boot_cpu_hartid);
|
||||
}
|
||||
|
||||
static DEFINE_PER_CPU_READ_MOSTLY(int, ipi_dummy_dev);
|
||||
|
||||
@@ -231,6 +231,10 @@ asmlinkage __visible void smp_callin(void)
|
||||
riscv_ipi_enable();
|
||||
|
||||
numa_add_cpu(curr_cpuid);
|
||||
|
||||
pr_debug("CPU%u: Booted secondary hartid %lu\n", curr_cpuid,
|
||||
cpuid_to_hartid_map(curr_cpuid));
|
||||
|
||||
set_cpu_online(curr_cpuid, true);
|
||||
|
||||
/*
|
||||
|
||||
@@ -148,22 +148,25 @@ unsigned long hugetlb_mask_last_page(struct hstate *h)
|
||||
static pte_t get_clear_contig(struct mm_struct *mm,
|
||||
unsigned long addr,
|
||||
pte_t *ptep,
|
||||
unsigned long pte_num)
|
||||
unsigned long ncontig)
|
||||
{
|
||||
pte_t orig_pte = ptep_get(ptep);
|
||||
unsigned long i;
|
||||
pte_t pte, tmp_pte;
|
||||
bool present;
|
||||
|
||||
for (i = 0; i < pte_num; i++, addr += PAGE_SIZE, ptep++) {
|
||||
pte_t pte = ptep_get_and_clear(mm, addr, ptep);
|
||||
|
||||
if (pte_dirty(pte))
|
||||
orig_pte = pte_mkdirty(orig_pte);
|
||||
|
||||
if (pte_young(pte))
|
||||
orig_pte = pte_mkyoung(orig_pte);
|
||||
pte = ptep_get_and_clear(mm, addr, ptep);
|
||||
present = pte_present(pte);
|
||||
while (--ncontig) {
|
||||
ptep++;
|
||||
addr += PAGE_SIZE;
|
||||
tmp_pte = ptep_get_and_clear(mm, addr, ptep);
|
||||
if (present) {
|
||||
if (pte_dirty(tmp_pte))
|
||||
pte = pte_mkdirty(pte);
|
||||
if (pte_young(tmp_pte))
|
||||
pte = pte_mkyoung(pte);
|
||||
}
|
||||
}
|
||||
|
||||
return orig_pte;
|
||||
return pte;
|
||||
}
|
||||
|
||||
static pte_t get_clear_contig_flush(struct mm_struct *mm,
|
||||
@@ -212,6 +215,26 @@ static void clear_flush(struct mm_struct *mm,
|
||||
flush_tlb_range(&vma, saddr, addr);
|
||||
}
|
||||
|
||||
static int num_contig_ptes_from_size(unsigned long sz, size_t *pgsize)
|
||||
{
|
||||
unsigned long hugepage_shift;
|
||||
|
||||
if (sz >= PGDIR_SIZE)
|
||||
hugepage_shift = PGDIR_SHIFT;
|
||||
else if (sz >= P4D_SIZE)
|
||||
hugepage_shift = P4D_SHIFT;
|
||||
else if (sz >= PUD_SIZE)
|
||||
hugepage_shift = PUD_SHIFT;
|
||||
else if (sz >= PMD_SIZE)
|
||||
hugepage_shift = PMD_SHIFT;
|
||||
else
|
||||
hugepage_shift = PAGE_SHIFT;
|
||||
|
||||
*pgsize = 1 << hugepage_shift;
|
||||
|
||||
return sz >> hugepage_shift;
|
||||
}
|
||||
|
||||
/*
|
||||
* When dealing with NAPOT mappings, the privileged specification indicates that
|
||||
* "if an update needs to be made, the OS generally should first mark all of the
|
||||
@@ -226,22 +249,10 @@ void set_huge_pte_at(struct mm_struct *mm,
|
||||
pte_t pte,
|
||||
unsigned long sz)
|
||||
{
|
||||
unsigned long hugepage_shift, pgsize;
|
||||
size_t pgsize;
|
||||
int i, pte_num;
|
||||
|
||||
if (sz >= PGDIR_SIZE)
|
||||
hugepage_shift = PGDIR_SHIFT;
|
||||
else if (sz >= P4D_SIZE)
|
||||
hugepage_shift = P4D_SHIFT;
|
||||
else if (sz >= PUD_SIZE)
|
||||
hugepage_shift = PUD_SHIFT;
|
||||
else if (sz >= PMD_SIZE)
|
||||
hugepage_shift = PMD_SHIFT;
|
||||
else
|
||||
hugepage_shift = PAGE_SHIFT;
|
||||
|
||||
pte_num = sz >> hugepage_shift;
|
||||
pgsize = 1 << hugepage_shift;
|
||||
pte_num = num_contig_ptes_from_size(sz, &pgsize);
|
||||
|
||||
if (!pte_present(pte)) {
|
||||
for (i = 0; i < pte_num; i++, ptep++, addr += pgsize)
|
||||
@@ -295,13 +306,14 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
|
||||
unsigned long addr,
|
||||
pte_t *ptep, unsigned long sz)
|
||||
{
|
||||
size_t pgsize;
|
||||
pte_t orig_pte = ptep_get(ptep);
|
||||
int pte_num;
|
||||
|
||||
if (!pte_napot(orig_pte))
|
||||
return ptep_get_and_clear(mm, addr, ptep);
|
||||
|
||||
pte_num = napot_pte_num(napot_cont_order(orig_pte));
|
||||
pte_num = num_contig_ptes_from_size(sz, &pgsize);
|
||||
|
||||
return get_clear_contig(mm, addr, ptep, pte_num);
|
||||
}
|
||||
@@ -351,6 +363,7 @@ void huge_pte_clear(struct mm_struct *mm,
|
||||
pte_t *ptep,
|
||||
unsigned long sz)
|
||||
{
|
||||
size_t pgsize;
|
||||
pte_t pte = ptep_get(ptep);
|
||||
int i, pte_num;
|
||||
|
||||
@@ -359,8 +372,9 @@ void huge_pte_clear(struct mm_struct *mm,
|
||||
return;
|
||||
}
|
||||
|
||||
pte_num = napot_pte_num(napot_cont_order(pte));
|
||||
for (i = 0; i < pte_num; i++, addr += PAGE_SIZE, ptep++)
|
||||
pte_num = num_contig_ptes_from_size(sz, &pgsize);
|
||||
|
||||
for (i = 0; i < pte_num; i++, addr += pgsize, ptep++)
|
||||
pte_clear(mm, addr, ptep);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
.text
|
||||
|
||||
.align 2
|
||||
SYM_CODE_START(purgatory_start)
|
||||
|
||||
lla sp, .Lstack
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* the values. To further ensure consistency, this file is compiled without
|
||||
* libc and without auto-vectorization.
|
||||
*
|
||||
* To be "clean" all values must be either all ones or all zeroes.
|
||||
* To be "clean" all values must be all zeroes.
|
||||
*/
|
||||
|
||||
#define __stringify_1(x...) #x
|
||||
@@ -14,9 +14,8 @@
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char prev_value = 0, value;
|
||||
char value = 0;
|
||||
unsigned long vl;
|
||||
int first = 1;
|
||||
|
||||
if (argc > 2 && strcmp(argv[2], "x"))
|
||||
asm volatile (
|
||||
@@ -44,14 +43,11 @@ int main(int argc, char **argv)
|
||||
"vsrl.vi " __stringify(register) ", " __stringify(register) ", 8\n\t" \
|
||||
".option pop\n\t" \
|
||||
: "=r" (value)); \
|
||||
if (first) { \
|
||||
first = 0; \
|
||||
} else if (value != prev_value || !(value == 0x00 || value == 0xff)) { \
|
||||
if (value != 0x00) { \
|
||||
printf("Register " __stringify(register) \
|
||||
" values not clean! value: %u\n", value); \
|
||||
exit(-1); \
|
||||
} \
|
||||
prev_value = value; \
|
||||
} \
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user