7bc6e7456e
of the kernel address space already. Intel recommend this anyway, because using a non-4GB limit adds an additional clock cycle to address generation. We were able to install 4GB segments into the LDT, so any limits we imposed on %cs and %ds were academic anyway. More importantly, this allows us to make a page in the kernel readable to user applications, for holding things like the signal trampoline and other fun things. Move the user %cs/%ds segments from the LDT to the GDT. There was no good reason for them to be there anyway. The old LDT entries are still there but we can now relax the restriction that prevented users from emptying the default LDT entries. Putting user and kernel %cs and %ds together allows us to access the fast sysenter/sysexit/syscall/sysret instructions. syscall/sysret in particular require that the user/kernel segments be laid out this way. Reserve a slot specifically for NDIS while here. Create two user controllable slots in the GDT that are context switched with the (kernel) thread. This allows user applications to set two user privilige selectors to arbitary values. Create i386_set_fsbase(void *base) and friends. (get/set, fs/gs). For i386, %gs is used by tls and the thread libraries and this means that user processes no longer have to have the cost of having a custom LDT, and we will no longer to do a ldt switch when activating a kthread/ithread in the usual case any more. In other words, we can now set the base address for %fs and %gs to arbitary addresses without the pain of messing with ldt segments.
110 lines
3.5 KiB
C
110 lines
3.5 KiB
C
/*-
|
|
* Copyright (c) 1993 The Regents of the University of California.
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* 4. Neither the name of the University nor the names of its contributors
|
|
* may be used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*
|
|
* $FreeBSD$
|
|
*/
|
|
|
|
/*
|
|
* Architecture specific syscalls (i386)
|
|
*/
|
|
#ifndef _MACHINE_SYSARCH_H_
|
|
#define _MACHINE_SYSARCH_H_
|
|
|
|
#define I386_GET_LDT 0
|
|
#define I386_SET_LDT 1
|
|
#define LDT_AUTO_ALLOC 0xffffffff
|
|
/* I386_IOPL */
|
|
#define I386_GET_IOPERM 3
|
|
#define I386_SET_IOPERM 4
|
|
/* xxxxx */
|
|
#define I386_VM86 6
|
|
#define I386_GET_FSBASE 7
|
|
#define I386_SET_FSBASE 8
|
|
#define I386_GET_GSBASE 9
|
|
#define I386_SET_GSBASE 10
|
|
|
|
/* These four only exist when running an i386 binary on amd64 */
|
|
#define _AMD64_GET_FSBASE 128
|
|
#define _AMD64_SET_FSBASE 129
|
|
#define _AMD64_GET_GSBASE 130
|
|
#define _AMD64_SET_GSBASE 131
|
|
|
|
struct i386_ldt_args {
|
|
unsigned int start;
|
|
union descriptor *descs;
|
|
unsigned int num;
|
|
};
|
|
|
|
struct i386_ioperm_args {
|
|
unsigned int start;
|
|
unsigned int length;
|
|
int enable;
|
|
};
|
|
|
|
struct i386_vm86_args {
|
|
int sub_op; /* sub-operation to perform */
|
|
char *sub_args; /* args */
|
|
};
|
|
|
|
#ifndef _KERNEL
|
|
#include <sys/cdefs.h>
|
|
|
|
union descriptor;
|
|
struct dbreg;
|
|
|
|
__BEGIN_DECLS
|
|
/* These four only exist when running an i386 binary on amd64 */
|
|
int _amd64_get_fsbase(void **);
|
|
int _amd64_get_gsbase(void **);
|
|
int _amd64_set_fsbase(void *);
|
|
int _amd64_set_gsbase(void *);
|
|
int i386_get_ldt(int, union descriptor *, int);
|
|
int i386_set_ldt(int, union descriptor *, int);
|
|
int i386_get_ioperm(unsigned int, unsigned int *, int *);
|
|
int i386_set_ioperm(unsigned int, unsigned int, int);
|
|
int i386_vm86(int, void *);
|
|
int i386_get_fsbase(void **);
|
|
int i386_get_gsbase(void **);
|
|
int i386_set_fsbase(void *);
|
|
int i386_set_gsbase(void *);
|
|
int i386_set_watch(int, unsigned int, int, int, struct dbreg *);
|
|
int i386_clr_watch(int, struct dbreg *);
|
|
int sysarch(int, void *);
|
|
__END_DECLS
|
|
#else
|
|
struct thread;
|
|
union descriptor;
|
|
|
|
int i386_get_ldt(struct thread *, struct i386_ldt_args *);
|
|
int i386_set_ldt(struct thread *, struct i386_ldt_args *, union descriptor *);
|
|
int i386_get_ioperm(struct thread *, struct i386_ioperm_args *);
|
|
int i386_set_ioperm(struct thread *, struct i386_ioperm_args *);
|
|
#endif
|
|
|
|
#endif /* !_MACHINE_SYSARCH_H_ */
|