Bug 224264 - emulators/i386-wine: demands kernel option USER_LDT which is not available
Summary: emulators/i386-wine: demands kernel option USER_LDT which is not available
Status: Open
Alias: None
Product: Ports & Packages
Classification: Unclassified
Component: Individual Port(s) (show other bugs)
Version: Latest
Hardware: amd64 Any
: --- Affects Some People
Assignee: Konstantin Belousov
Depends on:
Reported: 2017-12-12 08:20 UTC by Friedrich Volkmann
Modified: 2018-09-23 16:11 UTC (History)
6 users (show)

See Also:
bugzilla: maintainer-feedback? (dbn)

kernel config file on desktop (15.88 KB, text/plain)
2018-01-07 08:52 UTC, Friedrich Volkmann
no flags Details
kernel config file on laptop (7.11 KB, text/plain)
2018-01-07 08:54 UTC, Friedrich Volkmann
no flags Details
/etc/make.conf on desktop (1.48 KB, text/plain)
2018-01-07 08:54 UTC, Friedrich Volkmann
no flags Details
/etc/make.conf on laptop (183 bytes, text/plain)
2018-01-07 08:55 UTC, Friedrich Volkmann
no flags Details
/etc/sysctl.conf on desktop (1.45 KB, text/plain)
2018-01-07 08:57 UTC, Friedrich Volkmann
no flags Details
post install message update (2.71 KB, patch)
2018-05-12 15:48 UTC, rozhuk.im
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Friedrich Volkmann 2017-12-12 08:20:19 UTC
$ wine cb70i.exe
i386_set_ldt: Invalid argument
Did you reconfigure your kernel with "options USER_LDT"?

This error message is not helpful, as that kernel option is no more available since FreeBSD 5.

