Skip to content

std_detect: Workaround Exynos 9810 bug on aarch64 Android #1378

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

Merged
merged 3 commits into from
Feb 13, 2023

Conversation

taiki-e
Copy link
Member

@taiki-e taiki-e commented Feb 10, 2023

Samsung Exynos 9810 has a bug that big and little cores have different ISAs. And on older Android (pre-9), the kernel incorrectly reports that features available only on some cores are available on all cores.

See https://reviews.llvm.org/D114523 for details. That patch is about FEAT_LSE, but IIUC the detection of most features that are available in armv8.2-a but may not be available in armv8.0-a should be affected by this issue.

@rustbot
Copy link
Collaborator

rustbot commented Feb 10, 2023

r? @Amanieu

(rustbot has picked a reviewer for you, use r? to override)

@taiki-e taiki-e force-pushed the std-detect-aarch64-android branch from a22f460 to 12e7cbc Compare February 10, 2023 22:37
bors bot added a commit to taiki-e/portable-atomic that referenced this pull request Feb 11, 2023
76: detect: Workaround Exynos 9810 bug on aarch64 Android r=taiki-e a=taiki-e

Samsung Exynos 9810 has a bug that big and little cores have different ISAs. And on older Android (pre-9), the kernel incorrectly reports that features available only on some cores are available on all cores.

See https://reviews.llvm.org/D114523 for details.

Our own run-time detection code has not been released yet and is not a problem, but portable-atomic < 1.1 may have been affected by this issue since rustc 1.69-nightly when is_aarch64_feature_detected supported run-time detection on Android. (rust-lang/stdarch#1351, rust-lang/rust#105784)

A patch on stdarch side: rust-lang/stdarch#1378

Co-authored-by: Taiki Endo <[email protected]>
@taiki-e
Copy link
Member Author

taiki-e commented Feb 11, 2023

Hmm, I tested exynos (but 9825 since the problematic 9810 was not available) with Samsung remote test lab and it seems that ro.arch returns an empty string. So this may not actually work. EDIT: this is not a problem, see #1378 (comment)

An alternative would be to query OS version (ro.build.version.release, which works in the above environment) to exclude problematic versions...

@taiki-e taiki-e marked this pull request as draft February 11, 2023 09:22
@lu-zero
Copy link
Contributor

lu-zero commented Feb 11, 2023

If you can confirm, I'm fine with the approach.

@taiki-e
Copy link
Member Author

taiki-e commented Feb 11, 2023

Ah, it appears that ro.arch is actually a field that was removed in Android 12. The above case used Android 12, but Android 10 and Android 11 return a valid value (with both the getprop command and the __system_property_get function).

ro arch android10

ro arch android11

It is fine that ro.arch is not available for Android 12+ because Android 9+ includes the fix.
So, I believe that this PR is fine as is.

@taiki-e taiki-e marked this pull request as ready for review February 11, 2023 11:03
@lu-zero
Copy link
Contributor

lu-zero commented Feb 11, 2023

Maybe add to the comment that bit of additional information.

arch.as_mut_ptr() as *mut libc::c_char,
)
};
if len > 0 && arch.starts_with(b"exynos9810\0") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this checking that the returned string starts with exynos9810 or that it is exactly equal to exynos9810? In the former case you wouldn't want the \0 in the string.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I originally meant the latter, but looking at the LLVM patch they seem to be using the former.

So, I removed \0 to match the LLVM patch's behavior.

)
};
if len > 0 && arch.starts_with(b"exynos9810\0") {
return cache::Initializer::default();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We still want to probe for v8.0 features such as aes/sha/crc32.

Copy link
Member Author

@taiki-e taiki-e Feb 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC this is a bit tricky because even the armv8.0 optional features may not be consistent between little and big.

So for now, all I can think of is one of the following

  • Only check features that are known to be available on exynos-m3 (armv8.0 cores 1).
    (According to cmd/compile: go binaries not working on exynos 64 bit CPUs golang/go#28431) The old kernel seems to return auxv/cpuinfo based on features available on cortex-a55 (armv8.2 cores 1), so it can properly handle features even if they are available on exynos-m3 but not on cortex-a55 (though such features probably do not exist 2).
  • Continue detection on Android 9+ and return default value on pre-9.

The first one seems to make more sense, as it does not require additional __system_property_get to get the version and works on older kernels.

Footnotes

  1. https://en.wikichip.org/wiki/samsung/exynos/9810 2

  2. At least, all the target features in the output of rustc --print cfg --target aarch64-linux-android -C target-cpu=exynos-m3 are also included in the output of rustc --print cfg --target aarch64-linux-android -C target-cpu=cortex-a55.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented the first approach in 9ce03f1.

Samsung Exynos 9810 has a bug that big and little cores have different
ISAs. And on older Android (pre-9), the kernel incorrectly reports
that features available only on some cores are available on all cores.

https://reviews.llvm.org/D114523
@taiki-e taiki-e force-pushed the std-detect-aarch64-android branch from 12e7cbc to 0adfbec Compare February 12, 2023 05:55
@taiki-e
Copy link
Member Author

taiki-e commented Feb 12, 2023

Maybe add to the comment that bit of additional information.

Added comment about ro.arch on Android 12+ on Exynos.

@taiki-e taiki-e force-pushed the std-detect-aarch64-android branch from a873d1a to 9ce03f1 Compare February 12, 2023 07:25
This module is already `#[cfg(target_arch = "aarch64")]`.
@Amanieu Amanieu merged commit a428958 into rust-lang:master Feb 13, 2023
@taiki-e taiki-e deleted the std-detect-aarch64-android branch February 13, 2023 02:18
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.

4 participants