I got to the point with my hobby x86_64 UEFI kernel where user code calls system code, but it generates general protection fault with error code 0 at 0x1B:0x0 (0x1B is the user mode code segment selector). Single stepping it i realized that SYSRET does not return to the address held in RCX but to zero instead. I debug with qemu-system-x86_64 with and without KVM. Attached two screenshots about the phenomenon. Could anyone please explain this, and tell me what do i do wrong?
MSR 0xC0000080 = 0x0000000000000501
MSR 0xC0000081 = 0x001B00083D906D79
MSR 0xC0000082 = 0x000000003D906D79
MSR 0xC0000083 = 0x000000003D906D79
MSR 0xC0000084 = 0x0000000000000300
Interrupts disabled using both cli and Local APIC's entries.
GDT:
{ 0, 0, 0, 0x9A, 0x20, 0 }; // 0x08 ring 0 code
{ 0, 0, 0, 0x92, 0x00, 0 }; // 0x10 ring 0 data
{ 0, 0, 0, 0xFA, 0x20, 0 }; // 0x1B ring 3 code
{ 0, 0, 0, 0xF2, 0x00, 0 }; // 0x23 ring 3 data
{ 0, 0, 0, 0xFA, 0x20, 0 }; // 0x2B ring 3 code
{ 0, 0, 0, 0xF2, 0x00, 0 }; // 0x33 ring 3 data
typedef struct PACKED ENTRY
{
U16 limit_0_15;
U16 base_0_15;
U8 base_16_23;
U8 access;
U8 granularity;
U8 base_24_31;
} ENTRY, *PENTRY;
EDIT: After reading again the instruction manual, i noticed that in long mode the return CS will be (STAR.SYSRET_CS + 16) | 3 so i duplicated the user mode segment descriptors just to be sure, but the results are the same.