Strangely enough, the error only occurs on my laptop (FreeBSD 11.1-STABLE #1 r32t738 with i386-wine-2.0.3,1 or i386-wine-devel-2.21,1), but not on my desktop PC (FreeBSD 10.3-STABLE #1 r314643 with i386-wine-1.8.5,1).
Comment 1 David Naylor freebsd_committer 2017-12-16 18:33:54 UTC
Is this issue specific to cb70i.exe (what is that program?), more generally an issue (i.e. running winecfg)?

I can confirm i386-wine runs on 11.1-p1 without issue.
Comment 2 Friedrich Volkmann 2017-12-18 01:19:12 UTC
I get this error with all DOS programs and some Windows programs. winecfg runs without errors. cb70i.exe is the executable of the ChessBase 7.0i application (18 or so years old). I have uploaded a partial installation (sufficient to check if the error occurs) to http://steige.info/austausch/cb.zip (6 MB). If you don't get the error, it will ask you for the original CD. (That's the copy protection.)
Comment 3 David Naylor freebsd_committer 2017-12-18 06:17:27 UTC
On FreeBSD 11.1-p4 I get to the CD prompt screen, no error as described below.  Would you be able to test with a FreeBSD 11.1 kernel?
Comment 4 Friedrich Volkmann 2017-12-18 10:07:02 UTC
I did test it with 11.1, as that's the OS version currently installed on my laptop where the error happens (see first message). I guess that some old files may be left somewhere in the file system, particularly wine configuration files and directories, that might influence the outcome of wine running.

I can try to update my desktop OS (and wine version) too and see if I run into the same error there (with similar old config files left). Currently, all Windows programs seem to work on the desktop (10.3 kernel), while DOS programs don't ("Data segment size exceeds process limit") - but that would be another issue.
Comment 5 David Naylor freebsd_committer 2017-12-18 13:41:36 UTC
I just tried with 11-STABLE (FreeBSD 11.1-STABLE #0 r326821) and I was unable to reproduce the error.  

Yes, the data segment size issue in unrelated - I believe Gerald has fixed this a few releases back.  

Please update you kernel and packages, maybe that fixes it?  Also, are you using binary base/packages or compiling things yourself?
Comment 6 Friedrich Volkmann 2017-12-22 01:42:49 UTC
Meanwhile I upgraded my desktop OS from FBSD 10.3-STABLE to 11.1-STABLE and the i386-wine port too, with the result that I get the same error on the desktop too.

I use to compile everything from source. The i386-wine port, however, just installs a binary package. Maybe that's the problem. I could not find the error message anywhere within /usr/src, but it is contained in the libwine.so binary. This error message should not be there. It should not be compiled in, at least not with that text.
Comment 7 Gerald Pfeifer freebsd_committer 2017-12-22 03:40:47 UTC
The code in question (responsible for this message) is 

#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
 || defined(__OpenBSD__) || defined(__DragonFly__)
        LDT_ENTRY entry_copy = *entry;
        /* The kernel will only let us set LDTs with user priority level */
        if (entry_copy.HighWord.Bits.Pres
            && entry_copy.HighWord.Bits.Dpl != 3)
                entry_copy.HighWord.Bits.Dpl = 3;
        ret = i386_set_ldt(index, (union descriptor *)&entry_copy, 1);
        if (ret < 0)
            fprintf( stderr, "Did you reconfigure the kernel with \"options USER
_LDT\"?\n" );

in libs/wine/ldt.c in Wine sources.

The last changes relevant to BSDs have made in 2012. Of the three changes
since then, two were Linux-specific and one add GNU/Hurd support.

So I'd guess something is special about your system, Friedrich?  Any
non-standard kernel options?  Security settings?
Comment 8 Friedrich Volkmann 2017-12-25 01:02:14 UTC
I am not aware of anything special. Now I played around on my laptop:
11.1-STABLE GENERIC kernel => error
11.1-STABLE GENERIC kernel and running wine as root => same error
10.x-STABLE GENERIC kernel => works

As the first error line says "invalid argument", I assume that the i386_set_ldt() function throws an EINVAL error. This should be easy to debug, but I guess that a 32-bit wine within FreeBSD/amd64 needs a cross-compiler to compile?

The i386_set_ldt() function seems to be defined in /usr/include/x86/sysarch.h and implemented in /usr/src/lib/libc/i386/sys/i386_get_ldt.c, which calls sysarch() which in turn is implemented in /usr/src/sys/i386/i386/sys_machdep.c. I set DEBUG to 1 in that file, inserted additional printf's and reinstalled world and kernel, but all of that did not make the debug output appear.
Comment 9 David Naylor freebsd_committer 2018-01-06 08:02:45 UTC
Hi Friedrich, would you please attach your /etc/make.conf, /etc/sys.conf and kernel configuration (if you are not using GENERIC).  Given that is works on our systems the issue is likely a local change on your side.  Lets try isolate it.
Comment 10 Friedrich Volkmann 2018-01-07 08:52:46 UTC
Created attachment 189483 [details]
kernel config file on desktop
Comment 11 Friedrich Volkmann 2018-01-07 08:54:08 UTC
Created attachment 189484 [details]
kernel config file on laptop
Comment 12 Friedrich Volkmann 2018-01-07 08:54:54 UTC
Created attachment 189485 [details]
/etc/make.conf on desktop
Comment 13 Friedrich Volkmann 2018-01-07 08:55:38 UTC
Created attachment 189486 [details]
/etc/make.conf on laptop
Comment 14 Friedrich Volkmann 2018-01-07 08:57:06 UTC
Created attachment 189487 [details]
/etc/sysctl.conf on desktop
Comment 15 Friedrich Volkmann 2018-01-07 09:04:17 UTC
There is no /etc/sys.conf. I have attached /etc/sysctl.conf instead, but only for the desktop computer. The sysctl.conf on the laptop contains comments only.
Comment 16 David Naylor freebsd_committer 2018-01-07 16:43:55 UTC
Hmmm, this is an interesting nut to crack.  It would be interesting to know what errno(2) is set to.  I agree with Gerald that the message wine gives is the opposite of useful.  

Given that a GENERIC kernel does not work, I can suggest the following:
 a) try the binary kernel provided by [1] (if you didn't do this already)
 b) try the binary base (and lib32_ provided by [1]
 c) try a kernel compiled without CPUTYPE?=core2 in make.conf
 d) try a base work compiled without CPUTYPE?=core2 in make.conf

Please also try steps a, b and c, d together (i.e. both kernel and base either binary or compiled without CPUTYPE?=core2).  

My thinking is a compiler error (when CPUTYPE?=core2 enables some extract instructions and optimisations) is causing the problem.  I'm sure that wine is not the program - unless you are compiling your own version using WINE_CROSS_BUILD=yes?
Comment 17 Friedrich Volkmann 2018-01-10 10:15:26 UTC
errno(2) is EINVAL (invalid argument), see above. The question is: which parameter is invalid and why. In order to debug this, I would certainly need to cross-compile wine myself. I tried that with CFLAGS="-m32 -march=i686 -mmmx -msse -msse2 -mfancy-math-387 -DCOMPAT_32BIT -L/usr/lib32 -B/usr/lib32" ./configure --without-freetype && make, but /usr/local/bin/ld complained about incompatible libgcc and libc.

What is "[1]"? Did you intend to supply an URL?

I tried out (c) and (d), i.e. new world+kernel with the CPUTYPE line commented out in make.conf. Same error.
Comment 18 David Naylor freebsd_committer 2018-01-10 19:05:32 UTC
Sorry, [1] is https://download.freebsd.org/ftp/snapshots/amd64/11.1-STABLE/

