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

Commit ae82157b authored by Alexander van Heukelum's avatar Alexander van Heukelum Committed by Ingo Molnar
Browse files

x86, traps, i386: factor out lazy io-bitmap copy



x86_64 does not do the lazy io-bitmap dance. Putting it in
its own function makes i386's do_general_protection look
much more like x86_64's.

Signed-off-by: default avatarAlexander van Heukelum <heukelum@fastmail.fm>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent a28680b4
Loading
Loading
Loading
Loading
+43 −33
Original line number Original line Diff line number Diff line
@@ -95,6 +95,47 @@ die_if_kernel(const char *str, struct pt_regs *regs, long err)
		die(str, regs, err);
		die(str, regs, err);
}
}


/*
 * Perform the lazy TSS's I/O bitmap copy. If the TSS has an
 * invalid offset set (the LAZY one) and the faulting thread has
 * a valid I/O bitmap pointer, we copy the I/O bitmap in the TSS,
 * we set the offset field correctly and return 1.
 */
static int lazy_iobitmap_copy(void)
{
	struct thread_struct *thread;
	struct tss_struct *tss;
	int cpu;

	cpu = get_cpu();
	tss = &per_cpu(init_tss, cpu);
	thread = &current->thread;

	if (tss->x86_tss.io_bitmap_base == INVALID_IO_BITMAP_OFFSET_LAZY &&
	    thread->io_bitmap_ptr) {
		memcpy(tss->io_bitmap, thread->io_bitmap_ptr,
		       thread->io_bitmap_max);
		/*
		 * If the previously set map was extending to higher ports
		 * than the current one, pad extra space with 0xff (no access).
		 */
		if (thread->io_bitmap_max < tss->io_bitmap_max) {
			memset((char *) tss->io_bitmap +
				thread->io_bitmap_max, 0xff,
				tss->io_bitmap_max - thread->io_bitmap_max);
		}
		tss->io_bitmap_max = thread->io_bitmap_max;
		tss->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET;
		tss->io_bitmap_owner = thread;
		put_cpu();

		return 1;
	}
	put_cpu();

	return 0;
}

static void __kprobes
static void __kprobes
do_trap(int trapnr, int signr, char *str, struct pt_regs *regs,
do_trap(int trapnr, int signr, char *str, struct pt_regs *regs,
	long error_code, siginfo_t *info)
	long error_code, siginfo_t *info)
@@ -187,44 +228,13 @@ void __kprobes
do_general_protection(struct pt_regs *regs, long error_code)
do_general_protection(struct pt_regs *regs, long error_code)
{
{
	struct task_struct *tsk;
	struct task_struct *tsk;
	struct thread_struct *thread;
	struct tss_struct *tss;
	int cpu;


	conditional_sti(regs);
	conditional_sti(regs);


	cpu = get_cpu();
	if (lazy_iobitmap_copy()) {
	tss = &per_cpu(init_tss, cpu);
		/* restart the faulting instruction */
	thread = &current->thread;

	/*
	 * Perform the lazy TSS's I/O bitmap copy. If the TSS has an
	 * invalid offset set (the LAZY one) and the faulting thread has
	 * a valid I/O bitmap pointer, we copy the I/O bitmap in the TSS
	 * and we set the offset field correctly. Then we let the CPU to
	 * restart the faulting instruction.
	 */
	if (tss->x86_tss.io_bitmap_base == INVALID_IO_BITMAP_OFFSET_LAZY &&
	    thread->io_bitmap_ptr) {
		memcpy(tss->io_bitmap, thread->io_bitmap_ptr,
		       thread->io_bitmap_max);
		/*
		 * If the previously set map was extending to higher ports
		 * than the current one, pad extra space with 0xff (no access).
		 */
		if (thread->io_bitmap_max < tss->io_bitmap_max) {
			memset((char *) tss->io_bitmap +
				thread->io_bitmap_max, 0xff,
				tss->io_bitmap_max - thread->io_bitmap_max);
		}
		tss->io_bitmap_max = thread->io_bitmap_max;
		tss->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET;
		tss->io_bitmap_owner = thread;
		put_cpu();

		return;
		return;
	}
	}
	put_cpu();


	if (regs->flags & X86_VM_MASK)
	if (regs->flags & X86_VM_MASK)
		goto gp_in_vm86;
		goto gp_in_vm86;