Skip to content

kernel: Refactoring for multi-arch support#192

Merged
mato merged 14 commits intoSolo5:masterfrom
mato:multiarch
May 11, 2017
Merged

kernel: Refactoring for multi-arch support#192
mato merged 14 commits intoSolo5:masterfrom
mato:multiarch

Conversation

@mato
Copy link
Copy Markdown
Member

@mato mato commented Apr 24, 2017

This is the guest-side follow-up to #171, refactoring the kernel side to allow for multi-arch support.

Briefly, this separates out the kernel arch-specific code into cpu_<architecture>.[ch] and cpu_vectors_<architecture>.S. It also includes the build system infrastructure needed for multiarch. See individual commits for details.

/cc #151 #190

mato added 5 commits April 24, 2017 12:24
This is the first step for multi-arch support in the ukvm guest.
Arch-specific code (currently only x86_64) is factored out from all over
the codebase into cpu_x86_64.c and cpu_x86_64.h.

The assembly code in cpu.S has been replaced with either inline
functions in cpu_x86_64.h or directly with inline assembly in
cpu_x86_64.c.

As part of this change the virtio early bootstrap (boot.S) is modified
to initialise the CPU into the same state as is used by the ukvm target,
so that the two targets can share the cpu_init() code.
The kernel build now detects architecture-dependent portions at build
time, allowing for adding additional architectures.
Follow conventions and rename symbols to where they are now defined.
This was referenced Apr 24, 2017
@mato
Copy link
Copy Markdown
Member Author

mato commented Apr 24, 2017

@djwillia @ricarkol (and anyone else interested) Please review...

@Weichen81
Copy link
Copy Markdown
Contributor

@mato I have reviewed the changes. I think they can make ARM64 guest side code landing easily.
I have some concern about the build scripts. Can we provide an option for user to select ukvm or
virtio? Because these two kernels are exclusive while we are using opam install. And the ARM64 porting
currently can only work with ukvm :)

Regards,
Wei Chen

@mato
Copy link
Copy Markdown
Member Author

mato commented Apr 25, 2017

@Weichen81 I would just add a check to force BUILD_VIRTIO=no when the target architecture is not x86_64. FWIW you can already build ukvm only by doing make ukvm at the top level.

}

/* keeps track of how many stacked "interrupts_disable"'s there are */
int intr_depth = 1;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should this be volatile since it may be accessed by nested interrupts?

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.

