From mboxrd@z Thu Jan 1 00:00:00 1970 From: David Vrabel Subject: Re: [PATCH] x86/PV: properly populate descriptor tables Date: Mon, 26 Oct 2015 14:43:23 +0000 Message-ID: <562E3C0B.5040908@citrix.com> References: <5602E29802000078000A4EAF@prv-mh.provo.novell.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: Received: from mail6.bemta14.messagelabs.com ([193.109.254.103]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1Zqj06-0001AI-Eq for xen-devel@lists.xenproject.org; Mon, 26 Oct 2015 14:43:54 +0000 In-Reply-To: <5602E29802000078000A4EAF@prv-mh.provo.novell.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: Jan Beulich , xen-devel Cc: Andrew Cooper , Keir Fraser , Wei Liu List-Id: xen-devel@lists.xenproject.org On 23/09/15 16:34, Jan Beulich wrote: > Us extending the GDT limit past the Xen descriptors so far meant that > guests (including user mode programs) accessing any descriptor table > slot above the original OS'es limit but below the first Xen descriptor > caused a #PF, converted to a #GP in our #PF handler. Which is quite > different from the native behavior, where some of such accesses (LAR > and LSL) don't fault. Mimic that behavior by mapping a blank page into > unused slots. > > While not strictly required, treat the LDT the same for consistency. This change causes a 32-bit userspace process running in a 32-bit PV guest to segfault. The process is a Go program and it is using the modify_ldt() system call (which is successful) but loading %gs with the new descriptor causes a fault. Even a minimal (empty main()) go program faults. # strace ./go-crash execve("./go-crash", ["./go-crash"], [/* 21 vars */]) = 0 modify_ldt(1, {entry_number:7, base_addr:0x80a0b28, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}, 16) = 0 --- SIGSEGV (Segmentation fault) @ 0 (0) --- # gdb ./go-crash ... (gdb) run Starting program: /root/go-crash Program received signal SIGSEGV, Segmentation fault. runtime.setldt () at /usr/local/go/src/runtime/sys_linux_386.s:426 426 /usr/local/go/src/runtime/sys_linux_386.s: No such file or directory. in /usr/local/go/src/runtime/sys_linux_386.s (gdb) info registers eax 0x3f 63 ecx 0xbfffe4f8 -1073748744 edx 0x10 16 ebx 0x1 1 esp 0xbfffe4e8 0xbfffe4e8 ebp 0x809b180 0x809b180 esi 0x0 0 edi 0x0 0 eip 0x80700a1 0x80700a1 eflags 0x10206 [ PF IF RF ] cs 0x73 115 ss 0x7b 123 ds 0x7b 123 es 0x7b 123 fs 0x0 0 gs 0x0 0 (gdb) disassem Dump of assembler code for function runtime.setldt: ... 0x08070060 : lea 0x10(%esp),%eax 0x08070064 : mov %ebx,(%eax) 0x08070066 : mov %ecx,0x4(%eax) 0x08070069 : movl $0xfffff,0x8(%eax) 0x08070070 : movl $0x51,0xc(%eax) 0x08070077 : mov $0x1,%ebx 0x0807007c : mov %eax,%ecx 0x0807007e : mov $0x10,%edx 0x08070083 : mov $0x7b,%eax 0x08070088 : call *0x809800c 0x0807008e : cmp $0xfffff001,%eax 0x08070093 : jbe 0x8070097 0x08070095 : int $0x3 0x08070097 : mov 0x24(%esp),%eax 0x0807009b : shl $0x3,%eax 0x0807009e : add $0x7,%eax 0x080700a1 : mov %eax,%gs <-- FAULT 0x080700a3 : add $0x20,%esp 0x080700a6 : ret David