mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 12:43:29 +02:00
Merge tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pull arm64 updates from Catalin Marinas: "Notable features are user-space support for the memcpy/memset instructions and the permission indirection extension. - Support for the Armv8.9 Permission Indirection Extensions. While this feature doesn't add new functionality, it enables future support for Guarded Control Stacks (GCS) and Permission Overlays - User-space support for the Armv8.8 memcpy/memset instructions - arm64 perf: support the HiSilicon SoC uncore PMU, Arm CMN sysfs identifier, support for the NXP i.MX9 SoC DDRC PMU, fixes and cleanups - Removal of superfluous ISBs on context switch (following retrospective architecture tightening) - Decode the ISS2 register during faults for additional information to help with debugging - KPTI clean-up/simplification of the trampoline exit code - Addressing several -Wmissing-prototype warnings - Kselftest improvements for signal handling and ptrace - Fix TPIDR2_EL0 restoring on sigreturn - Clean-up, robustness improvements of the module allocation code - More sysreg conversions to the automatic register/bitfields generation - CPU capabilities handling cleanup - Arm documentation updates: ACPI, ptdump" * tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: (124 commits) kselftest/arm64: Add a test case for TPIDR2 restore arm64/signal: Restore TPIDR2 register rather than memory state arm64: alternatives: make clean_dcache_range_nopatch() noinstr-safe Documentation/arm64: Add ptdump documentation arm64: hibernate: remove WARN_ON in save_processor_state kselftest/arm64: Log signal code and address for unexpected signals docs: perf: Fix warning from 'make htmldocs' in hisi-pmu.rst arm64/fpsimd: Exit streaming mode when flushing tasks docs: perf: Add new description for HiSilicon UC PMU drivers/perf: hisi: Add support for HiSilicon UC PMU driver drivers/perf: hisi: Add support for HiSilicon H60PA and PAv3 PMU driver perf: arm_cspmu: Add missing MODULE_DEVICE_TABLE perf/arm-cmn: Add sysfs identifier perf/arm-cmn: Revamp model detection perf/arm_dmc620: Add cpumask arm64: mm: fix VA-range sanity check arm64/mm: remove now-superfluous ISBs from TTBR writes Documentation/arm64: Update ACPI tables from BBR Documentation/arm64: Update references in arm-acpi Documentation/arm64: Update ARM and arch reference ...
This commit is contained in:
@@ -39,6 +39,20 @@ static void cssc_sigill(void)
|
||||
asm volatile(".inst 0xdac01c00" : : : "x0");
|
||||
}
|
||||
|
||||
static void mops_sigill(void)
|
||||
{
|
||||
char dst[1], src[1];
|
||||
register char *dstp asm ("x0") = dst;
|
||||
register char *srcp asm ("x1") = src;
|
||||
register long size asm ("x2") = 1;
|
||||
|
||||
/* CPYP [x0]!, [x1]!, x2! */
|
||||
asm volatile(".inst 0x1d010440"
|
||||
: "+r" (dstp), "+r" (srcp), "+r" (size)
|
||||
:
|
||||
: "cc", "memory");
|
||||
}
|
||||
|
||||
static void rng_sigill(void)
|
||||
{
|
||||
asm volatile("mrs x0, S3_3_C2_C4_0" : : : "x0");
|
||||
@@ -209,6 +223,14 @@ static const struct hwcap_data {
|
||||
.cpuinfo = "cssc",
|
||||
.sigill_fn = cssc_sigill,
|
||||
},
|
||||
{
|
||||
.name = "MOPS",
|
||||
.at_hwcap = AT_HWCAP2,
|
||||
.hwcap_bit = HWCAP2_MOPS,
|
||||
.cpuinfo = "mops",
|
||||
.sigill_fn = mops_sigill,
|
||||
.sigill_reliable = true,
|
||||
},
|
||||
{
|
||||
.name = "RNG",
|
||||
.at_hwcap = AT_HWCAP2,
|
||||
|
@@ -20,7 +20,7 @@
|
||||
|
||||
#include "../../kselftest.h"
|
||||
|
||||
#define EXPECTED_TESTS 7
|
||||
#define EXPECTED_TESTS 11
|
||||
|
||||
#define MAX_TPIDRS 2
|
||||
|
||||
@@ -132,6 +132,34 @@ static void test_tpidr(pid_t child)
|
||||
}
|
||||
}
|
||||
|
||||
static void test_hw_debug(pid_t child, int type, const char *type_name)
|
||||
{
|
||||
struct user_hwdebug_state state;
|
||||
struct iovec iov;
|
||||
int slots, arch, ret;
|
||||
|
||||
iov.iov_len = sizeof(state);
|
||||
iov.iov_base = &state;
|
||||
|
||||
/* Should be able to read the values */
|
||||
ret = ptrace(PTRACE_GETREGSET, child, type, &iov);
|
||||
ksft_test_result(ret == 0, "read_%s\n", type_name);
|
||||
|
||||
if (ret == 0) {
|
||||
/* Low 8 bits is the number of slots, next 4 bits the arch */
|
||||
slots = state.dbg_info & 0xff;
|
||||
arch = (state.dbg_info >> 8) & 0xf;
|
||||
|
||||
ksft_print_msg("%s version %d with %d slots\n", type_name,
|
||||
arch, slots);
|
||||
|
||||
/* Zero is not currently architecturally valid */
|
||||
ksft_test_result(arch, "%s_arch_set\n", type_name);
|
||||
} else {
|
||||
ksft_test_result_skip("%s_arch_set\n");
|
||||
}
|
||||
}
|
||||
|
||||
static int do_child(void)
|
||||
{
|
||||
if (ptrace(PTRACE_TRACEME, -1, NULL, NULL))
|
||||
@@ -207,6 +235,8 @@ static int do_parent(pid_t child)
|
||||
ksft_print_msg("Parent is %d, child is %d\n", getpid(), child);
|
||||
|
||||
test_tpidr(child);
|
||||
test_hw_debug(child, NT_ARM_HW_WATCH, "NT_ARM_HW_WATCH");
|
||||
test_hw_debug(child, NT_ARM_HW_BREAK, "NT_ARM_HW_BREAK");
|
||||
|
||||
ret = EXIT_SUCCESS;
|
||||
|
||||
|
@@ -4,7 +4,7 @@ fake_sigreturn_*
|
||||
sme_*
|
||||
ssve_*
|
||||
sve_*
|
||||
tpidr2_siginfo
|
||||
tpidr2_*
|
||||
za_*
|
||||
zt_*
|
||||
!*.[ch]
|
||||
|
@@ -249,7 +249,8 @@ static void default_handler(int signum, siginfo_t *si, void *uc)
|
||||
fprintf(stderr, "-- Timeout !\n");
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
"-- RX UNEXPECTED SIGNAL: %d\n", signum);
|
||||
"-- RX UNEXPECTED SIGNAL: %d code %d address %p\n",
|
||||
signum, si->si_code, si->si_addr);
|
||||
}
|
||||
default_result(current, 1);
|
||||
}
|
||||
|
@@ -0,0 +1,86 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2023 ARM Limited
|
||||
*
|
||||
* Verify that the TPIDR2 register context in signal frames is restored.
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
#include <ucontext.h>
|
||||
#include <sys/auxv.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <unistd.h>
|
||||
#include <asm/sigcontext.h>
|
||||
|
||||
#include "test_signals_utils.h"
|
||||
#include "testcases.h"
|
||||
|
||||
#define SYS_TPIDR2 "S3_3_C13_C0_5"
|
||||
|
||||
static uint64_t get_tpidr2(void)
|
||||
{
|
||||
uint64_t val;
|
||||
|
||||
asm volatile (
|
||||
"mrs %0, " SYS_TPIDR2 "\n"
|
||||
: "=r"(val)
|
||||
:
|
||||
: "cc");
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void set_tpidr2(uint64_t val)
|
||||
{
|
||||
asm volatile (
|
||||
"msr " SYS_TPIDR2 ", %0\n"
|
||||
:
|
||||
: "r"(val)
|
||||
: "cc");
|
||||
}
|
||||
|
||||
|
||||
static uint64_t initial_tpidr2;
|
||||
|
||||
static bool save_tpidr2(struct tdescr *td)
|
||||
{
|
||||
initial_tpidr2 = get_tpidr2();
|
||||
fprintf(stderr, "Initial TPIDR2: %lx\n", initial_tpidr2);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int modify_tpidr2(struct tdescr *td, siginfo_t *si, ucontext_t *uc)
|
||||
{
|
||||
uint64_t my_tpidr2 = get_tpidr2();
|
||||
|
||||
my_tpidr2++;
|
||||
fprintf(stderr, "Setting TPIDR2 to %lx\n", my_tpidr2);
|
||||
set_tpidr2(my_tpidr2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void check_tpidr2(struct tdescr *td)
|
||||
{
|
||||
uint64_t tpidr2 = get_tpidr2();
|
||||
|
||||
td->pass = tpidr2 == initial_tpidr2;
|
||||
|
||||
if (td->pass)
|
||||
fprintf(stderr, "TPIDR2 restored\n");
|
||||
else
|
||||
fprintf(stderr, "TPIDR2 was %lx but is now %lx\n",
|
||||
initial_tpidr2, tpidr2);
|
||||
}
|
||||
|
||||
struct tdescr tde = {
|
||||
.name = "TPIDR2 restore",
|
||||
.descr = "Validate that TPIDR2 is restored from the sigframe",
|
||||
.feats_required = FEAT_SME,
|
||||
.timeout = 3,
|
||||
.sig_trig = SIGUSR1,
|
||||
.init = save_tpidr2,
|
||||
.run = modify_tpidr2,
|
||||
.check_result = check_tpidr2,
|
||||
};
|
@@ -48,6 +48,34 @@ struct reg_sublist {
|
||||
__u64 rejects_set_n;
|
||||
};
|
||||
|
||||
struct feature_id_reg {
|
||||
__u64 reg;
|
||||
__u64 id_reg;
|
||||
__u64 feat_shift;
|
||||
__u64 feat_min;
|
||||
};
|
||||
|
||||
static struct feature_id_reg feat_id_regs[] = {
|
||||
{
|
||||
ARM64_SYS_REG(3, 0, 2, 0, 3), /* TCR2_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 0, 7, 3), /* ID_AA64MMFR3_EL1 */
|
||||
0,
|
||||
1
|
||||
},
|
||||
{
|
||||
ARM64_SYS_REG(3, 0, 10, 2, 2), /* PIRE0_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 0, 7, 3), /* ID_AA64MMFR3_EL1 */
|
||||
4,
|
||||
1
|
||||
},
|
||||
{
|
||||
ARM64_SYS_REG(3, 0, 10, 2, 3), /* PIR_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 0, 7, 3), /* ID_AA64MMFR3_EL1 */
|
||||
4,
|
||||
1
|
||||
}
|
||||
};
|
||||
|
||||
struct vcpu_config {
|
||||
char *name;
|
||||
struct reg_sublist sublists[];
|
||||
@@ -68,7 +96,8 @@ static int vcpu_configs_n;
|
||||
|
||||
#define for_each_missing_reg(i) \
|
||||
for ((i) = 0; (i) < blessed_n; ++(i)) \
|
||||
if (!find_reg(reg_list->reg, reg_list->n, blessed_reg[i]))
|
||||
if (!find_reg(reg_list->reg, reg_list->n, blessed_reg[i])) \
|
||||
if (check_supported_feat_reg(vcpu, blessed_reg[i]))
|
||||
|
||||
#define for_each_new_reg(i) \
|
||||
for_each_reg_filtered(i) \
|
||||
@@ -132,6 +161,25 @@ static bool find_reg(__u64 regs[], __u64 nr_regs, __u64 reg)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool check_supported_feat_reg(struct kvm_vcpu *vcpu, __u64 reg)
|
||||
{
|
||||
int i, ret;
|
||||
__u64 data, feat_val;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(feat_id_regs); i++) {
|
||||
if (feat_id_regs[i].reg == reg) {
|
||||
ret = __vcpu_get_reg(vcpu, feat_id_regs[i].id_reg, &data);
|
||||
if (ret < 0)
|
||||
return false;
|
||||
|
||||
feat_val = ((data >> feat_id_regs[i].feat_shift) & 0xf);
|
||||
return feat_val >= feat_id_regs[i].feat_min;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static const char *str_with_index(const char *template, __u64 index)
|
||||
{
|
||||
char *str, *p;
|
||||
@@ -843,12 +891,15 @@ static __u64 base_regs[] = {
|
||||
ARM64_SYS_REG(3, 0, 2, 0, 0), /* TTBR0_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 2, 0, 1), /* TTBR1_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 2, 0, 2), /* TCR_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 2, 0, 3), /* TCR2_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 5, 1, 0), /* AFSR0_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 5, 1, 1), /* AFSR1_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 5, 2, 0), /* ESR_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 6, 0, 0), /* FAR_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 7, 4, 0), /* PAR_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 10, 2, 0), /* MAIR_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 10, 2, 2), /* PIRE0_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 10, 2, 3), /* PIR_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 10, 3, 0), /* AMAIR_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 12, 0, 0), /* VBAR_EL1 */
|
||||
ARM64_SYS_REG(3, 0, 12, 1, 1), /* DISR_EL1 */
|
||||
|
Reference in New Issue
Block a user