to facilitate tests which switches privilege during the course of its run.
This is achieved by providing a dpl3 IDT entry which restores %esp and jumps
to the %eip found in the exception frame.
Therefore, 'int $0x20' acts as function call which returns at the kernels cpl.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
add $8, %esp /* Pop error_code/entry_vector. */
env_IRET
+
+
+ENTRY(entry_ret_to_kernel) /* int $0x20 (return to kernel) */
+
+ /* User required to ensure this is called from CPL > KERNEL_RPL */
+
+ mov 0*4(%esp), %eax /* Stash %eip from iret frame */
+ mov 3*4(%esp), %esp /* Load %esp from iret frame */
+ jmp *%eax /* Jump back */
add $8, %rsp /* Pop error_code/entry_vector. */
env_IRETQ
+
+
+ENTRY(entry_ret_to_kernel) /* int $0x20 (return to kernel) */
+ env_ADJUST_FRAME
+
+ mov 0*8(%rsp), %rax /* Stash %rip from iret frame */
+ mov 3*8(%rsp), %rsp /* Load %esp from iret frame */
+ jmp *%rax /* Jump back */
void entry_MC(void);
void entry_XM(void);
void entry_VE(void);
+void entry_ret_to_kernel(void);
hw_tss tss __aligned(16) =
{
setup_gate(X86_EXC_XM, &entry_XM, 0);
setup_gate(X86_EXC_VE, &entry_VE, 0);
+ setup_gate(0x20, &entry_ret_to_kernel, 3);
+
asm volatile ("lidt idt_ptr");
gdt[GDTE_TSS] = (typeof(*gdt))INIT_GDTE_RAW((unsigned long)&tss, 0x67, 0x89);
void entry_MC(void);
void entry_XM(void);
void entry_VE(void);
+void entry_ret_to_kernel(void);
struct xen_trap_info pv_default_trap_info[] =
{
{ X86_EXC_MC, 0|4, __KERN_CS, (unsigned long)&entry_MC },
{ X86_EXC_XM, 0|4, __KERN_CS, (unsigned long)&entry_XM },
{ X86_EXC_VE, 0|4, __KERN_CS, (unsigned long)&entry_VE },
+
+ { 0x20, 3|4, __KERN_CS, (unsigned long)&entry_ret_to_kernel },
+
{ 0 }, /* Sentinel. */
};