Running Mac OS X under qemu/KVM on AMD CPU

Due to the excellent work of Gabriel L.Somlo it is possible to run the emulated Mac OS X on Linux under Qemu/KVM. The changes seem to be minimal, and the operating system emulation works well – as long as you have the Intel CPU, that’s it.

If you have only the AMD CPU, the emulation only works without the KVM, i.e. when you run qemu without the -enable-kvm option. With this option the emulation hangs on the grey screen with Apple logo. Enabling the verbose boot (-v option to Chameleon) shows an empty black screen instead.

This happens because Qemu does not properly pass the CPU vendor to the virtualized CPU when using KVM. For example, booting the Linux DVD installation with the following options:

qemu-system-x86_64 -cpu core2duo openSUSE-13.1-DVD-x86_64.iso

and running cat /proc/cpuinfo | grep vendor prints the following:

vendor_id    : GenuineIntel

As you see, despite your host CPU being AMD, qemu properly emulates the Intel CPU and sets the options correctly.

However if you add -enable-kvm switch, and run:

qemu-system-x86_64 -enable-kvm -cpu core2duo openSUSE-13.1-DVD-x86_64.iso

and run cat /proc/cpuinfo | grep vendor you’ll see a rather ridiculous picture:

vendor_id    : AuthenticAMD

So the CPU model does not change. Since Mac OS X is supposed to only run on Intel CPU, we can assume Mac OS gets really confused when it does cpuid, and halts.

Now, there is a reason why Qemu is doing this. The reason is that the syscall emulation uses different instructions on AMD and Intel CPUs. So if the virtualized guest is specific to the CPU, and This is likely a bug in qemu for which the patch is submitted, but until it makes it upstream, you can apply the patch yourself:

+++ a/target-i386/cpu.c   2014-03-10 23:47:32.433412520 -0700
--- b/target-i386/cpu.c    2014-03-10 23:47:08.965411258 -0700
@@ -1863,7 +1863,7 @@
     const char *vendor = def->vendor;
     char host_vendor[CPUID_VENDOR_SZ + 1];
