Syscall/Sysret works the first time, causes #IO next.

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
zhiayang
Member
Member
Posts: 368
Joined: Tue Dec 27, 2011 7:57 am
Libera.chat IRC: zhiayang

Syscall/Sysret works the first time, causes #IO next.

Post by zhiayang »

Hello.

I've recently got Ring3 threads working in my scheduler, but right now I'm using iret and there is a noticeable lag/stutter/what have you.

So I'm looking into replacing that with Syscall/Sysret... and I believe i've gotten most of the thing figured out... except this.

As you can tell from the title, I can successfully perform a syscall and sysret... however, it fails with an Invalid Opcode exception subsequent times.

Here is the code:

Ring3 program:

Code: Select all

while(true)
{
	asm volatile("syscall");
}
quite simple. Here is the MSR setup:

Code: Select all

        // setup MSRs for syscall/sysret

	// modify STAR
	mov $0xC0000081, %ecx
	rdmsr
	// msr is edx:eax

	// simultaneously setup sysret CS and syscall CS
	mov $0x001B0008, %edx
	xor %eax, %eax
	wrmsr


	// now we modify LSTAR to hold the address of HandleSyscall
	xor %edx, %edx

	// TODO: Write handler for SYSCALL instruction instead of interrupt
	// keep both options available.
	// fill in address when ready/
	mov $HandleSyscallInstruction, %eax
	mov $0xC0000082, %ecx
	wrmsr


	// set SFMASK to 0.
	mov $0xC0000084, %ecx
	xor %eax, %eax
	wrmsr








	// Call our kernel.
	call kmain

And here is the actual code that gets called:

Code: Select all

xchg %bx, %bx
push %rcx

pop %rcx
sysret


Anyone got any clues? All the register values look normal at the time -- the exception occurs on the 'syscall' instruction, the second time. Works 100% as far as i can tell for the first time.

Thanks!
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: Syscall/Sysret works the first time, causes #IO next.

Post by bluemoon »

requimrar wrote: // TODO: Write handler for SYSCALL instruction instead of interrupt
// keep both options available.
// fill in address when ready/
xor %edx, %edx
mov $HandleSyscallInstruction, %eax
mov $0xC0000082, %ecx
wrmsr
EDX:EAX should point to the handler, you probably should do this instead:

Code: Select all

    mov     ecx, 0xC0000082     ; IA32_LSTAR
    mov     rax, qword _syscall_stub
    mov     rdx, rax
    shr     rdx, 32
requimrar wrote: // set SFMASK to 0.
mov $0xC0000084, %ecx
xor %eax, %eax
wrmsr
I suggest to set FMASK to IF, so you could safely setup things like valid stack after the CPU gets into ring0.

By the way, I assume you have set IA32_EFER.SCE.
User avatar
zhiayang
Member
Member
Posts: 368
Joined: Tue Dec 27, 2011 7:57 am
Libera.chat IRC: zhiayang

Re: Syscall/Sysret works the first time, causes #IO next.

Post by zhiayang »

bluemoon wrote:
requimrar wrote: // TODO: Write handler for SYSCALL instruction instead of interrupt
// keep both options available.
// fill in address when ready/
xor %edx, %edx
mov $HandleSyscallInstruction, %eax
mov $0xC0000082, %ecx
wrmsr
EDX:EAX should point to the handler, you probably should do this instead:

Code: Select all

    mov     ecx, 0xC0000082     ; IA32_LSTAR
    mov     rax, qword _syscall_stub
    mov     rdx, rax
    shr     rdx, 32
requimrar wrote: // set SFMASK to 0.
mov $0xC0000084, %ecx
xor %eax, %eax
wrmsr
I suggest to set FMASK to IF, so you could safely setup things like valid stack after the CPU gets into ring0.

By the way, I assume you have set IA32_EFER.SCE.

I know for a fact that the sys call handler is below 4GB so I can omit the %edx part of the MSR. (notice i xor it).
And yes, SCE is set.
I get the feeling it's the IST messing the stack up (I encountered a similar problem this morning while working with my iret model)...
User avatar
iansjack
Member
Member
Posts: 4711
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Syscall/Sysret works the first time, causes #IO next.

Post by iansjack »

I get the feeling it's the IST messing the stack up
Easily tested with a debugger. Facts are better than feelings in OS design.
Post Reply