Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add is_s390x_feature_detected #1699

Merged
merged 1 commit into from
Jan 16, 2025

Conversation

folkertdev
Copy link
Contributor

@folkertdev folkertdev commented Jan 12, 2025

tracking issue: rust-lang/rust#135413
relevant issue: rust-lang/rust#130869

this PR adds the is_s390x_feature_detected macro.

Is an ACP needed here?

Below is a bunch of context.

Feature detection

This PR uses only the getauxval function. That is sufficient for the current feature flags.

Based on the official documents, the stfl instruction can/should be used to test for "Facility Indications". Unfortunately, it appears that this instruction can only be executed by the kernel, and in any case stores its result at address 200, that users cannot read. Bummer.

There is also the stfle instruction, that provides more facility indications. We can actually use that from user space, e.g.

struct ExtendedFacilityList([u64; 4]);

impl ExtendedFacilityList {
    unsafe fn new() -> Self {
        let mut result: [u64; 4] = [0; 4];
        unsafe {
            core::arch::asm!(
                "lgr %r0, {0}",
                // equivalently ".insn s, 0xb2b00000, 0({1})",
                "stfle 0({1})",
                in(reg) result.len() as u64 - 1,
                in(reg_addr) result.as_mut_ptr() ,
                options(nostack, preserves_flags )
            );
        }
        Self(result)
    }

    const fn get(&self, n: usize) -> bool {
        // of course they number bits from the left...
        self.0[n / 64] & (1 << (63 - (n % 64))) != 0
    }
}

But, for now, this is not needed and getauxval is sufficient.

Feature names

On nightly, s390x currently has two target features, introduced in rust-lang/rust#127506:

  • vector for SIMD capabilities
  • backchain related to stack unwinding

The "vector" name appears to be an LLVM concept: in qemu, clang and the linux kernel the "vector" extension is called vx. There is nothing called "backchain" in the Facility Indications, so it looks like that is not a feature that can be queried for at runtime.

Anyway, for now, only "vector" is supported by the is_s390x_feature_detected macro, and it maps internally to the vx facility indication. For some of the vector instructions, the extensions like vector-enhancements-1 will likely also be needed, but this PR does not include them.

This LLVM file lists many more features that are not currently supported.

Testing

I could not find a qemu CPU that works with rust programs and also does not support vx. I did test the logic using the vxrs_ext2 field, and a custom CPU:

runner = "qemu-s390x -cpu qemu,vx=on,vxeh=on,vxeh2=off -L /usr/s390x-linux-gnu"

I verified that toggling the vxeh2 flag is observed by the implementation.

Obviously that is not an automated test, so for now the details of the implementation go untested.

cc @taiki-e, hope I'm not stepping on your toes here, but this nerdsniped me.

@rustbot
Copy link
Collaborator

rustbot commented Jan 12, 2025

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @Amanieu (or someone else) some time within the next two weeks.

@folkertdev folkertdev force-pushed the s390x-feature-detected branch from 70eb1da to 96136d6 Compare January 12, 2025 20:17
@Amanieu Amanieu added this pull request to the merge queue Jan 16, 2025
Merged via the queue into rust-lang:master with commit 225e1ec Jan 16, 2025
60 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants