Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 03 Sep 2015 22:59:18 +0000
From:      bugzilla-noreply@freebsd.org
To:        freebsd-x11@FreeBSD.org
Subject:   [Bug 202643] x11/xorg: illegal instruction starting xorg in FreeBSD 10.2 in kvm/qemu virtulization
Message-ID:  <bug-202643-8047-Bomjvq3PWM@https.bugs.freebsd.org/bugzilla/>
In-Reply-To: <bug-202643-8047@https.bugs.freebsd.org/bugzilla/>
References:  <bug-202643-8047@https.bugs.freebsd.org/bugzilla/>

next in thread | previous in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=202643

--- Comment #19 from Dimitry Andric <dim@FreeBSD.org> ---
Created attachment 160694
  --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=160694&action=edit
Disable SSE for hw/xfree86/os-support/misc/SlowBcopy.c

This patch works for me, can the original submitters please try dropping it in
/usr/ports/x11-servers/xorg-server/files, and then rebuilding and reinstalling
/usr/ports/x11-servers/xorg-server?

I think what is happening is the following:
- Xorg calls the VESA driver's VESAScreenInit() function
- VESAScreenInit() calls VESAMapVidMem(), which uses pci_device_map_legacy() to
map PCI memory into pVesa->VGAbase
- VESAScreenInit() later calls VESASaveRestore(), which in turn calls
SaveFonts()
- SaveFonts() (and its inverse RestoreFonts()) calls xf86SlowBcopy(), with
pVesa->VGAbase as source address
- For some reason, QEmu does not like copying from the just-mapped PCI memory
using SSE instructions (e.g. movups)
- QEmu throws either an illegal instruction exception, or some other exception
(which causes either SIGILL or SIGBUS)

I'm guessing that this is the whole reason for the existence of a "slow bcopy"
function in X.org: the function attempts to "slowly" copy byte by byte, even
inserting outb(0x80, 0x00) instructions in between, if the really_slow_bcopy
flag is set.

However, clang recognizes the "while (len--) *dst++ = *src++;" idiom, and
replaces this with SSE, which leads to QEmu throwing a fit, as described above.
 Note that this may very well also occur with newer gcc versions, since those
will probably also transform copying loops into SSE.

In any case, to make the "slow bcopy" really slow again, and avoid QEmu blowing
up, I've added -mno-sse to the CFLAGS for the SlowBcopy.c file.  (This flag is
only needed on x86, btw.)

The resulting assembly does not use SSE anymore, but just old-fashioned byte by
byte copying:

0000000000000010 <xf86SlowBcopy>:
[...]
  47:   85 c9                   test   %ecx,%ecx
  49:   74 15                   je     60 <xf86SlowBcopy+0x50>
  4b:   0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)
  50:   ff c9                   dec    %ecx
  52:   8a 07                   mov    (%rdi),%al
  54:   48 8d 7f 01             lea    0x1(%rdi),%rdi
  58:   88 06                   mov    %al,(%rsi)
  5a:   48 8d 76 01             lea    0x1(%rsi),%rsi
  5e:   75 f0                   jne    50 <xf86SlowBcopy+0x40>
  60:   5d                      pop    %rbp
  61:   c3                      retq

-- 
You are receiving this mail because:
You are the assignee for the bug.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-202643-8047-Bomjvq3PWM>