Index: emulators/qemu-user-static-devel/files/patch-1 =================================================================== --- emulators/qemu-user-static-devel/files/patch-1 (nonexistent) +++ emulators/qemu-user-static-devel/files/patch-1 (working copy) @@ -0,0 +1,58 @@ +https://lists.gnu.org/archive/html/qemu-arm/2019-01/msg00474.html + +XXX mik enable read from qemu-user-mode + + +Although technically not visible to userspace the kernel does make +them visible via a trap and emulate ABI. We provide a new permission +mask (PL0U_R) which maps to PL0_R for CONFIG_USER builds and adjust +the minimum permission check accordingly. + +Signed-off-by: Alex Bennée +--- + target/arm/cpu.h | 12 ++++++++++++ + target/arm/helper.c | 6 +++++- + 2 files changed, 17 insertions(+), 1 deletion(-) + +diff --git a/target/arm/cpu.h b/target/arm/cpu.h +index ff81db420d..3b3c359cca 100644 +--- target/arm/cpu.h ++++ target/arm/cpu.h +@@ -2202,6 +2202,18 @@ static inline bool cptype_valid(int cptype) + #define PL0_R (0x02 | PL1_R) + #define PL0_W (0x01 | PL1_W) + ++/* ++ * For user-mode some registers are accessible to EL0 via a kernel ++ * trap-and-emulate ABI. In this case we define the read permissions ++ * as actually being PL0_R. However some bits of any given register ++ * may still be masked. ++ */ ++//#ifdef CONFIG_USER_ONLY ++#define PL0U_R PL0_R ++//#else ++//#define PL0U_R PL1_R ++//#endif ++ + #define PL3_RW (PL3_R | PL3_W) + #define PL2_RW (PL2_R | PL2_W) + #define PL1_RW (PL1_R | PL1_W) +diff --git a/target/arm/helper.c b/target/arm/helper.c +index 92666e5208..42c1c0b144 100644 +--- target/arm/helper.c ++++ target/arm/helper.c +@@ -6731,7 +6731,11 @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu, + if (r->state != ARM_CP_STATE_AA32) { + int mask = 0; + switch (r->opc1) { +- case 0: case 1: case 2: ++ case 0: ++ /* min_EL EL1, but some accessible to EL0 via kernel ABI */ ++ mask = PL0U_R | PL1_RW; ++ break; ++ case 1: case 2: + /* min_EL EL1 */ + mask = PL1_RW; + break; +-- +2.17.1 Property changes on: emulators/qemu-user-static-devel/files/patch-1 ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: emulators/qemu-user-static-devel/files/patch-2 =================================================================== --- emulators/qemu-user-static-devel/files/patch-2 (nonexistent) +++ emulators/qemu-user-static-devel/files/patch-2 (working copy) @@ -0,0 +1,151 @@ +https://lists.gnu.org/archive/html/qemu-arm/2019-01/msg00476.html + + +A number of CPUID registers are exposed to userspace by modern Linux +kernels thanks to the "ARM64 CPU Feature Registers" ABI. For QEMU's +user-mode emulation we don't need to emulate the kernels trap but just +return the value the trap would have done. For this we use the PL0U_R +permission mask which allows this access in CONFIG_USER mode. + +Some registers only return a subset of their contents so we need +specific CONFIG_USER_ONLY logic to do this. + +Signed-off-by: Alex Bennée + +--- +v4 + - tweak commit message + - use PL0U_R instead of PL1U_R to be less confusing + - more CONFIG_USER logic for special cases + - mask a bunch of bits for some registers +--- + target/arm/helper.c | 51 ++++++++++++++++++++++++++++++++------------- + 1 file changed, 36 insertions(+), 15 deletions(-) + + +--- target/arm/helper.c.orig 2020-01-15 10:57:32.205310000 +0100 ++++ target/arm/helper.c 2020-01-15 11:09:33.857765000 +0100 +@@ -3047,7 +3047,7 @@ static uint64_t mpidr_read(CPUARMState *env, const ARM + static const ARMCPRegInfo mpidr_cp_reginfo[] = { + { .name = "MPIDR", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 5, +- .access = PL1_R, .readfn = mpidr_read, .type = ARM_CP_NO_RAW }, ++ .access = PL0U_R, .readfn = mpidr_read, .type = ARM_CP_NO_RAW }, + REGINFO_SENTINEL + }; + +@@ -4945,6 +4945,7 @@ static uint64_t id_pfr1_read(CPUARMState *env, const A + return pfr1; + } + ++#ifndef CONFIG_USER_ONLY + static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri) + { + ARMCPU *cpu = arm_env_get_cpu(env); +@@ -4955,6 +4956,7 @@ static uint64_t id_aa64pfr0_read(CPUARMState *env, con + } + return pfr0; + } ++#endif + + void register_cp_regs_for_features(ARMCPU *cpu) + { +@@ -5102,18 +5104,26 @@ void register_cp_regs_for_features(ARMCPU *cpu) + * define new registers here. + */ + ARMCPRegInfo v8_idregs[] = { +- /* ID_AA64PFR0_EL1 is not a plain ARM_CP_CONST because we don't +- * know the right value for the GIC field until after we +- * define these regs. ++ /* ID_AA64PFR0_EL1 is not a plain ARM_CP_CONST for system ++ * emulation because we don't know the right value for the ++ * GIC field until after we define these regs. For ++ * user-mode HWCAP_CPUID emulation the GIC bits are masked ++ * anyway. + */ + { .name = "ID_AA64PFR0_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 0, ++#ifndef CONFIG_USER_ONLY + .access = PL1_R, .type = ARM_CP_NO_RAW, + .readfn = id_aa64pfr0_read, +- .writefn = arm_cp_write_ignore }, ++ .writefn = arm_cp_write_ignore ++#else ++ .access = PL0U_R, .type = ARM_CP_CONST, ++ .resetvalue = cpu->isar.id_aa64pfr0 & 0x000f000f0ff0000ULL ++#endif ++ }, + { .name = "ID_AA64PFR1_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 1, +- .access = PL1_R, .type = ARM_CP_CONST, ++ .access = PL0U_R, .type = ARM_CP_CONST, + .resetvalue = cpu->isar.id_aa64pfr1}, + { .name = "ID_AA64PFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 2, +@@ -5142,7 +5152,7 @@ void register_cp_regs_for_features(ARMCPU *cpu) + .resetvalue = 0 }, + { .name = "ID_AA64DFR0_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 0, +- .access = PL1_R, .type = ARM_CP_CONST, ++ .access = PL0U_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_aa64dfr0 }, + { .name = "ID_AA64DFR1_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 1, +@@ -5174,11 +5184,16 @@ void register_cp_regs_for_features(ARMCPU *cpu) + .resetvalue = 0 }, + { .name = "ID_AA64ISAR0_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 0, +- .access = PL1_R, .type = ARM_CP_CONST, +- .resetvalue = cpu->isar.id_aa64isar0 }, ++ .access = PL0U_R, .type = ARM_CP_CONST, ++#ifdef CONFIG_USER_ONLY ++ .resetvalue = cpu->isar.id_aa64isar0 & 0x000fffffff0ffff0ULL ++#else ++ .resetvalue = cpu->isar.id_aa64isar0 ++#endif ++ }, + { .name = "ID_AA64ISAR1_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 1, +- .access = PL1_R, .type = ARM_CP_CONST, ++ .access = PL0U_R, .type = ARM_CP_CONST, + .resetvalue = cpu->isar.id_aa64isar1 }, + { .name = "ID_AA64ISAR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 2, +@@ -5206,11 +5221,11 @@ void register_cp_regs_for_features(ARMCPU *cpu) + .resetvalue = 0 }, + { .name = "ID_AA64MMFR0_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0, +- .access = PL1_R, .type = ARM_CP_CONST, ++ .access = PL0U_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_aa64mmfr0 }, + { .name = "ID_AA64MMFR1_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 1, +- .access = PL1_R, .type = ARM_CP_CONST, ++ .access = PL0U_R, .type = ARM_CP_CONST, + .resetvalue = cpu->id_aa64mmfr1 }, + { .name = "ID_AA64MMFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 2, +@@ -5510,7 +5525,7 @@ void register_cp_regs_for_features(ARMCPU *cpu) + ARMCPRegInfo id_v8_midr_cp_reginfo[] = { + { .name = "MIDR_EL1", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 0, +- .access = PL1_R, .type = ARM_CP_NO_RAW, .resetvalue = cpu->midr, ++ .access = PL0U_R, .type = ARM_CP_NO_RAW, .resetvalue = cpu->midr, + .fieldoffset = offsetof(CPUARMState, cp15.c0_cpuid), + .readfn = midr_read }, + /* crn = 0 op1 = 0 crm = 0 op2 = 4,7 : AArch32 aliases of MIDR */ +@@ -5522,7 +5537,13 @@ void register_cp_regs_for_features(ARMCPU *cpu) + .access = PL1_R, .resetvalue = cpu->midr }, + { .name = "REVIDR_EL1", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 6, +- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->revidr }, ++#ifdef CONFIG_USER_ONLY ++ .access = PL0U_R, .type = ARM_CP_CONST, ++ .resetvalue = 0 /* HW_CPUID IMPDEF fields are 0 */ }, ++#else ++ .access = PL1_R, .type = ARM_CP_CONST, ++ .resetvalue = cpu->revidr }, ++#endif + REGINFO_SENTINEL + }; + ARMCPRegInfo id_cp_reginfo[] = { Property changes on: emulators/qemu-user-static-devel/files/patch-2 ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property