Arm desktop: emulation

This post is part 5 of the "Let me try to use an AArch64 system as a desktop" series:

  1. AArch64 desktop: day one
  2. AArch64 desktop: day two
  3. AArch64 desktop: last day
  4. Arm desktop: 2025 attempt, part one
  5. Arm desktop: emulation

Whenever people use a non-x86 system, sooner or later someone asks: “But can it run [name of x86-64 only binary]?”. So, let’s check how to make it possible.

Software stack

When you look for ‘how to run x86-64 apps on Fedora/Arm’, you usually end up with Asahi’s documentation about it.

It is a good thing to read to understand the stack. But if your Arm system runs a 4K page size kernel, then most of that documentation can be skipped. You would not need muvm nor binfmt-dispatcher packages.

What you need is FEX-emu, and nothing else, as it recommends all required components.

To make it easier, I recommend removing some of QEMU packages: dnf remove qemu-static-* so only FEX-emu will be used for running foreign architecture binaries.

Checking emulation

Installing FEX-emu should also install the Fedora/x86-64 rootfs. So, let check if emulation is working:

$ uname -m
aarch64

$ FEXBash "uname -m"
erofsfuse 1.8.9
<W> erofs: /usr/share/fex-emu/RootFS/default.erofs mounted on /run/user/1000/.FEXMount2262322-Fjd32T with offset 0
x86_64

If you have errors at this stage, then check what you have in the /usr/lib/binfmt.d/ directory. There should be only two files:

$ ls /usr/lib/binfmt.d/ -l
-rw-r--r--. 1 root root 198 07-13 02:00 FEX-x86_64.conf
-rw-r--r--. 1 root root 195 07-13 02:00 FEX-x86.conf

Geekbench 6

So, let me check speed of the emulated CPU. I ran Geekbench 6 on it:

CPU Information
  Name                  Neoverse N1
  Topology              1 Processor, 80 Cores
  Identifier            GenuineIntel Family 6 Model 166 Stepping 1
  Base Frequency        3.00 GHz
  L1 Instruction Cache  32.0 KB x 80
  L1 Data Cache         32.0 KB x 80
  L2 Cache              512 KB x 80
  L3 Cache              8.00 MB
  Instruction Sets      sse2 sse3 pclmul fma3 sse41 aesni avx avx2 shani vaes

Test results were awful:

That’s the level of an Intel Atom CPU from 2021. My AMD Ryzen 5 3600 has much better results.

Can it be better?

I asked FEX-Emu developers a few days ago with this kind of question. There are several Arm CPU features that can be used to make emulation faster:

Section Features
Crypto AES, CRC, SHA, PMULL
TSO emulation Apple Silicon TSO bit, LRCPC, LRCPC2, LSE2
Flags stuff AFP, FlagM, FlagM2
Atomic operations LSE
Misc FCMA, FRINTTS, RPRES, SVE, SVE_bitperm
Future RCPC3, CSSC, RAND

The Ampere Altra is an old, Arm v8.2 CPU. Its Neoverse-N1 cores are from 2019 and can support only a small subset of entries from the table above: all crypto ones + LSE and LRCPC.

Tips and tricks

After publishing post I got some additional hints from FEX-emu folks to make emulation a bit faster.

One is reducing precision of x86 FPU, second is disabling TSO. So my configuration file (“~/.fex-emu/Config.json”) looks like this now:

{
  "Config": {
    "RootFS": "/usr/share/fex-emu/RootFS/default.erofs",
    "X87ReducedPrecision": "1",
    "TSOEnabled": "0"
  },
  "ThunksDB": {
    "GL": 1,
    "Vulkan": 1
  }
}

This gave Factorio a visible speed-up. Cannot compare Geekbench results cause it crashes randomly after configuration changes.

Steam

Now that we have sorted out software, let’s start with games (because what else would you do with x86(-64) emulation?). Which usually means Steam.

First of all, we need Steam package. I took it from the RPM Fusion non-free page. The next step is installation. This is done without dependencies (those will be provided by the FEX-emu rootfs), and we need to tell RPM that the architecture of the package is not that important:

$ sudo rpm -i steam-1.0.0.82-3.fc42.i686.rpm --nodeps --ignorearch

The next step is the Steam installation, where we run it under emulation:

FEXBash steam

It can take some time, but at the end you should get the Steam window:

Steam
Steam

So now we are ready to play some games, right?

Factorio

As you may know from one of my previous posts, I am addicted to the the Factorio game. So how it goes on an Ampere Altra-based system?

Factorio
Factorio

Let me be honest: without tweaking FEX-Emu config it was unplayable. At least not with my saved games, in 3440x1440 resolution. What was 60/60 on a Ryzen 5 3600 went to 8-11/59.5 ;(

After tweaking FEX-Emu configuration Factorio started to be more playable. In areas with many robots it was running at 16-25 FPS and there were moments with close to 60/60 but it had to be close zoom to deserted area. I may consider attempt to finish game during 100 hours.

A funny story

A few days ago, @chenlin3 added Ninja build solution for EDK2 build system. I took a look at that change.

At first, I built the ALTRA8UD-1L2T firmware without using Ninja. It took 30 seconds (11 minutes of total CPU time). Then I did a run with Ninja. It took 2 minutes (72 minutes of total CPU time).

Hmm… It should be much faster. I retried and looked at the htop window. And I saw a lot of “FEXInterpreter” lines… So it was running in emulation.

I then replaced the x86-64 binary of Ninja with a symlink to the aarch64 one, and then it was a visible improvement.

I commented on the pull request with a NAK.

Is it worth using?

So, the final question is: “Is it worth using x86(-64) emulation at all?”…

I do not plan to use it much. I may try to play some older games like Torchlight II, which I managed to run once and then it stopped working.

aarch64 computers desktop fedora

Comments?

If you want to comment, head over to my post on Mastodon.