Merge branch 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: x86/i386: Put aligned stack-canary in percpu shared_aligned section x86/i386: Make sure stack-protector segment base is cache aligned x86: Detect stack protector for i386 builds on x86_64 x86: allow "=rm" in native_save_fl() x86: properly annotate alternatives.c x86: Introduce GDT_ENTRY_INIT(), initialize bad_bios_desc statically x86, 32-bit: Use generic sys_pipe() x86: Introduce GDT_ENTRY_INIT(), fix APM x86: Introduce GDT_ENTRY_INIT() x86: Introduce set_desc_base() and set_desc_limit() x86: Remove unused patch_espfix_desc() x86: Use get_desc_base()
This commit is contained in:
@ -2,6 +2,7 @@
|
||||
#include <linux/sched.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/stringify.h>
|
||||
#include <linux/kprobes.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/vmalloc.h>
|
||||
@ -32,7 +33,7 @@ __setup("smp-alt-boot", bootonly);
|
||||
#define smp_alt_once 1
|
||||
#endif
|
||||
|
||||
static int debug_alternative;
|
||||
static int __initdata_or_module debug_alternative;
|
||||
|
||||
static int __init debug_alt(char *str)
|
||||
{
|
||||
@ -51,7 +52,7 @@ static int __init setup_noreplace_smp(char *str)
|
||||
__setup("noreplace-smp", setup_noreplace_smp);
|
||||
|
||||
#ifdef CONFIG_PARAVIRT
|
||||
static int noreplace_paravirt = 0;
|
||||
static int __initdata_or_module noreplace_paravirt = 0;
|
||||
|
||||
static int __init setup_noreplace_paravirt(char *str)
|
||||
{
|
||||
@ -64,16 +65,17 @@ __setup("noreplace-paravirt", setup_noreplace_paravirt);
|
||||
#define DPRINTK(fmt, args...) if (debug_alternative) \
|
||||
printk(KERN_DEBUG fmt, args)
|
||||
|
||||
#ifdef GENERIC_NOP1
|
||||
#if defined(GENERIC_NOP1) && !defined(CONFIG_X86_64)
|
||||
/* Use inline assembly to define this because the nops are defined
|
||||
as inline assembly strings in the include files and we cannot
|
||||
get them easily into strings. */
|
||||
asm("\t.section .rodata, \"a\"\nintelnops: "
|
||||
asm("\t" __stringify(__INITRODATA_OR_MODULE) "\nintelnops: "
|
||||
GENERIC_NOP1 GENERIC_NOP2 GENERIC_NOP3 GENERIC_NOP4 GENERIC_NOP5 GENERIC_NOP6
|
||||
GENERIC_NOP7 GENERIC_NOP8
|
||||
"\t.previous");
|
||||
extern const unsigned char intelnops[];
|
||||
static const unsigned char *const intel_nops[ASM_NOP_MAX+1] = {
|
||||
static const unsigned char *const __initconst_or_module
|
||||
intel_nops[ASM_NOP_MAX+1] = {
|
||||
NULL,
|
||||
intelnops,
|
||||
intelnops + 1,
|
||||
@ -87,12 +89,13 @@ static const unsigned char *const intel_nops[ASM_NOP_MAX+1] = {
|
||||
#endif
|
||||
|
||||
#ifdef K8_NOP1
|
||||
asm("\t.section .rodata, \"a\"\nk8nops: "
|
||||
asm("\t" __stringify(__INITRODATA_OR_MODULE) "\nk8nops: "
|
||||
K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6
|
||||
K8_NOP7 K8_NOP8
|
||||
"\t.previous");
|
||||
extern const unsigned char k8nops[];
|
||||
static const unsigned char *const k8_nops[ASM_NOP_MAX+1] = {
|
||||
static const unsigned char *const __initconst_or_module
|
||||
k8_nops[ASM_NOP_MAX+1] = {
|
||||
NULL,
|
||||
k8nops,
|
||||
k8nops + 1,
|
||||
@ -105,13 +108,14 @@ static const unsigned char *const k8_nops[ASM_NOP_MAX+1] = {
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef K7_NOP1
|
||||
asm("\t.section .rodata, \"a\"\nk7nops: "
|
||||
#if defined(K7_NOP1) && !defined(CONFIG_X86_64)
|
||||
asm("\t" __stringify(__INITRODATA_OR_MODULE) "\nk7nops: "
|
||||
K7_NOP1 K7_NOP2 K7_NOP3 K7_NOP4 K7_NOP5 K7_NOP6
|
||||
K7_NOP7 K7_NOP8
|
||||
"\t.previous");
|
||||
extern const unsigned char k7nops[];
|
||||
static const unsigned char *const k7_nops[ASM_NOP_MAX+1] = {
|
||||
static const unsigned char *const __initconst_or_module
|
||||
k7_nops[ASM_NOP_MAX+1] = {
|
||||
NULL,
|
||||
k7nops,
|
||||
k7nops + 1,
|
||||
@ -125,12 +129,13 @@ static const unsigned char *const k7_nops[ASM_NOP_MAX+1] = {
|
||||
#endif
|
||||
|
||||
#ifdef P6_NOP1
|
||||
asm("\t.section .rodata, \"a\"\np6nops: "
|
||||
asm("\t" __stringify(__INITRODATA_OR_MODULE) "\np6nops: "
|
||||
P6_NOP1 P6_NOP2 P6_NOP3 P6_NOP4 P6_NOP5 P6_NOP6
|
||||
P6_NOP7 P6_NOP8
|
||||
"\t.previous");
|
||||
extern const unsigned char p6nops[];
|
||||
static const unsigned char *const p6_nops[ASM_NOP_MAX+1] = {
|
||||
static const unsigned char *const __initconst_or_module
|
||||
p6_nops[ASM_NOP_MAX+1] = {
|
||||
NULL,
|
||||
p6nops,
|
||||
p6nops + 1,
|
||||
@ -146,7 +151,7 @@ static const unsigned char *const p6_nops[ASM_NOP_MAX+1] = {
|
||||
#ifdef CONFIG_X86_64
|
||||
|
||||
extern char __vsyscall_0;
|
||||
const unsigned char *const *find_nop_table(void)
|
||||
static const unsigned char *const *__init_or_module find_nop_table(void)
|
||||
{
|
||||
if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
|
||||
boot_cpu_has(X86_FEATURE_NOPL))
|
||||
@ -157,7 +162,7 @@ const unsigned char *const *find_nop_table(void)
|
||||
|
||||
#else /* CONFIG_X86_64 */
|
||||
|
||||
const unsigned char *const *find_nop_table(void)
|
||||
static const unsigned char *const *__init_or_module find_nop_table(void)
|
||||
{
|
||||
if (boot_cpu_has(X86_FEATURE_K8))
|
||||
return k8_nops;
|
||||
@ -172,7 +177,7 @@ const unsigned char *const *find_nop_table(void)
|
||||
#endif /* CONFIG_X86_64 */
|
||||
|
||||
/* Use this to add nops to a buffer, then text_poke the whole buffer. */
|
||||
void add_nops(void *insns, unsigned int len)
|
||||
static void __init_or_module add_nops(void *insns, unsigned int len)
|
||||
{
|
||||
const unsigned char *const *noptable = find_nop_table();
|
||||
|
||||
@ -185,10 +190,10 @@ void add_nops(void *insns, unsigned int len)
|
||||
len -= noplen;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(add_nops);
|
||||
|
||||
extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
|
||||
extern u8 *__smp_locks[], *__smp_locks_end[];
|
||||
static void *text_poke_early(void *addr, const void *opcode, size_t len);
|
||||
|
||||
/* Replace instructions with better alternatives for this CPU type.
|
||||
This runs before SMP is initialized to avoid SMP problems with
|
||||
@ -196,7 +201,8 @@ extern u8 *__smp_locks[], *__smp_locks_end[];
|
||||
APs have less capabilities than the boot processor are not handled.
|
||||
Tough. Make sure you disable such features by hand. */
|
||||
|
||||
void apply_alternatives(struct alt_instr *start, struct alt_instr *end)
|
||||
void __init_or_module apply_alternatives(struct alt_instr *start,
|
||||
struct alt_instr *end)
|
||||
{
|
||||
struct alt_instr *a;
|
||||
char insnbuf[MAX_PATCH_LEN];
|
||||
@ -279,9 +285,10 @@ static LIST_HEAD(smp_alt_modules);
|
||||
static DEFINE_MUTEX(smp_alt);
|
||||
static int smp_mode = 1; /* protected by smp_alt */
|
||||
|
||||
void alternatives_smp_module_add(struct module *mod, char *name,
|
||||
void *locks, void *locks_end,
|
||||
void *text, void *text_end)
|
||||
void __init_or_module alternatives_smp_module_add(struct module *mod,
|
||||
char *name,
|
||||
void *locks, void *locks_end,
|
||||
void *text, void *text_end)
|
||||
{
|
||||
struct smp_alt_module *smp;
|
||||
|
||||
@ -317,7 +324,7 @@ void alternatives_smp_module_add(struct module *mod, char *name,
|
||||
mutex_unlock(&smp_alt);
|
||||
}
|
||||
|
||||
void alternatives_smp_module_del(struct module *mod)
|
||||
void __init_or_module alternatives_smp_module_del(struct module *mod)
|
||||
{
|
||||
struct smp_alt_module *item;
|
||||
|
||||
@ -386,8 +393,8 @@ void alternatives_smp_switch(int smp)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PARAVIRT
|
||||
void apply_paravirt(struct paravirt_patch_site *start,
|
||||
struct paravirt_patch_site *end)
|
||||
void __init_or_module apply_paravirt(struct paravirt_patch_site *start,
|
||||
struct paravirt_patch_site *end)
|
||||
{
|
||||
struct paravirt_patch_site *p;
|
||||
char insnbuf[MAX_PATCH_LEN];
|
||||
@ -485,7 +492,8 @@ void __init alternative_instructions(void)
|
||||
* instructions. And on the local CPU you need to be protected again NMI or MCE
|
||||
* handlers seeing an inconsistent instruction while you patch.
|
||||
*/
|
||||
void *text_poke_early(void *addr, const void *opcode, size_t len)
|
||||
static void *__init_or_module text_poke_early(void *addr, const void *opcode,
|
||||
size_t len)
|
||||
{
|
||||
unsigned long flags;
|
||||
local_irq_save(flags);
|
||||
|
@ -403,7 +403,15 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue);
|
||||
static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
|
||||
static struct apm_user *user_list;
|
||||
static DEFINE_SPINLOCK(user_list_lock);
|
||||
static const struct desc_struct bad_bios_desc = { { { 0, 0x00409200 } } };
|
||||
|
||||
/*
|
||||
* Set up a segment that references the real mode segment 0x40
|
||||
* that extends up to the end of page zero (that we have reserved).
|
||||
* This is for buggy BIOS's that refer to (real mode) segment 0x40
|
||||
* even though they are called in protected mode.
|
||||
*/
|
||||
static struct desc_struct bad_bios_desc = GDT_ENTRY_INIT(0x4092,
|
||||
(unsigned long)__va(0x400UL), PAGE_SIZE - 0x400 - 1);
|
||||
|
||||
static const char driver_version[] = "1.16ac"; /* no spaces */
|
||||
|
||||
@ -2331,15 +2339,6 @@ static int __init apm_init(void)
|
||||
}
|
||||
pm_flags |= PM_APM;
|
||||
|
||||
/*
|
||||
* Set up a segment that references the real mode segment 0x40
|
||||
* that extends up to the end of page zero (that we have reserved).
|
||||
* This is for buggy BIOS's that refer to (real mode) segment 0x40
|
||||
* even though they are called in protected mode.
|
||||
*/
|
||||
set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
|
||||
_set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
|
||||
|
||||
/*
|
||||
* Set up the long jump entry point to the APM BIOS, which is called
|
||||
* from inline assembly.
|
||||
@ -2358,12 +2357,12 @@ static int __init apm_init(void)
|
||||
* code to that CPU.
|
||||
*/
|
||||
gdt = get_cpu_gdt_table(0);
|
||||
set_base(gdt[APM_CS >> 3],
|
||||
__va((unsigned long)apm_info.bios.cseg << 4));
|
||||
set_base(gdt[APM_CS_16 >> 3],
|
||||
__va((unsigned long)apm_info.bios.cseg_16 << 4));
|
||||
set_base(gdt[APM_DS >> 3],
|
||||
__va((unsigned long)apm_info.bios.dseg << 4));
|
||||
set_desc_base(&gdt[APM_CS >> 3],
|
||||
(unsigned long)__va((unsigned long)apm_info.bios.cseg << 4));
|
||||
set_desc_base(&gdt[APM_CS_16 >> 3],
|
||||
(unsigned long)__va((unsigned long)apm_info.bios.cseg_16 << 4));
|
||||
set_desc_base(&gdt[APM_DS >> 3],
|
||||
(unsigned long)__va((unsigned long)apm_info.bios.dseg << 4));
|
||||
|
||||
proc_create("apm", 0, NULL, &apm_file_ops);
|
||||
|
||||
|
@ -94,45 +94,45 @@ DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = {
|
||||
* TLS descriptors are currently at a different place compared to i386.
|
||||
* Hopefully nobody expects them at a fixed place (Wine?)
|
||||
*/
|
||||
[GDT_ENTRY_KERNEL32_CS] = { { { 0x0000ffff, 0x00cf9b00 } } },
|
||||
[GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00af9b00 } } },
|
||||
[GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9300 } } },
|
||||
[GDT_ENTRY_DEFAULT_USER32_CS] = { { { 0x0000ffff, 0x00cffb00 } } },
|
||||
[GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff300 } } },
|
||||
[GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00affb00 } } },
|
||||
[GDT_ENTRY_KERNEL32_CS] = GDT_ENTRY_INIT(0xc09b, 0, 0xfffff),
|
||||
[GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(0xa09b, 0, 0xfffff),
|
||||
[GDT_ENTRY_KERNEL_DS] = GDT_ENTRY_INIT(0xc093, 0, 0xfffff),
|
||||
[GDT_ENTRY_DEFAULT_USER32_CS] = GDT_ENTRY_INIT(0xc0fb, 0, 0xfffff),
|
||||
[GDT_ENTRY_DEFAULT_USER_DS] = GDT_ENTRY_INIT(0xc0f3, 0, 0xfffff),
|
||||
[GDT_ENTRY_DEFAULT_USER_CS] = GDT_ENTRY_INIT(0xa0fb, 0, 0xfffff),
|
||||
#else
|
||||
[GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } },
|
||||
[GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } },
|
||||
[GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } },
|
||||
[GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff200 } } },
|
||||
[GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(0xc09a, 0, 0xfffff),
|
||||
[GDT_ENTRY_KERNEL_DS] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff),
|
||||
[GDT_ENTRY_DEFAULT_USER_CS] = GDT_ENTRY_INIT(0xc0fa, 0, 0xfffff),
|
||||
[GDT_ENTRY_DEFAULT_USER_DS] = GDT_ENTRY_INIT(0xc0f2, 0, 0xfffff),
|
||||
/*
|
||||
* Segments used for calling PnP BIOS have byte granularity.
|
||||
* They code segments and data segments have fixed 64k limits,
|
||||
* the transfer segment sizes are set at run time.
|
||||
*/
|
||||
/* 32-bit code */
|
||||
[GDT_ENTRY_PNPBIOS_CS32] = { { { 0x0000ffff, 0x00409a00 } } },
|
||||
[GDT_ENTRY_PNPBIOS_CS32] = GDT_ENTRY_INIT(0x409a, 0, 0xffff),
|
||||
/* 16-bit code */
|
||||
[GDT_ENTRY_PNPBIOS_CS16] = { { { 0x0000ffff, 0x00009a00 } } },
|
||||
[GDT_ENTRY_PNPBIOS_CS16] = GDT_ENTRY_INIT(0x009a, 0, 0xffff),
|
||||
/* 16-bit data */
|
||||
[GDT_ENTRY_PNPBIOS_DS] = { { { 0x0000ffff, 0x00009200 } } },
|
||||
[GDT_ENTRY_PNPBIOS_DS] = GDT_ENTRY_INIT(0x0092, 0, 0xffff),
|
||||
/* 16-bit data */
|
||||
[GDT_ENTRY_PNPBIOS_TS1] = { { { 0x00000000, 0x00009200 } } },
|
||||
[GDT_ENTRY_PNPBIOS_TS1] = GDT_ENTRY_INIT(0x0092, 0, 0),
|
||||
/* 16-bit data */
|
||||
[GDT_ENTRY_PNPBIOS_TS2] = { { { 0x00000000, 0x00009200 } } },
|
||||
[GDT_ENTRY_PNPBIOS_TS2] = GDT_ENTRY_INIT(0x0092, 0, 0),
|
||||
/*
|
||||
* The APM segments have byte granularity and their bases
|
||||
* are set at run time. All have 64k limits.
|
||||
*/
|
||||
/* 32-bit code */
|
||||
[GDT_ENTRY_APMBIOS_BASE] = { { { 0x0000ffff, 0x00409a00 } } },
|
||||
[GDT_ENTRY_APMBIOS_BASE] = GDT_ENTRY_INIT(0x409a, 0, 0xffff),
|
||||
/* 16-bit code */
|
||||
[GDT_ENTRY_APMBIOS_BASE+1] = { { { 0x0000ffff, 0x00009a00 } } },
|
||||
[GDT_ENTRY_APMBIOS_BASE+1] = GDT_ENTRY_INIT(0x009a, 0, 0xffff),
|
||||
/* data */
|
||||
[GDT_ENTRY_APMBIOS_BASE+2] = { { { 0x0000ffff, 0x00409200 } } },
|
||||
[GDT_ENTRY_APMBIOS_BASE+2] = GDT_ENTRY_INIT(0x4092, 0, 0xffff),
|
||||
|
||||
[GDT_ENTRY_ESPFIX_SS] = { { { 0x0000ffff, 0x00cf9200 } } },
|
||||
[GDT_ENTRY_PERCPU] = { { { 0x0000ffff, 0x00cf9200 } } },
|
||||
[GDT_ENTRY_ESPFIX_SS] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff),
|
||||
[GDT_ENTRY_PERCPU] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff),
|
||||
GDT_STACK_CANARY_INIT
|
||||
#endif
|
||||
} };
|
||||
@ -1043,7 +1043,7 @@ DEFINE_PER_CPU(struct orig_ist, orig_ist);
|
||||
#else /* CONFIG_X86_64 */
|
||||
|
||||
#ifdef CONFIG_CC_STACKPROTECTOR
|
||||
DEFINE_PER_CPU(unsigned long, stack_canary);
|
||||
DEFINE_PER_CPU_ALIGNED(struct stack_canary, stack_canary);
|
||||
#endif
|
||||
|
||||
/* Make sure %fs and %gs are initialized properly in idle threads */
|
||||
|
@ -27,9 +27,7 @@ static void doublefault_fn(void)
|
||||
|
||||
if (ptr_ok(gdt)) {
|
||||
gdt += GDT_ENTRY_TSS << 3;
|
||||
tss = *(u16 *)(gdt+2);
|
||||
tss += *(u8 *)(gdt+4) << 16;
|
||||
tss += *(u8 *)(gdt+7) << 24;
|
||||
tss = get_desc_base((struct desc_struct *)gdt);
|
||||
printk(KERN_EMERG "double fault, tss at %08lx\n", tss);
|
||||
|
||||
if (ptr_ok(tss)) {
|
||||
|
@ -439,7 +439,6 @@ is386: movl $2,%ecx # set MP
|
||||
jne 1f
|
||||
movl $per_cpu__gdt_page,%eax
|
||||
movl $per_cpu__stack_canary,%ecx
|
||||
subl $20, %ecx
|
||||
movw %cx, 8 * GDT_ENTRY_STACK_CANARY + 2(%eax)
|
||||
shrl $16, %ecx
|
||||
movb %cl, 8 * GDT_ENTRY_STACK_CANARY + 4(%eax)
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <linux/sched.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <asm/desc.h>
|
||||
|
||||
unsigned long convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs)
|
||||
{
|
||||
@ -23,7 +24,7 @@ unsigned long convert_ip_to_linear(struct task_struct *child, struct pt_regs *re
|
||||
* and APM bios ones we just ignore here.
|
||||
*/
|
||||
if ((seg & SEGMENT_TI_MASK) == SEGMENT_LDT) {
|
||||
u32 *desc;
|
||||
struct desc_struct *desc;
|
||||
unsigned long base;
|
||||
|
||||
seg &= ~7UL;
|
||||
@ -33,12 +34,10 @@ unsigned long convert_ip_to_linear(struct task_struct *child, struct pt_regs *re
|
||||
addr = -1L; /* bogus selector, access would fault */
|
||||
else {
|
||||
desc = child->mm->context.ldt + seg;
|
||||
base = ((desc[0] >> 16) |
|
||||
((desc[1] & 0xff) << 16) |
|
||||
(desc[1] & 0xff000000));
|
||||
base = get_desc_base(desc);
|
||||
|
||||
/* 16-bit code segment? */
|
||||
if (!((desc[1] >> 22) & 1))
|
||||
if (!desc->d)
|
||||
addr &= 0xffff;
|
||||
addr += base;
|
||||
}
|
||||
|
@ -786,27 +786,6 @@ do_spurious_interrupt_bug(struct pt_regs *regs, long error_code)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
unsigned long patch_espfix_desc(unsigned long uesp, unsigned long kesp)
|
||||
{
|
||||
struct desc_struct *gdt = get_cpu_gdt_table(smp_processor_id());
|
||||
unsigned long base = (kesp - uesp) & -THREAD_SIZE;
|
||||
unsigned long new_kesp = kesp - base;
|
||||
unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT;
|
||||
__u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS];
|
||||
|
||||
/* Set up base for espfix segment */
|
||||
desc &= 0x00f0ff0000000000ULL;
|
||||
desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) |
|
||||
((((__u64)base) << 32) & 0xff00000000000000ULL) |
|
||||
((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) |
|
||||
(lim_pages & 0xffff);
|
||||
*(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc;
|
||||
|
||||
return new_kesp;
|
||||
}
|
||||
#endif
|
||||
|
||||
asmlinkage void __attribute__((weak)) smp_thermal_interrupt(void)
|
||||
{
|
||||
}
|
||||
|
Reference in New Issue
Block a user