Per the comment in idt_fillgate() (https://github.com/mato/solo5/blob/multiarch/kernel/cpu_x86_64.c#L57), we run all interrupt handlers with interrupts disabled. So this should be fine as is.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Sorry I misread, I wrongly had the impression that the variable was also accessed when handling exceptions/traps.

@mato
Copy link
Copy Markdown
Member Author

mato commented Apr 27, 2017

@Kensan @diwillia I have pushed 2ef936d to address the outcome of our discussion about consolidating x86 FPU/SSE unit setup in #190. This compiles and passes all tests on both Linux and FreeBSD. Please take a look and let me know what you think.

(Edit: Out of band discussion with @Kensan and @djwillia about this led to the outcome discussed below in #192 (comment))

@Kensan
Copy link
Copy Markdown
Contributor

Kensan commented Apr 28, 2017

@mato The change looks fine to me.

A note regarding Muen/#190: I will want to override fpu_init() (by splitting it into a separate compilation unit) since the control register accesses create traps. On Muen I really only want to perform the MXCSR initialization part. Will adapt #190 accordingly once this PR lands on master.

mato added 3 commits May 3, 2017 16:21
- Make FPU and SSE unit setup consistent with ukvm target.
- Move bootstrap stack and page tables into the correct linker sections.
- Rename .bootstrap to .data.multiboot and include it at the start of
  the .text section.

The last two points save us some kilobytes of unnecessary image size and
remove the oddity of the virtio text segment "starting" at 0x101000.
This hasn't caught us till now as GCC is much more conservative in
enabling FPU/SSE optimizations. Clang on the other hand will happily use
these at -O2.
mato added 6 commits May 4, 2017 12:21
As per the comment, see also discussion of point (3) in
mirage/mirage-solo5#15.
The GDT descriptor values should be consistent with those set up by
ukvm. Recalculate the values based on those defined in
ukvm/ukvm_cpu_x86_64.c and also used them in the virtio bootstrap GDT.
Add a platform_init() hook for plaform-specific initialiazation. This is
primarily to support the upcoming Muen port.

For virtio, move the resposibility for calling platform_intr_init() to
platform_init() since that's where it belongs.
1. Move more platform-specific initialization (virtio multiboot) into
platform_init(). This allows us to unify mem.c between virtio and ukvm,
which was until now essentially duplicate code.

2. While doing this, clean up the "memory size" vs. "maximum address"
confusion in mem.c and improve the stack guard and memory sizing logic.

3. Rename the virtio early boot and startup functions (in boot.S and
kernel.c) to better reflect their purposes. This unifies the virtio and
ukvm startup flow as much as possible.
1. There are no plans to port virtio to !x86_64, so don't do that.
2. FreeBSD will need extra work due to use of clang, so refuse to build
on !x86_64 there as well.
@mato
Copy link
Copy Markdown
Member Author

mato commented May 5, 2017

I've reworked these changes to incorporate the outcome of the out-of-band discussions around FPU/SSE setup, which was to keep things as they are for now (i.e. do the majority of setup on the monitor side) and add a platform_init() which can be used for platform-specific initialisation such as LDMXCSR for the Muen port.

This led to somewhat more refactoring than I expected, mostly on the virtio side. The outcome of this is that I've managed to unify and clean up mem.c for both platforms which is a good thing. Also, the virtio initialisation / bootstrap flow is now much clearer. See the individual commits for details.

While I was at it I also excised / #ifdef'd most of the remaining arch-dependent code with the exception of the call to tscclock_init() from time_init() on the ukvm side.

@Weichen81: You'll need to add an appropriate clock for ARM64 and #ifdef the call to it's init function (if any). I've also addressed your comment about not building virtio on !x86_64.

@djwillia Please take a look and let me know if this is OK to merge.

@Weichen81
Copy link
Copy Markdown
Contributor

Weichen81 commented May 5, 2017 via email

Copy link
Copy Markdown
Collaborator

@ricarkol ricarkol left a comment

Choose a reason for hiding this comment

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

Hi @mato , sorry for the late reply. Reviewed the code and all looks good.


.text :
{
*(.data.multiboot)
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 multiboot header won't be aligned as before. It seems like it just has to be aligned at 4 bytes (which is taken care of). Just checking (so GCE doesn't have to be tested).

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.

That's correct. The requirements are that the header be within the first 8k of the executable and be 4-byte aligned, both of which are taken care of. I tested GCE with these commits and everything works.

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.

Awesome, thanks for the test.

gdt64:
.quad 0x0000000000000000
.quad 0x00af9b000000ffff /* 64bit CS */
.quad GDT_DESC_CODE_VAL /* 64bit CS */
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.

New value is 0x00af99000000ffff which I think changes the limit field. It has a new limit of 0x9ffff (before was 0xbffff). Memory can grow up to 2.5 GB now. Not much difference really but wonder why the change.

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.

It does not, LIMIT is bits (0 - 15) and (48 - 51) all of which are 1. The values were taken directly from the result of the computation in ukvm_x86_setup_gdt(). The reason I made this change was to deliberately remove any confusion/differences between the values used by ukvm and those used by virtio.

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.

You are right, sorry for the confusion. The field changed is type which for a code segment means:

before: 0x00af9b000000ffff -> type = 0xb (Execute-Only, accessed)
now: 	0x00af99000000ffff -> type = 0x9 (Execute/Read, accessed)

*/

#include "multiboot.h"
#include "../cpu_x86_64.h"
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.

might want to rename boot.S to boot_x86_64.S

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.

We can do that if (unlikely) virtio ever gets ported to a non x86_64 architecture.

@ricarkol
Copy link
Copy Markdown
Collaborator

LGTM (just in case)

@mato mato merged commit 8dc4934 into Solo5:master 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