Skip to content

Conversation

@ALSchwalm
Copy link
Collaborator

This patchset make some significant changes to the allocation layout
of Mythril. Now, instead of heap allocation of devices and virtual
machines, these are allocated in the following way:

There is a static 'VirtualMachineSet' object that contains a list
of virtual machines and associated message passing contexts. This
structure is how inter-core and inter-vm communication occurs. Each
'VirtualMachine' now contains an ArrayVec of 'DynamicVirtualDevice'.

A 'DynamicVirtualDevice' is a wrapper around various EmulatedDevice
types that are not part of the required guest architecture. For
example, a given PCI device is 'dynamic' in the sense that we cannot
state that it is part of the guest at compile time.

Non-dynamic EmulatedDevices are now stored explicitly as part of the
'StaticVirtualDevices' field of the 'VirtualMachine'. This makes it
significantly easier to reference a particular part of the guest
architecture (rather than having to look up a device by Port, for
example).

I also removed the stub EmulatedDevices we had and just started
ignoring the portio operations that are mapped to devices we don't
emulate. I believe this is the right move, architecturally. It may not
be the correct thing to do for memory mapped devices, but they
should trigger an EPT violation anyway.

This patch make some significant changes to the allocation layout
of Mythril. Now, instead of heap allocation of devices and virtual
machines, these are allocated in the following way:

There is a static 'VirtualMachineSet' object that contains a list
of virtual machines and associated message passing contexts. This
structure is how inter-core and inter-vm communication occurs. Each
'VirtualMachine' now contains an ArrayVec of 'DynamicVirtualDevice'.

A 'DynamicVirtualDevice' is a wrapper around various EmulatedDevice
types that are _not_ part of the required guest architecture. For
example, a given PCI device is 'dynamic' in the sense that we cannot
state that it is part of the guest at compile time.

Non-dynamic EmulatedDevices are now stored explicitly as part of the
'StaticVirtualDevices' field of the 'VirtualMachine'. This makes it
significantly easier to reference a particular part of the guest
architecture (rather than having to look up a device by Port, for
example).
Without this patch, it's possible to declare a per-core variable
like so:

    declare_per_core! {
        static mut TIMER_WHEEL: Option<TimerWheel> = None;
    }

Then access the variable like:

    unsafe {
        TIMER_WHEEL = Some(value);
    }

But this will always mutate the value on the BSP core (and is not
thread-safe). This patch generates a new symbol for the actual
static variable, which effectively requires the usage of the
'get_per_core' or 'get_per_core_mut' and prevents this category
of error.
Copy link
Contributor

@dlrobertson dlrobertson left a comment

Choose a reason for hiding this comment

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

I actually really like the static device and dynamic device change... I think it helps simplify things a bit as we start developing more of the emulated devices

@ALSchwalm ALSchwalm merged commit af161a4 into master Feb 26, 2021
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.

3 participants