-    if (kvm_enabled()) { 
+    if (kvm_enabled() && def->name[0] == 'q' && def->name[1] == 'e' && def->name[2] == 'm' && def->name[3] == 'u' ) {
         uint32_t  ebx = 0, ecx = 0, edx = 0;
         host_cpuid(0, 0, NULL, &ebx, &ecx, &edx);
         x86_cpu_vendor_words2str(host_vendor, ebx, edx, ecx);

This patch forces the CPU vendor copy even when KVM is being used and a non-Qemu CPU is specified. With this patch Mac OS X installs and runs on the AMD CPU under kvm.

Update: the patch is not needed, as Hin-Tak Leung pointed out in comments, you can pass the vendor as string, and KVM would respect that:

qemu-system-x86_64 -enable-kvm -cpu core2duo,vendor=GenuineIntel openSUSE-13.1-DVD-x86_64.iso

 

This entry was posted in Uncategorized.

28 Responses to Running Mac OS X under qemu/KVM on AMD CPU

  1. Ace says:

    amazing! i would love to get OSX running in KVM!

    • George says:

      It does. 10.9 still doesn’t have keyboard working (most likely qemu issue), but the current qemu git head runs 10.8.5 just fine with the patches mentioned by Gabriel.

  2. Hin-Tak Leung says:

    10.9.2 dies with illegal opcode with that patch. This is still further than previous, which is just the stuck apple screen or black screen… after the not-genuine-intel-cpu message flashes by too quickly too be seen.

  3. Hin-Tak Leung says:

    Actually the patch is not needed – you can achieve similar outcome without patching, by specifying
    “-cpu core2duo,vendor=GenuineIntel” on the command line instead. That said, I still get kernel panic with illegal opcode. Apparently not all AMD CPUs are created equal.

  4. Hin-Tak Leung says:

    I sort of gave up on kvm and is now half-way with installation with full emulation now. I’ll be interested in your output of -cpu core2duo,enforce though. The enforce option tells you what the target has that the host cpu does not have. My amd cpu shows a dozen entries. Yours might be fewer or none.

    • George says:

      Here’s what I get:

      warning: host doesn’t support requested feature: CPUID.01H:EDX.ds [bit 21]
      warning: host doesn’t support requested feature: CPUID.01H:EDX.acpi [bit 22]
      warning: host doesn’t support requested feature: CPUID.01H:EDX.ss [bit 27]
      warning: host doesn’t support requested feature: CPUID.01H:EDX.ht [bit 28]
      warning: host doesn’t support requested feature: CPUID.01H:EDX.tm [bit 29]
      warning: host doesn’t support requested feature: CPUID.01H:EDX.pbe [bit 31]
      warning: host doesn’t support requested feature: CPUID.01H:ECX.dtes64 [bit 2]
      warning: host doesn’t support requested feature: CPUID.01H:ECX.ds_cpl [bit 4]
      warning: host doesn’t support requested feature: CPUID.01H:ECX.vmx [bit 5]
      warning: host doesn’t support requested feature: CPUID.01H:ECX.est [bit 7]
      warning: host doesn’t support requested feature: CPUID.01H:ECX.tm2 [bit 8]
      warning: host doesn’t support requested feature: CPUID.01H:ECX.xtpr [bit 14]
      warning: host doesn’t support requested feature: CPUID.01H:ECX.pdcm [bit 15]
      qemu-system-x86_64: Host’s CPU doesn’t support requested features

      As a side note, qemu is now fixed, and git head 315b59344126beab85a62b53582794b14436a5a4 works fine for me with no extra patches needed except e1000, with mouse and keyboard working both on 10.8.5 and 10.9.

      With KVM, could you post the actual crash screen (take a screenshot)?

  5. Hin-Tak Leung says:

    Argh, your amd cpu supports ssse3 (mine does not). Mine is also missing monitor. Apparently ssse3 is really important. As I wrote I am in the middle of a full emulation install, 24 hours and about half way. I’ll put the screendump somewhere when iI am done.

    • George says:

      You have probably a really old AMD cpu; mine is almost three year old.

      Monitor emulation could be added into KVM by a patch mentioned by Gabriel. This is why I asked if you applied this patch which adds monitor/mwait support.

      Regarding ss3, I wonder if your CPU announces (with KVM) that it supports it?

      Once your emulation finishes, you’d have another half-day configuration. It would probably be faster to add sse3 into KVM, there are like ten or so of them.

  6. Hin-Tak Leung says:

    If I read Gabriel’s post correctly, the patch isn’t needed for 10.9? Anyway, I also tried appending -ssse3, etc to the cpu option, and it paniced the same way. I guess since apple already checked cpuid, they don’t need to check cpu features… Would love that kvm can software-emulate some missing instructions. Yes, mine is 6 years old. I’ll rebase qmu/kvm when it is time to reboot to see if it helps. My current estimate is another day or so. Installed qcow is 4.7G after 34h cpu time (about 32h elapsed).

    • George says:

      Yes, I’ve read it, but I have this patch applied anyway. Not sure if it does anything, but I have no crashes.

      If I understand it correctly, KVM does not emulate those instructions at all (why it would? that’s regular ring3 userspace stuff, not some privileged instructions). So this needs to be written separately, and I’m unsure anyone would care to do that – I think pretty much anyone nowadays have CPUs younger than 6yo 🙂 although I’m surprised yours has svm but not sse3.

      Apple CPU is supposed to be Intel with sse3, I don’t know why they even care to do CPUID check. They probably just compiled the code with SSE3 optimization – even though it isn’t really necessary for kernel.

  7. Hin-Tak Leung says:

    Yes, I have svm but not ssse3. It is dual core 2.2Ghz & quite sufficient. Indeed I think apple simply apply all optimizations relevant to their limited range of hardware.

  8. Hin-Tak Leung says:

    I forgot where I kept the screenshots of the kernel panic , so here they are:
    http://htl10.users.sourceforge.net/tmp/

    I was doing them via gnome’s screenshot’ing, until I found qemu’s built-in. So there are missing the bottom few lines of the virtual screen. I have deleted some uninteresting ones from my earlier failure so I mistakenly thought I got rd of them. Anyway, here they are, the earliest failures.

    It is in a laptop so changing it would means a new machine…

    I don’t know how to make sense of it yet, but if ssse3 is the problem, crypto kext is probably where it would be used, as that’s all maths presumably. Please feel free to share, exp to those who might be able to understand it :-).

  9. Hin-Tak Leung says:

    Wikipedia says ssse3 is only added to amd cpus from 2011 onwards, so plenty non-ssse3 amd cpus out there. Other sources say corecrypto is fairly well-known to needs ssse3…

    • George says:

      Yes, there is certainly some use for it. But I’m afraid you’d need someone dedicated to add sse3 support into KVM (and even more dedication to have it accepted upstream, as people would probably be concerned about such a “useless” module size increase).

  10. Hin-Tak Leung says:

    Have a few correspondences with Gabriel, corecrypto dies on my CPU on the instruction pshufb .
    PSHUFB is an SSSE3 instruction. I should write up my experience, etc and put it under http://htl10.users.sourceforge.net/apple/ . Visit that in a few days and give me some comments, etc.

  11. kaazoo says:

    I was able to boot Mac OSX 10.9 on KVM running on Ubuntu 14.10 (has all needed versions of kernel, KVM, qemu, seabios, …) with the help of a modified mach_kernel from here: http://www.hackintoshosx.com/files/file/4201-mach-10-9-4-rc1-for-amd/

    My Ubuntu 14.10 itself is running inside a VM on KVM which runs on the Ubuntu 12.04 host. I’m using nested virtualization because I didn’t want to update my host system just for testing.

  12. Hin-Tak Leung says:

    My old machine served me well and finally died. The new machine can run OS X inside kvm as is, no custom kernels, no custom software on the host, and no hacks to the OS X guest either.

    • George says:

      Glad to hear that. Just to check, you can’t run Yosemite either (it doesn’t boot due to non-EFI bootloader in qemu), am I right?

      • Hin-Tak Leung says:

        That’s somewhat correct. At the boot into the installer stage (in an upgrade), it either (1) boot the old system (with a dated chameleon), (2) dies very painfully (with up-to-date chameleon), (2) do something, video flashes by, then go back to the boot loader prompt (with an upacked yosemite kernel + up-to-date chameleon).
        Also tried installing fresh and it didn’t work; though it may simply be with the old
        chameleon. Recent chamelon has some yosemite-specfic enhancements, and supposedly work in bare-metal systems…

        Also tried Virtual Box, and didn’t get very far; though it appears that some people have success running Yosemite with virtual box.

        • Hin-Tak Leung says:

          Sorry, I meant (3) – with a yosemite kernel and up-to-date chameleon it does start the access and unpack the kerrnel cache, but seem not to be able to start graphics, I don’t now why.

    • Mike says:

      Could you share, what CPU that is? Is it an AMD again? I have the same problem, that you had on a Phenom 2 missing SSSE3. Running OS X without KVM is painfully slow. 🙂

  13. Hin-Tak Leung says:

    I counted 4 people (including the writer) in
    https://macosxvirtualmachinekvm.wordpress.com/guide-mac-os-x-vm-on-unraid/
    who are able to get yosemite to work; I have no luck – had the EBIOS error as well as it just rebooting after loading all the kernel extensions. I might go in and compile chameleon with EBIOS disabled (it is in libsaio/disk.c) or watch more carefully what happened just before reboot next. Please feel free to beat me to it and/or report whether you can get it to work.

    • ysrj says:

      u can just copy files in /extra/extensions into /system/library/extensions,i mean copy,keep the files in /extra/extensions.i had the ebios error when i remove /extra/extensions or empty the files in /extra/extensions

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.