Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a75c54f9 authored by Rusty Russell's avatar Rusty Russell Committed by Andi Kleen
Browse files

[PATCH] i386: i386 separate hardware-defined TSS from Linux additions



On Thu, 2007-03-29 at 13:16 +0200, Andi Kleen wrote:
> Please clean it up properly with two structs.

Not sure about this, now I've done it.  Running it here.

If you like it, I can do x86-64 as well.

==
lguest defines its own TSS struct because the "struct tss_struct"
contains linux-specific additions.  Andi asked me to split the struct
in processor.h.

Unfortunately it makes usage a little awkward.

Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
parent 82d1bb72
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -93,7 +93,7 @@ void foo(void)
	OFFSET(pbe_next, pbe, next);

	/* Offset from the sysenter stack to tss.esp0 */
	DEFINE(TSS_sysenter_esp0, offsetof(struct tss_struct, esp0) -
	DEFINE(TSS_sysenter_esp0, offsetof(struct tss_struct, x86_tss.esp0) -
		 sizeof(struct tss_struct));

	DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
+16 −13
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ static void doublefault_fn(void)
		printk("double fault, tss at %08lx\n", tss);

		if (ptr_ok(tss)) {
			struct tss_struct *t = (struct tss_struct *)tss;
			struct i386_hw_tss *t = (struct i386_hw_tss *)tss;

			printk("eip = %08lx, esp = %08lx\n", t->eip, t->esp);

@@ -49,13 +49,15 @@ static void doublefault_fn(void)
}

struct tss_struct doublefault_tss __cacheline_aligned = {
	.x86_tss = {
		.esp0		= STACK_START,
		.ss0		= __KERNEL_DS,
		.ldt		= 0,
		.io_bitmap_base	= INVALID_IO_BITMAP_OFFSET,

		.eip		= (unsigned long) doublefault_fn,
	.eflags		= X86_EFLAGS_SF | 0x2,	/* 0x2 bit is always set */
		/* 0x2 bit is always set */
		.eflags		= X86_EFLAGS_SF | 0x2,
		.esp		= STACK_START,
		.es		= __USER_DS,
		.cs		= __KERNEL_CS,
@@ -63,4 +65,5 @@ struct tss_struct doublefault_tss __cacheline_aligned = {
		.ds		= __USER_DS,

		.__cr3		= __pa(swapper_pg_dir)
	}
};
+1 −1
Original line number Diff line number Diff line
@@ -114,7 +114,7 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
	 * Reset the owner so that a process switch will not set
	 * tss->io_bitmap_base to IO_BITMAP_OFFSET.
	 */
	tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY;
	tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY;
	tss->io_bitmap_owner = NULL;

	put_cpu();
+4 −4
Original line number Diff line number Diff line
@@ -375,7 +375,7 @@ void exit_thread(void)
		t->io_bitmap_max = 0;
		tss->io_bitmap_owner = NULL;
		tss->io_bitmap_max = 0;
		tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET;
		tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET;
		put_cpu();
	}
}
@@ -554,7 +554,7 @@ static noinline void __switch_to_xtra(struct task_struct *next_p,
		 * Disable the bitmap via an invalid offset. We still cache
		 * the previous bitmap owner and the IO bitmap contents:
		 */
		tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET;
		tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET;
		return;
	}

@@ -564,7 +564,7 @@ static noinline void __switch_to_xtra(struct task_struct *next_p,
		 * matches the next task, we dont have to do anything but
		 * to set a valid offset in the TSS:
		 */
		tss->io_bitmap_base = IO_BITMAP_OFFSET;
		tss->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET;
		return;
	}
	/*
@@ -576,7 +576,7 @@ static noinline void __switch_to_xtra(struct task_struct *next_p,
	 * redundant copies when the currently switched task does not
	 * perform any I/O during its timeslice.
	 */
	tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY;
	tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY;
}

/*
+3 −3
Original line number Diff line number Diff line
@@ -183,10 +183,10 @@ void enable_sep_cpu(void)
		return;
	}

	tss->ss1 = __KERNEL_CS;
	tss->esp1 = sizeof(struct tss_struct) + (unsigned long) tss;
	tss->x86_tss.ss1 = __KERNEL_CS;
	tss->x86_tss.esp1 = sizeof(struct tss_struct) + (unsigned long) tss;
	wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);
	wrmsr(MSR_IA32_SYSENTER_ESP, tss->esp1, 0);
	wrmsr(MSR_IA32_SYSENTER_ESP, tss->x86_tss.esp1, 0);
	wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long) sysenter_entry, 0);
	put_cpu();	
}
Loading