4
votes

All the textbooks and Internet resources tell me int 80h is a stale style for invoking system calls, and has been replaced by SYSENTER on x86 platforms.

But I just found my system still uses int 80h. I know the textbook stuff like VDSO, libc wrapper that implements the system call service, but don't understand why int 80h is still used by default.

  1. Can anybody tell me the reason? The glibc or the kernel is too old?

  2. Nowadays under what conditions is "int 80h" still used by default?

  3. How can I enforce sysenter without installing a new glibc?


Below is my environment:

I installed a virtual machine using VMWare on my macbook air 2011 (Core Duo CPU). 32-bit Ubuntu 8.04/kernel 2.6.24 (compiled using the original .config) /libc 2.7 in the VM.

2
Here is a good link about how to determine which mechanism of int 80h and sysenter is used in a system. But it doesn't resolve my surprise that my system still uses int 80h. I just gdb-ed an executable, and found "int 80h"is actually encoded in glibc. That is, in my case, the VDSO provided by the kernel is not used.Infinite
After some investigation, I am sure that the kernel does provide the vsyscall page. Just the glibc is configured to use int 80h directly. I guess this was the choice of Ubuntu people who configured this kind of libc for 8.04 release.Infinite

2 Answers

2
votes

Most likely for compatibility reasons - 32-bits Ubuntu is compiled to be compatible up to the i386 processor (well, maybe not that old nowadays), which did not support sysenter (it only appeared on Pentium 2 AFAIK). Apparently using sysenter against int 80h is really benefical only on some kinds of processors:

http://articles.manugarg.com/systemcallinlinux2_6.html

Therefore, if there is no significant speed gain in the general case and broader compatibility, using int 80h over sysenter still makes sense, even today. If you use the 64-bit version of Ubuntu then sysenter/sysexit are used all over the place.

Edit: actually the system call mechanism to use is decided by the kernel at boot time, not by glibc. This page (section 4.6) explains how this works very well. In your case, it just happens that the hardware emulated by VMware is considered by the kernel to be more efficient using int 80h rather than sysenter. You would have to debug the kernel in order to figure out how it makes that decision.

2
votes

What instructions (int80 or sysenter) is always decided by the guest OS itself, as you can see from linux kernel source code - it all depends what hardware VMware has presented to it.

Look at the file arch/x86/vdso/vdso32-setup.c (linux kernel source code):

   if (vdso32_syscall()) {
            vsyscall = &vdso32_syscall_start;
            vsyscall_len = &vdso32_syscall_end - &vdso32_syscall_start;
    } else if (vdso32_sysenter()){
            vsyscall = &vdso32_sysenter_start;
            vsyscall_len = &vdso32_sysenter_end - &vdso32_sysenter_start;
    } else {
            vsyscall = &vdso32_int80_start;
            vsyscall_len = &vdso32_int80_end - &vdso32_int80_start;
    }

From above u can see that the decision to use int80 is only when sysenter feature detection failed. And this feature is in turned presented to the guest via VMWare's emulation engine. Perhaps if u had use the most recent version of VMware, together with some modern hardware, VMware should present a more modern OS to the guest.