LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
From: Andy Lutomirski <luto@amacapital.net>
To: Michael Kerrisk <mtk.manpages@gmail.com>, linux-kernel@vger.kernel.org
Cc: Andy Lutomirski <luto@amacapital.net>
Subject: [PATCH manpages 1/2] modify_ldt.2: Overhaul the documentation
Date: Thu, 29 Jan 2015 13:47:54 -0800	[thread overview]
Message-ID: <a470192313e89c5eeb08a2d3c8d9a180a963c2ba.1422568013.git.luto@amacapital.net> (raw)
In-Reply-To: <cover.1422568013.git.luto@amacapital.net>
In-Reply-To: <cover.1422568013.git.luto@amacapital.net>

This clarifies the behavior and documents all four functions.

Signed-off-by: Andy Lutomirski <luto@amacapital.net>
---
 man2/modify_ldt.2 | 101 +++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 78 insertions(+), 23 deletions(-)

diff --git a/man2/modify_ldt.2 b/man2/modify_ldt.2
index d128664716c6..f3cc94d397b3 100644
--- a/man2/modify_ldt.2
+++ b/man2/modify_ldt.2
@@ -1,4 +1,5 @@
 .\" Copyright (c) 1995 Michael Chastain (mec@duracef.shout.net), 22 July 1995.
+.\" Copyright (c) 2015 Andrew Lutomirski
 .\"
 .\" %%%LICENSE_START(GPLv2+_DOC_FULL)
 .\" This is free documentation; you can redistribute it and/or
@@ -23,37 +24,43 @@
 .\"
 .TH MODIFY_LDT 2 2012-07-13 "Linux" "Linux Programmer's Manual"
 .SH NAME
-modify_ldt \- get or set ldt
+modify_ldt \- get or set a per-process LDT entry
 .SH SYNOPSIS
 .nf
 .B #include <sys/types.h>
 .sp
 .BI "int modify_ldt(int " "func" ", void *" "ptr" ", unsigned long " "bytecount" );
 .fi
-
+.PP
 .IR Note :
 There is no glibc wrapper for this system call; see NOTES.
 .SH DESCRIPTION
 .BR modify_ldt ()
-reads or writes the local descriptor table (ldt) for a process.
-The ldt is a per-process memory management table used by the i386 processor.
-For more information on this table, see an Intel 386 processor handbook.
+reads or writes the local descriptor table (LDT) for a process.  The LDT
+is an array of segment descriptors that can be referenced by user code.
+Linux allows processes to configure a per-process (actually per-mm) LDT.
+For more information about the LDT, see the Intel Software Developer's
+Manual or the AMD Architecture Programming Manual.
 .PP
 When
 .I func
 is 0,
 .BR modify_ldt ()
-reads the ldt into the memory pointed to by
+reads the LDT into the memory pointed to by
 .IR ptr .
 The number of bytes read is the smaller of
 .I bytecount
-and the actual size of the ldt.
+and the actual size of the LDT, although the kernel may act as though
+the LDT is padded with additional trailing zero bytes.  On success,
+.BR modify_ldt ()
+will return the number of bytes read.
 .PP
 When
 .I func
-is 1,
+is 1 or 0x11,
 .BR modify_ldt ()
-modifies one ldt entry.
+modifies the LDT entry indicated by
+.I ptr\->entry_number.
 .I ptr
 points to a
 .I user_desc
@@ -61,11 +68,6 @@ structure
 and
 .I bytecount
 must equal the size of this structure.
-.\"
-.\" FIXME Should this page say something about func == 2 and func == 0x11?
-.\" In Linux 2.4, func == 2 returned "the default ldt"
-.\" In Linux 2.6, func == 2 is a nop, returning a zeroed out structure.
-.\" Linux 2.4 and 2.6 implement an operation for func == 0x11
 
 The
 .I user_desc