So rebuild i386-wine you need to:
 - create an i386 chroot/jail
 - in that chroot/jail run:
   # make -C /usr/ports/emulators/i386-wine-devel -DWINE_CROSS_BUILD

The resulting package can be installed on amd64 (you will need to use the '-f' option as the architecture will be incorrect in the package).  

Would you please also post your /boot/loader.conf file.
Comment 19 Marco Perez 2018-01-15 21:26:16 UTC
I'm able to reproduce the issue on an up-to-date 11-stable GENERIC kernel.
This is on an amd64 box (Intel SandyBridge with integrated graphics card).
Booting my previous kernel (11-stable (r324724) from 2017-10-18) with new
userland and without altering any of the config files the problem's gone.

That may help narrow down the possible regression window. The port I'm
using is emulators/i386-wine-devel and this happens with several games.

My config is fairly conservative, with the possible exception of make.conf:
  CFLAGS+=-O2 -pipe
I also happen to have the latest version of sysutils/devcpu-data installed.
Comment 20 Friedrich Volkmann 2018-01-15 23:15:18 UTC
/boot/loader.conf on desktop:

/boot/loader.conf on the laptop contains comments only.

concerning (a) in comment #16: same error with binary kernel. I have not tried (b) as I am afraid it might overwrite some of my config.

Preparing the jail and the required ports within it took some time, but I finally succeeded. First results: In the line
  ret = i386_set_ldt(index, (union descriptor *)&entry_copy, 1)
index is 512, and ret is set to -1.
Comment 21 Marco Perez 2018-01-18 20:40:44 UTC
According to my regression tests the breakage was introduced on 2017-10-22 with revision 324855:
Comment 22 David Naylor freebsd_committer 2018-01-19 19:37:25 UTC
Assign to kib, as the committer of the commit.  kib, in summary:
 - wine started failing on FreeBSD 11-Stable with a failed call to i386_set_ldt
 - in this case 'index=512' is causing the problem
 - the issue appears to have been introduced in r324855
Comment 23 Marco Perez 2018-01-19 19:54:04 UTC
The change in question is https://svnweb.freebsd.org/base?view=revision&revision=324302. Temporarily setting max_ldt_segment back to 1024 works around the problem (but I doubt that this is the solution).

I wonder if there's a sane way to ensure the index remains below 512 without introducing other nasty side-effects...
Comment 24 rozhuk.im 2018-04-20 12:47:05 UTC
max_ldt_segment=1024 fix this problem.
Comment 25 rozhuk.im 2018-05-09 21:23:33 UTC
May be solution is update post install message for wine ports with text like:

If you get message: "Did you reconfigure your kernel with "options USER_LDT"?"
then add to /boot/loader.conf
this fix problem.
Comment 26 rozhuk.im 2018-05-12 15:48:41 UTC
Created attachment 193326 [details]
post install message update
Comment 27 Gleb Popov freebsd_committer 2018-09-23 08:57:20 UTC
I met this problem too, however setting max_ldt_segment=2048 in /boot/loader.conf didn't helped me. Any ideas?
Comment 28 Gerald Pfeifer freebsd_committer 2018-09-23 09:45:20 UTC
Thanks for proposing this patch!

From a language and formatting perspective, instead of

  To fix message: "Did you reconfigure your kernel with "options USER_LDT"?"
  add to /boot/loader.conf 
  and reboot.

I suggest something a little different:

  If you receive a message of "Did you reconfigure your kernel
  with "options USER_LDT"?" add the line
  to /boot/loader.conf and reboot.

David, you're a native speaker, what do you think?  Since it seems
to help some users, I'm fine making this change if you agree, i.e.,
Approved: gerald (maintainer) - and I can also apply once we have
Comment 29 Gerald Pfeifer freebsd_committer 2018-09-23 10:22:30 UTC
That said, kib@, this being a regression caused by your commit
can you please look into this?
Comment 30 Konstantin Belousov freebsd_committer 2018-09-23 16:11:29 UTC
(In reply to Gerald Pfeifer from comment #29)
Look at what ?

The decision to provide default max LDT size 512 is backed by the fact that a segment descriptor size is 8 bytes, and LDT must be contiguous in the KVA.  The consequence is that if we allow more that 512 descriptors by default, we must allocate two or more contiguous page frames.  This can break in situation where KVA is highly fragmented due to the load.

So the default is on the upper safe limit, and if user is confident that she both needs it and that the machine load would not cause the fragmentation, there is the knob to adjust it.  That said, I do not believe that there are legitimate use cases when single process needs more that dozen or two segment descriptors, so 512 should be ample.

If the process does need so many descriptors, the limit is bumped, and you get some error, then it is almost certainly unrelated both to the limit and to the commit.  Start debugging it, perhaps look at the failing syscall arguments to see what is going on (ktrace/truss).