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

Commit 56adbe9d authored by Rusty Russell's avatar Rusty Russell
Browse files

Make shadow IDT a complete IDT with 256 entries.



This simplifies the code a little, in preparation for allowing
alternate system call vectors in guests (Plan 9 uses 0x40).

Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
parent 48245cc0
Loading
Loading
Loading
Loading
+19 −30
Original line number Original line Diff line number Diff line
@@ -218,10 +218,9 @@ int deliver_trap(struct lguest *lg, unsigned int num)
 * system calls down from 1750ns to 270ns.  Plus, if lguest didn't do it, all
 * system calls down from 1750ns to 270ns.  Plus, if lguest didn't do it, all
 * the other hypervisors would tease it.
 * the other hypervisors would tease it.
 *
 *
 * This routine determines if a trap can be delivered directly. */
 * This routine indicates if a particular trap number could be delivered
static int direct_trap(const struct lguest *lg,
 * directly. */
		       const struct desc_struct *trap,
static int direct_trap(unsigned int num)
		       unsigned int num)
{
{
	/* Hardware interrupts don't go to the Guest at all (except system
	/* Hardware interrupts don't go to the Guest at all (except system
	 * call). */
	 * call). */
@@ -232,14 +231,7 @@ static int direct_trap(const struct lguest *lg,
	 * fault address), general protection faults (in/out emulation) and
	 * fault address), general protection faults (in/out emulation) and
	 * device not available (TS handling), and of course, the hypercall
	 * device not available (TS handling), and of course, the hypercall
	 * trap. */
	 * trap. */
	if (num == 14 || num == 13 || num == 7 || num == LGUEST_TRAP_ENTRY)
	return num != 14 && num != 13 && num != 7 && num != LGUEST_TRAP_ENTRY;
		return 0;

	/* Only trap gates (type 15) can go direct to the Guest.  Interrupt
	 * gates (type 14) disable interrupts as they are entered, which we
	 * never let the Guest do.  Not present entries (type 0x0) also can't
	 * go direct, of course 8) */
	return idt_type(trap->a, trap->b) == 0xF;
}
}
/*:*/
/*:*/


@@ -348,15 +340,11 @@ void load_guest_idt_entry(struct lguest *lg, unsigned int num, u32 lo, u32 hi)
	 * to copy this again. */
	 * to copy this again. */
	lg->changed |= CHANGED_IDT;
	lg->changed |= CHANGED_IDT;


	/* The IDT which we keep in "struct lguest" only contains 32 entries
	/* Check that the Guest doesn't try to step outside the bounds. */
	 * for the traps and LGUEST_IRQS (32) entries for interrupts.  We
	if (num >= ARRAY_SIZE(lg->idt))
	 * ignore attempts to set handlers for higher interrupt numbers, except
		kill_guest(lg, "Setting idt entry %u", num);
	 * for the system call "interrupt" at 128: we have a special IDT entry
	else
	 * for that. */
	if (num < ARRAY_SIZE(lg->idt))
		set_trap(lg, &lg->idt[num], num, lo, hi);
		set_trap(lg, &lg->idt[num], num, lo, hi);
	else if (num == SYSCALL_VECTOR)
		set_trap(lg, &lg->syscall_idt, num, lo, hi);
}
}


/* The default entry for each interrupt points into the Switcher routines which
/* The default entry for each interrupt points into the Switcher routines which
@@ -399,20 +387,21 @@ void copy_traps(const struct lguest *lg, struct desc_struct *idt,


	/* We can simply copy the direct traps, otherwise we use the default
	/* We can simply copy the direct traps, otherwise we use the default
	 * ones in the Switcher: they will return to the Host. */
	 * ones in the Switcher: they will return to the Host. */
	for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++) {
	for (i = 0; i < ARRAY_SIZE(lg->idt); i++) {
		if (direct_trap(lg, &lg->idt[i], i))
		/* If no Guest can ever override this trap, leave it alone. */
		if (!direct_trap(i))
			continue;

		/* Only trap gates (type 15) can go direct to the Guest.
		 * Interrupt gates (type 14) disable interrupts as they are
		 * entered, which we never let the Guest do.  Not present
		 * entries (type 0x0) also can't go direct, of course. */
		if (idt_type(lg->idt[i].a, lg->idt[i].b) == 0xF)
			idt[i] = lg->idt[i];
			idt[i] = lg->idt[i];
		else
		else
			/* Reset it to the default. */
			default_idt_entry(&idt[i], i, def[i]);
			default_idt_entry(&idt[i], i, def[i]);
	}
	}

	/* Don't forget the system call trap!  The IDT entries for other
	 * interupts never change, so no need to copy them. */
	i = SYSCALL_VECTOR;
	if (direct_trap(lg, &lg->syscall_idt, i))
		idt[i] = lg->syscall_idt;
	else
		default_idt_entry(&idt[i], i, def[i]);
}
}


void guest_set_clockevent(struct lguest *lg, unsigned long delta)
void guest_set_clockevent(struct lguest *lg, unsigned long delta)
+1 −2
Original line number Original line Diff line number Diff line
@@ -184,8 +184,7 @@ struct lguest
	struct desc_struct gdt[GDT_ENTRIES];
	struct desc_struct gdt[GDT_ENTRIES];


	/* The IDT entries: some copied into lguest_ro_state when running. */
	/* The IDT entries: some copied into lguest_ro_state when running. */
	struct desc_struct idt[FIRST_EXTERNAL_VECTOR+LGUEST_IRQS];
	struct desc_struct idt[IDT_ENTRIES];
	struct desc_struct syscall_idt;


	/* Virtual clock device */
	/* Virtual clock device */
	struct hrtimer hrt;
	struct hrtimer hrt;