On 5/12/2017 6:11 PM, Andy Lutomirski wrote:
On Thu, May 11, 2017 at 9:56 PM, Huang, Kai <kai.huang@xxxxxxxxxxxxxxx>
wrote:
I am not sure whether the cost of writing to 4 MSRs would be
*extremely*
slow, as when vcpu is schedule in, KVM is already doing vmcs_load,
writing
to several MSRs, etc.
I'm speculating that these MSRs may be rather unoptimized and hence
unusualy slow.
Have a percpu variable that stores the current SGXLEPUBKEYHASH along
with whatever lock is needed (probably just a mutex). Users of EINIT
will take the mutex, compare the percpu variable to the desired
value,
and, if it's different, do WRMSR and update the percpu variable.
KVM will implement writes to SGXLEPUBKEYHASH by updating its
in-memory
state but *not* changing the MSRs. KVM will trap and emulate
EINIT to
support the same handling as the host. There is no action
required at
all on KVM guest entry and exit.
This is doable, but SGX driver needs to do those things and expose
interfaces for KVM to use. In terms of the percpu data, it is nice to
have,
but I am not sure whether it is mandatory, as IMO EINIT is not even in
performance critical path. We can simply read old value from MSRs
out and
compare whether the old equals to the new.
I think the SGX driver should probably live in arch/x86, and the
interface could be a simple percpu variable that is exported (from the
main kernel image, not from a module).
FWIW, I think that KVM will, in the long run, want to trap EINIT for
other reasons: someone is going to want to implement policy for what
enclaves are allowed that applies to guests as well as the host.
I am not very convinced why "what enclaves are allowed" in host would
apply
to guest. Can you elaborate? I mean in general virtualization just
focus
emulating hardware behavior. If a native machine is able to run any
LE,
the
virtual machine should be able to as well (of course, with guest's
IA32_FEATURE_CONTROL[bit 17] set).
I strongly disagree. I can imagine two classes of sensible policies
for launch control:
1. Allow everything. This seems quite sensible to me.
2. Allow some things, and make sure that VMs have at least as
restrictive a policy as host root has. After all, what's the point of
restricting enclaves in the host if host code can simply spawn a
little VM to run otherwise-disallowed enclaves?
What's the current SGX driver launch control policy? Yes allow
everything
works for KVM so lets skip this. Are we going to support allowing
several
LEs, or just allowing one single LE? I know Jarkko is doing in-kernel LE
staff but I don't know details.
I am trying to find a way that we can both not break host launch control
policy, and be consistent to HW behavior (from guest's view).
Currently we
can create a KVM guest with runtime change to IA32_SGXLEPUBKEYHASHn
either
enabled or disabled. I introduced an Qemu parameter 'lewr' for this
purpose.
Actually I introduced below Qemu SGX parameters for creating guest:
-sgx epc=<size>,lehash='SHA-256 hash',lewr
where 'epc' specifies guest's EPC size, lehash specifies (initial)
value of
guest's IA32_SGXLEPUBKEYHASHn, and 'lewr' specifies whether guest is
allowed
to change guest's IA32_SGXLEPUBKEYHASHn at runtime.
If host only allows one single LE to run, KVM can add a restrict that
only
allows to create KVM guest with runtime change to IA32_SGXLEPUBKEYHASHn
disabled, so that only host allowed (single) hash can be used by
guest. From
guest's view, it simply has IA32_FEATURE_CONTROL[bit17] cleared and has
IA32_SGXLEPUBKEYHASHn with default value to be host allowed (single)
hash.
If host allows several LEs (not but everything), and if we create
guest with
'lewr', then the behavior is not consistent with HW behavior, as from
guest's hardware's point of view, we can actually run any LE but we
have to
tell guest that you are only allowed to change IA32_SGXLEPUBKEYHASHn
to some
specific values. One compromise solution is we don't allow to create
guest
with 'lewr' specified, and at the meantime, only allow to create
guest with
host approved hashes specified in 'lehash'. This will make guest's
behavior
consistent to HW behavior but only allows guest to run one LE (which is
specified by 'lehash' when guest is created).