Skip to content

DO NOT MERGE: refactor ukvm to add ukvm backend#150

Closed
djwillia wants to merge 4 commits intoSolo5:masterfrom
djwillia:monitors-squash
Closed

DO NOT MERGE: refactor ukvm to add ukvm backend#150
djwillia wants to merge 4 commits intoSolo5:masterfrom
djwillia:monitors-squash

Conversation

@djwillia
Copy link
Copy Markdown
Member

@djwillia djwillia commented Jan 6, 2017

This is the result of splitting ukvm into a top half and a bottom half in order to get a better understanding of the abstract ukvm interface and add another platform (MacOSX/Hypervisor.framework in addition to the original Linux/KVM). It works: I can run the same .ukvm binary with either uhvf-bin or ukvm-bin for the standalone tests and the Mirage tests I use (console, block, stackv4). It's still a bit rough, but I think it's high time to get some feedback now.

@mato @hannes, I know you guys don't run MacOSX, but I would appreciate your feedback even if you can't run it on your systems :)
@ricarkol hopefully it works on your mac!

As the ukvm directory was renamed to monitors, there is a change needed in the mirage tool if building mirage unikernels (see djwillia/mirage@841a9b2)

In addition to comments on the code itself, there are two major issues that we need to discuss:

  1. What to do about PVCLOCK. Hypervisor.framework doesn't have it (and there are reasons that something "trappable" is preferable for e.g., deterministic replay). At the moment, I've switched things to rdtsc but it's incomplete and hacky at the moment.

  2. What to do about the build tools. uhvf needs to be built on MacOSX to get the appropriate headers and link with the appropriate libraries. But most of the Mirage build typically happens (for me) using Docker for Mac, which means it's really happening in a Linux VM. I'm not sure what the best way is to make this happen seamlessly.

If you'd like it partitioned into separate commits or something, let me know!

@hannesm
Copy link
Copy Markdown
Contributor

hannesm commented Jan 9, 2017

  1. is the (for virtio already implemented) tscclock an option here?
  2. no clue whether there are usable cross-compilation toolchains to build MacOSX binaries on Linux (in a docker container) -- my usual approach is to build on the platform I target (if sufficient resources are available on the target). MirageOS (and OCaml) should also compile seamlessly on MacOSX (and then you won't need Docker, instead let opam drive the compilation) using homebrew (AFAIK, and I don't have a Mac)

@djwillia
Copy link
Copy Markdown
Member Author

djwillia commented Jan 9, 2017

  1. We don't have the means to calibrate the tscclock in the same way, as the ukvm interface does not emulate a i8254 hardware timer. It also does not emulate the RTC.

    That said, I think all the relevant info can be passed in via ukvm hypercall and then used in the implementation of a couple of functions similar to tscclock_monotonic() and tscclock_epochoffset(), which would be a bit more consistent with the tscclock implementation, although not much code would be shared.

  2. Apparently there are cross-compilation toolchains like https://github.com/tpoechtrager/osxcross (as pointed out by @justincormack on slack). Solo5 does not yet compile on MacOSX (though it's close thanks to your work getting it to compile on FreeBSD). I still like the idea of trying to keep everything for building in its own container, but this may not make sense here...

* the default value (0x1f80).
*/
unsigned default_mxcsr = 0x1f80;
__asm__ __volatile__("ldmxcsr %0\n" : : "m"(default_mxcsr));
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The odd thing is that I can't find a similar workaround in xHyve for the mxcsr value... how does it deal with this idiosyncracy I wonder.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I also looked (unsuccessfully) for some code in xHyve to give me a hint how to set the mxcsr from the hypervisor. I couldn't figure out how to write any value to that register in hypervisor context via Hypervisor.framework. My best guess at the moment is that this value is probably being initially set from within guest context, perhaps in some part of normal Linux boot.

@djwillia djwillia mentioned this pull request Jan 23, 2017
@mato
Copy link
Copy Markdown
Member

mato commented Jan 25, 2017

Starting with the two main points in @djwillia's first comment:

  1. Regarding PVCLOCK. The proposed change to ukvmclock where the monitor provides a new UKVM_PORT_TIME_INIT which hands the tsc_freq and rtc_boot values to the guest seems reasonable at first glance. However: It's unclear if tsc_freq can be reliably determined on Linux (and you acknowledge that in the function that uses /proc/cpuinfo). There may be something we can do using either MSRs or performance counters, however that may require root which would be bad.

    A bigger issue with the timekeeping implementation on the Hvf side is that it relies on trapping every RDTSC instruction. Keep in mind that timekeeping is extremely performance-sensitive, having every RDTSC cause a VMEXIT is going to be painfully slow.

  2. Regarding build tools, the situation thanks to Apple is just bad. While OSX-on-foo cross compilers exist, they rely on users manually downloading the Apple SDK, which is not redistributable (https://www.apple.com/legal/sla/docs/xcode.pdf) and requires an Apple ID to download. In practice I think this means building the OSX parts outside of OSX is not realistic (sorry Dan, your containers won't be redistributable). For a pure native OSX build, I would investigate doing things the other way round, i.e. when building uhvf build/install/otherwise get an ELF toolchain as part of the Solo5 build.

    This does not resolve the question of how the "specialised" uhvf should be built as part of e.g. a MirageOS build process in a container -- I don't have a good idea for this at the moment :-( I see that you've changed ukvm-configure to always try and build ukvm-bin and uhvf-bin, this won't work without an OSX toolchain...

General comments on the code (copied from paper notes, the diff is too big for me to comment on it directly on Github):

  • Could you please reformat the changes to use "4 spaces and not tabs"? At the moment there's an indentation mess which makes the diff hard to read.
  • You're not using an IDT and uhvf explicitly sets IDTR.base and IDTR.limit to zero. I'm surprised this works at all, I'd expect it to triple-fault and shutdown the VCPU on an exception. Have you verified that you can trap exceptions in uhvf?
  • pread_in_full() has an unnecessary change to lseek() / read(). AFAICT OSX has a pread() call, verified on a spare Mac I have.
  • ukvm-elf.h is CDDL, I think that needs to be replaced with a suitably licensed copy from one of the BSDs.
  • UKVM_PORT_POLL is changed to use pselect(), presumably due to the absence of ppoll() on OSX. This is fine, but we may want platform-dependent implementations of this in the future.
  • platform_vcpu_t should be int for KVM, not uint64_t.

Apart from these comments, nice work! The struct platform abstraction makes sense to me, but we need to think about how multi-arch will fit in, hence #151.

Also, I think the changes should be split up somehow. Need to print out(!) the diff and stare at it for a while, will follow up.

@mato
Copy link
Copy Markdown
Member

mato commented Apr 7, 2017

This has been superseded by #171, so I think we can close it?

@Kensan Kensan mentioned this pull request Apr 25, 2017
@mato
Copy link
Copy Markdown
Member

mato commented May 11, 2017

No one's complained and #171 is long since merged, so I'm closing this.

@mato mato closed this May 11, 2017
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