{"id":447,"date":"2022-06-07T22:26:39","date_gmt":"2022-06-07T20:26:39","guid":{"rendered":"https:\/\/threedots.ovh\/blog\/?p=447"},"modified":"2022-06-08T13:29:32","modified_gmt":"2022-06-08T11:29:32","slug":"quick-look-at-rosetta-on-linux","status":"publish","type":"post","link":"https:\/\/threedots.ovh\/blog\/2022\/06\/quick-look-at-rosetta-on-linux\/","title":{"rendered":"Quick look at Rosetta on Linux"},"content":{"rendered":"\n<p>Yesterday, Apple did release RosettaLinux as part of the macOS Ventura preview. Let&#8217;s take a first quick look&#8230;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Location<\/h2>\n\n\n\n<p>RosettaLinux is located at <code>\/Library\/Apple\/usr\/libexec\/oah\/RosettaLinux<\/code>. A <code>rosetta<\/code> ELF executable is present on that directory.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Does it do AoT?<\/h2>\n\n\n\n<p>No. Rosetta on Linux exclusively operates in JIT mode, at least for the time being.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Mapping to the VM<\/h2>\n\n\n\n<p>That directory is mapped through <code>virtiofs<\/code> to the virtual machine. <code>binfmt_misc<\/code> is then used to make execution attempts of x86_64 binaries run through Rosetta.<\/p>\n\n\n\n<p>When the Rosetta directory is mapped to the virtual machine, all of the VM runs in <em>Total Store Ordering<\/em> mode. This provides the guarantees needed by Rosetta to provide x86-compatible memory model semantics.<\/p>\n\n\n\n<p>If TSO mode is not present or not active on a given Arm platform, Rosetta explicitly does not provide those guarantees. It does <em>not<\/em> try to handle that use case. As such, to provide proper semantics on those environments, you can use <code>taskset<\/code> to bind applications using Rosetta to a single core.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Not-really-DSMOS*<\/h2>\n\n\n\n<p>Rosetta has a mechanism to restrict it to <code>Virtualization.framework<\/code> virtual machines. The <code>ioctl<\/code> is passed through <code>virtiofs<\/code> to the host.<\/p>\n\n\n\n<p>A re-creation of that mechanism is pasted below:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  char* AppleRosettaKey = \"Our hard work\\nby these words guarded\\nplease don't steal\\n Apple Inc\";\n\n  int fd = openat(AT_FDCWD ,\"\/proc\/self\/exe\", 0);\n\n  if (fd &lt; 0) {\n    rosetta_error(\"Unable to open \/proc\/self\/exe: %lu\", fd);\n  }\n\n  char key&#91;0x45];\n  int ioctl_result = ioctl(fd, _IOC(_IOC_READ, 0x61, 0x22, 0x45), key);\n\n  if (ioctl_result &lt; 0 || memcmp(key,AppleRosettaKey,0x45) != 0) {\n    rosetta_error(\n                 \"Rosetta is only intended to run on Apple Silicon with a macOS host \\\n                 using Virtualization.framework with Rosetta mode enabled\"\n                 );\n  }\n<\/code><\/pre>\n\n\n\n<p>As we can see, the mechanism is quite trivial to bypass. However, please rely on another solution if you&#8217;re running on non-Apple hardware.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Running it on non-Apple CPUs?<\/h2>\n\n\n\n<p>Running it on a Mac is fun, but what if we try to run it on other processors? <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Tegra Xavier testing<\/h3>\n\n\n\n<p>My first thought was the Tegra Xavier processor, which provides sequential consistency in hardware. As such, it satisfies the programmer-visible memory ordering constraints required for Rosetta to be functional. <\/p>\n\n\n\n<p>However, Rosetta relies on <code>FEAT_FlagM<\/code> flag manipulation instructions. Those are not implemented on Carmel. As such, I skipped over to another potential testing target.<\/p>\n\n\n\n<p>And the <code>CNTFRQ_EL0<\/code> timer frequency of 31.25MHz on Xavier doesn&#8217;t match with what Rosetta expects either.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Graviton3 testing<\/h3>\n\n\n\n<p>Which Arm platforms are easily accessible with flag manipulation instructions? There are some, such as the AWS Graviton3 processor, which uses Arm&#8217;s Neoverse V1 core.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>rosetta error: Unsupported counter frequency, check value of CNTFRQ_EL0\nTrace\/breakpoint trap<\/code><\/pre>\n\n\n\n<p>Rosetta supports <code>CNTFRQ_EL0<\/code> timer frequencies of 24 MHz and 1.00GHz, which is unlike the 1.05 GHz value used by the Graviton3 platform.<\/p>\n\n\n\n<p>Let&#8217;s override the value reported to Rosetta with 1.00 GHz. This is close enough for things to work fine for testing purposes. <\/p>\n\n\n\n<p>This allows to make a <a rel=\"noreferrer noopener\" href=\"https:\/\/browser.geekbench.com\/v5\/cpu\/compare\/15338732?baseline=15338946\" target=\"_blank\">Geekbench 5 run<\/a>, showing ~70% of native performance for Rosetta 2 on a c7g.large dual-core instance. Anecdotally, the HDR subtest of Geekbench anomalously gives higher performance inside of the Rosetta environment than outside for this configuration. <\/p>\n\n\n\n<p>However, a reminder that x86 memory ordering semantics aren&#8217;t provided is required to put that score into perspective.<\/p>\n\n\n\n<p><em>* Don&#8217;t Steal Mac OS X, the system used to restrict x86_64 macOS from running on non-Apple hardware.<\/em><\/p>\n\n\n\n<p><em>edit: fixing the buffer size for the sample DSMOS code.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Quick look at Rosetta on Linux.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"neve_meta_sidebar":"","neve_meta_container":"","neve_meta_enable_content_width":"","neve_meta_content_width":0,"neve_meta_title_alignment":"","neve_meta_author_avatar":"","neve_post_elements_order":"","neve_meta_disable_header":"","neve_meta_disable_footer":"","neve_meta_disable_title":"","footnotes":""},"categories":[1],"tags":[],"class_list":["post-447","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/threedots.ovh\/blog\/wp-json\/wp\/v2\/posts\/447","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/threedots.ovh\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/threedots.ovh\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/threedots.ovh\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/threedots.ovh\/blog\/wp-json\/wp\/v2\/comments?post=447"}],"version-history":[{"count":2,"href":"https:\/\/threedots.ovh\/blog\/wp-json\/wp\/v2\/posts\/447\/revisions"}],"predecessor-version":[{"id":449,"href":"https:\/\/threedots.ovh\/blog\/wp-json\/wp\/v2\/posts\/447\/revisions\/449"}],"wp:attachment":[{"href":"https:\/\/threedots.ovh\/blog\/wp-json\/wp\/v2\/media?parent=447"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/threedots.ovh\/blog\/wp-json\/wp\/v2\/categories?post=447"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/threedots.ovh\/blog\/wp-json\/wp\/v2\/tags?post=447"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}