hrw / arm-socs-table

Table of ARM SoC and their features
https://gpages.juszkiewicz.com.pl/arm-socs-table/arm-socs.html
GNU General Public License v2.0
33 stars 6 forks source link

cortex-a78c and cortex-x1c are documented to support SSBS, despite the table indicating otherwise #95

Closed markmi closed 1 year ago

markmi commented 1 year ago

Looking in: arm_cortex_a78c_core_trm_102226_0002_03_en.pdf arm_cortex_x1c_core_trm_101968_0002_04_en.pdf

There is the status-values:

"ID_AA64PFR1_EL1, AArch64" "SBSS [7:4] AArch64 provides the PSTATE.SSBS mechanism to mark regions that are Speculative Store Bypassing Safe (SSBS). 0x01 AArch64 provides the PSTATE.SSBS mechanism to mark regions that are Speculative Store Bypassing Safe, but does not implement the MSR/MRS instructions to directly read and write the PSTATE.SSBS field."

"ID_PFR2_EL1, AArch32" "SBSS [7:4] 1 AArch32 provides the PSTATE.SSBS mechanism to mark regions that are Speculative Store Bypassing Safe (SSBS)."

Also, other places in the documents indicate support for SSBS:

"The traps for EL0 and EL1 cache controls, PSTATE Speculative Store Bypass Safe (SSBS) bit and the speculation barriers (CSDB, SSBB, PSSBB) instructions introduced in the Armv8.5‐A extension"

"The Cortex-X1C core implements the PSTATE Speculative Store Bypass Safe (SSBS) bit introduced in the Armv8.5‐A extension."

May be linux only reports ssbs if the "MSR/MRS instructions" are supported?

Based on references in GCC sources and the like, such SSBS points may apply to a lot of other cortex contexts.

hrw commented 1 year ago

This table is built on what Linux reports, not what TRM reports for cpu cores used in SoC.

And those values can differ even between dumps from same SoC used in misc devices.

markmi commented 1 year ago

This table is built on what Linux reports, not what TRM reports for cpu cores used in SoC.

And those values can differ even between dumps from same SoC used in misc devices.

FYI: FreeBSD reports for the Windows Dev Kit 2023 's Snapdragon 8cx Gen 3:

         Processor Features 1 = <PSTATE.SSBS>

More fully:

 Instruction Set Attributes 0 = <CondM-8.4,DP,RDM,Atomic,CRC32,SHA2,SHA1,AES+PMULL>
 Instruction Set Attributes 1 = <GPA,RCPC-8.4,APA EPAC2,DCPoP>
 Instruction Set Attributes 2 = <>
         Processor Features 0 = <CSV3,CSV2,RAS,GIC,AdvSIMD+HP,FP+HP,EL3,EL2,EL1,EL0 32>
         Processor Features 1 = <PSTATE.SSBS>
      Memory Model Features 0 = <TGran4,TGran64,TGran16,SNSMem,BigEnd,16bit ASID,1TB PA>
      Memory Model Features 1 = <XNX,PAN+ATS1E1,LO,HPD+TTPBHA,VH,16bit VMID,HAF+DS>
      Memory Model Features 2 = <AT,32bit CCIDX,48bit VA,IESB,UAO,CnP>
             Debug Features 0 = <DoubleLock,SPE,2 CTX BKPTs,4 Watchpoints,6 Breakpoints,PMUv3 v8.1,Debugv8.2>
             Debug Features 1 = <>
         Auxiliary Features 0 = <>
         Auxiliary Features 1 = <>
AArch32 Instruction Set Attributes 5 = <RDM,CRC32,SHA2,SHA1,AES+VMULL,SEVL>
AArch32 Media and VFP Features 0 = <FPRound,FPSqrt,FPDivide,DP VFPv3+v4,SP VFPv3+v4,AdvSIMD>
AArch32 Media and VFP Features 1 = <SIMDFMAC,FPHP Arith,SIMDHP Arith,SIMDSP,SIMDInt,SIMDLS,FPDNaN,FPFtZ>
markmi commented 1 year ago

Hmm. Looks like Linux sometimes explicitly hides the SSBS feature based on some criteria if the investigative context involves kvm:

int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
{
    struct kvm_smccc_features *smccc_feat = &vcpu->kvm->arch.smccc_feat;
    u32 func_id = smccc_get_function(vcpu);
    u64 val[4] = {SMCCC_RET_NOT_SUPPORTED};
    u32 feature;
    gpa_t gpa;

    if (!kvm_hvc_call_allowed(vcpu, func_id))
        goto out;

    switch (func_id) {
    . . .
    case ARM_SMCCC_ARCH_FEATURES_FUNC_ID:
        feature = smccc_get_arg1(vcpu);
        switch (feature) {
        . . .
        case ARM_SMCCC_ARCH_WORKAROUND_2:
            switch (arm64_get_spectre_v4_state()) {
            case SPECTRE_VULNERABLE:
                break;
            case SPECTRE_MITIGATED:
                /*
                 * SSBS everywhere: Indicate no firmware
                 * support, as the SSBS support will be
                 * indicated to the guest and the default is
                 * safe.
                 *
                 * Otherwise, expose a permanent mitigation
                 * to the guest, and hide SSBS so that the
                 * guest stays protected.
                 */
                if (cpus_have_final_cap(ARM64_SSBS))
                    break;
                fallthrough;
            case SPECTRE_UNAFFECTED:
                val[0] = SMCCC_RET_NOT_REQUIRED;
                break;
            }
            break;
. . .

static int get_kernel_wa_level(u64 regid)
{
    switch (regid) {
    . . .
    case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2:
        switch (arm64_get_spectre_v4_state()) {
        case SPECTRE_MITIGATED:
            /*
             * As for the hypercall discovery, we pretend we
             * don't have any FW mitigation if SSBS is there at
             * all times.
             */
            if (cpus_have_final_cap(ARM64_SSBS))
                return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL;
            fallthrough;
        case SPECTRE_UNAFFECTED:
            return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED;
        case SPECTRE_VULNERABLE:
            return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL;
        }
        break;
. . .

It might be important to be sure data collection is via bare metal instead of kvm or to document that such issues of interpretation could be involved instead of directly being about the core itself.

But, there is also spectre_v4 related variability in the status used:

void spectre_v4_enable_task_mitigation(struct task_struct *tsk)
{
    struct pt_regs *regs = task_pt_regs(tsk);
    bool ssbs = false, kthread = tsk->flags & PF_KTHREAD;

    if (spectre_v4_mitigations_off())
        ssbs = true;
    else if (spectre_v4_mitigations_dynamic() && !kthread)
        ssbs = !test_tsk_thread_flag(tsk, TIF_SSBD);

    __update_pstate_ssbs(regs, ssbs);
}

What a mess. Well, now I've more of a clue how not to interpret SSBS status information without checking the details of the source of the information.