iansjack wrote:
Presumably you are using the qemu-sgx version as, I believe, the standard version of qemu doesn't support SGX.
Yes, I am using qemu-sgx with correct SGX options tested by Linux guest. So this would not be a problem.
iansjack wrote:
Anyway, that doesn't solve your immediate problem. From what you have said, my guess would be that your mapping of the page containing the instructions you are trying to execute isn't configured to allow execution by user-mode code. It's difficult to think of any other fault that would prevent execution of a "non" instruction.
YES! I finally found the mistake just now. I forgot to set the U/S bit of the page table entry, hence once switched to ring 3, page fault occurs. After I set this bit, things went well.
But now a new bug occurs. When I try to test the exception handler in ring-3 by triggering a simple divide error, I found it cannot switch back to ring-0 correctly. I have set the rsp of the TSS to the kernel stack addr. For the IDT entries, I set the selector to the kernel code segment index 0x8,and also set the DPL to 0. But it's weird that once getting into the exception handler, the CS register will have value 0xb, which is (0x8 | 0x3), somehow meaning that it did not switch back to ring-0.
I am wondering if I miss some important configuration or setup for the CPU or kernel to correctly switch back to ring-0 once exception occurs in ring-3. But up to now, I cannot find any useful information.
iansjack wrote:
Do you have a link to a repository of your code?
Yes, this is my fork of Unikraft, a light-weighted unikernel. The link to my repo is
https://github.com/xymeng16/unikraftIn case you kindly want to go through the code briefly, I hereby point out some important source code files:
1. plat/kvm/x86/traps.c sets the GDT TSS and IDT
2. plat/common/x86/traps.c defines and registers the exception handler, and the real entry point of the handlers are defined in plat/kvm/x86/cpu_vectors_x86_64.S
3. lib/uksgx/sgx_utils.c defines switch_to_ring3() and it is invoked by lib/uksgx/sgx_ioctl.c:sgx_ioc_enclave_create(), user application (in this unikernel application also runs under ring 0) use the ioctl() manner to cooperate with SGX device. I am porting SGX driver right now.
Thanks for your help!