@@ -89,12 +91,44 @@ struct user_desc {
 .PP
 In Linux 2.4 and earlier, this structure was named
 .IR modify_ldt_ldt_s .
-.\" .PP
-.\" The ldt is specific for the calling process. Any attempts to change
-.\" the ldt to include the address space of another process or the kernel
-.\" will result in a segmentation violation when trying to access the memory
-.\" outside of the process address space. The memory protection is enforced
-.\" at the paging layer.
+.PP
+The
+.I contents
+field is the segment type (data, expand-down data, non-conforming code, or
+conforming code).  The other fields match their descriptions in the
+CPU manual, although
+.BR modify_ldt ()
+cannot set the accessed bit.
+.PP
+A
+.I user_desc
+is considered "empty" if
+.I read_exec_only
+and
+.I seg_not_present
+are set to 1 and all of the other fields are 0.
+An LDT entry can be cleared by setting it to an "empty"
+.I user_desc
+or, if
+.I func
+is 1, by setting both
+.I base
+and
+.I limit
+to 0.
+.PP
+A conforming code segment will be rejected if
+.I
+func
+is 1 or if
+.I seg_not_present
+is 0.
+.PP
+When
+.I func
+is 2,
+.BR modify_ldt ()
+will read zeros.  This appears to be a leftover from Linux 2.4.
 .SH RETURN VALUE
 On success,
 .BR modify_ldt ()
@@ -119,19 +153,40 @@ or
 is 1 and
 .I bytecount
 is not equal to the size of the structure
-.IR modify_ldt_ldt_s ,
+.IR user_desc ,
 or
 .I func
-is 1 and the new ldt entry has invalid values.
+is 1 or 0x11 and the new ldt entry has invalid values.
 .TP
 .B ENOSYS
 .I func
-is neither 0 nor 1.
+is neither 0, 1, 2, nor 0x11.
 .SH CONFORMING TO
 This call is Linux-specific and should not be used in programs intended
 to be portable.
+.SH BUGS
+On 64-bit kernels before Linux 3.19, one of the padding bits in
+.I user_desc,
+if set, would prevent the descriptor from being considered empty.
 .SH NOTES
 Glibc does not provide a wrapper for this system call; call it using
 .BR syscall (2).
+.PP
+.BR modify_ldt ()
+should not be used for thread-local storage, as it slows down context
+switches and only supports a limited number of threads.  Threading libraries
+should use
+.BR set_thread_area (2)
+or
+.BR arch_prctl (2)
+instead, except on extremely old kernels that do not support those system
+calls.
+.PP
+The normal use for
+.BR modify_ldt (2)
+is to run legacy 16-bit or segmented 32-bit code.  Not all kernels allow
+16-bit segments to be installed, however.
 .SH SEE ALSO
+.BR set_thread_area (2),
+.BR arch_prctl (2),
 .BR vm86 (2)
-- 
2.1.0


  reply	other threads:[~2015-01-29 21:48 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-01-29 21:47 [PATCH manpages 0/2] Improve modify_ldt, [gs]et_thread_area docs Andy Lutomirski
2015-01-29 21:47 ` Andy Lutomirski [this message]
2015-01-30 12:18   ` [PATCH manpages 1/2] modify_ldt.2: Overhaul the documentation Michael Kerrisk (man-pages)
2015-01-30 14:42     ` Andy Lutomirski
2015-01-30 15:21       ` Michael Kerrisk (man-pages)
2015-01-29 21:47 ` [PATCH manpages 2/2] arch_prctl.2, set_thread_area.2, get_thread_area.2: Improve TLS documentation Andy Lutomirski
2015-01-30 12:59   ` Michael Kerrisk (man-pages)
2015-01-30 14:45     ` Andy Lutomirski
2015-01-30 15:18       ` Michael Kerrisk (man-pages)
2015-01-30 12:18 ` [PATCH manpages 0/2] Improve modify_ldt, [gs]et_thread_area docs Michael Kerrisk (man-pages)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=a470192313e89c5eeb08a2d3c8d9a180a963c2ba.1422568013.git.luto@amacapital.net \
    --to=luto@amacapital.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mtk.manpages@gmail.com \
    --subject='Re: [PATCH manpages 1/2] modify_ldt.2: Overhaul the documentation' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).