Thread (69 messages) 69 messages, 5 authors, 2021-03-18

Re: [PATCH v2 07/25] x86/sgx: Initialize virtual EPC driver even when SGX driver is disabled

From: Jarkko Sakkinen <jarkko@kernel.org>
Date: 2021-03-15 13:52:31
Also in: lkml

On Mon, Mar 15, 2021 at 03:04:59PM +0200, Jarkko Sakkinen wrote:
On Mon, Mar 15, 2021 at 04:13:17PM +1300, Kai Huang wrote:
quoted
On Sun, 14 Mar 2021 17:27:18 +0200 Jarkko Sakkinen wrote:
quoted
On Sun, Mar 14, 2021 at 05:25:26PM +0200, Jarkko Sakkinen wrote:
quoted
On Sat, Mar 13, 2021 at 09:07:36PM +0200, Jarkko Sakkinen wrote:
quoted
On Sat, Mar 13, 2021 at 09:05:36PM +0200, Jarkko Sakkinen wrote:
quoted
On Fri, Mar 12, 2021 at 01:44:58PM -0800, Sean Christopherson wrote:
quoted
On Tue, Mar 09, 2021, Kai Huang wrote:
quoted
Modify sgx_init() to always try to initialize the virtual EPC driver,
even if the SGX driver is disabled.  The SGX driver might be disabled
if SGX Launch Control is in locked mode, or not supported in the
hardware at all.  This allows (non-Linux) guests that support non-LC
configurations to use SGX.

Acked-by: Dave Hansen <redacted>
Signed-off-by: Kai Huang <redacted>
---
 arch/x86/kernel/cpu/sgx/main.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kernel/cpu/sgx/main.c b/arch/x86/kernel/cpu/sgx/main.c
index 44fe91a5bfb3..8c922e68274d 100644
--- a/arch/x86/kernel/cpu/sgx/main.c
+++ b/arch/x86/kernel/cpu/sgx/main.c
@@ -712,7 +712,15 @@ static int __init sgx_init(void)
 		goto err_page_cache;
 	}
 
-	ret = sgx_drv_init();
+	/*
+	 * Always try to initialize the native *and* KVM drivers.
+	 * The KVM driver is less picky than the native one and
+	 * can function if the native one is not supported on the
+	 * current system or fails to initialize.
+	 *
+	 * Error out only if both fail to initialize.
+	 */
+	ret = !!sgx_drv_init() & !!sgx_vepc_init();
I love this code.

Reviewed-by: Sean Christopherson <seanjc@google.com>
I'm still wondering why this code let's go through when sgx_drv_init()
succeeds and sgx_vepc_init() fails.

The inline comment explains only the mirrored case (which does make
sense).
I.e. if sgx_drv_init() succeeds, I'd expect that sgx_vepc_init() must
succeed. Why expect legitly anything else?
 
Apologies coming with these ideas at this point, but here is what this
led me.

I think that the all this complexity comes from a bad code structure.

So, what is essentially happening here:

- We essentially want to make EPC always work.
- Driver optionally.

So what this sums to is something like:

        ret = sgx_epc_init();
        if (ret) {
                pr_err("EPC initialization failed.\n");
                return ret;
        }

        ret = sgx_drv_init();
        if (ret)
                pr_info("Driver could not be initialized.\n");

        /* continue */

I.e. I think there should be a single EPC init, which does both EPC
bootstrapping and vepc, and driver initialization comes after that.
In other words, from SGX point of view, the thing that KVM needs is
to cut out EPC and driver part into different islands. How this is now
implemented in the current patch set is half-way there but not yet what
it should be.
Well conceptually, SGX virtualization and SGX driver are two independently
functionalities can be enabled separately, although they both requires some
come functionalities, such as /dev/sgx_provision, which we have moved to
sgx/main.c exactly for this purpose. THerefore, conceptually, it is bad to make
assumption that, if SGX virtualization initialization succeeded, SGX driver
must succeed -- we can potentially add more staff in SGX virtualization in the
future..

If the name sgx_vepc_init() confuses you, I can rename it to sgx_virt_init().
I don't understand what would be the bad thing here. Can you open that
up please? I'm neither capable of predicting the future...
Right, so since vepc_init() does only just device file initialization the
current function structure is fine. I totally forgot that sgx_drv_init()
does not call EPC initialization when I wrote the above :-) We refactored
during the inital cycle the driver so many times that I sometimes fix up
thing, sorry about.

To meld this into code:

        ret = sgx_vepc_init();
        if (ret != -ENODEV) {
                pr_err("vEPC initialization failed with %d.\n", ret);
                return ret;
        }

        ret = sgx_drv_init();
        if (ret != ENODEV)
                pr_info("Driver initialization failed %d.\n", ret);

This would also give more accurate information how far the initialization
went.

/Jarkko
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help