smp: Force userspace preemption on other cores.
This commit is contained in:
parent
db9c2a6d3f
commit
6eaeff3451
4
apps/test-loop.c
Normal file
4
apps/test-loop.c
Normal file
@ -0,0 +1,4 @@
|
||||
int main(int argc, char * argv[]) {
|
||||
while (1);
|
||||
return 0;
|
||||
}
|
@ -50,6 +50,7 @@ extern struct regs * _irq12(struct regs*);
|
||||
extern struct regs * _irq13(struct regs*);
|
||||
extern struct regs * _irq14(struct regs*);
|
||||
extern struct regs * _irq15(struct regs*);
|
||||
extern struct regs * _isr123(struct regs*);
|
||||
extern struct regs * _isr124(struct regs*); /* Does not actually take regs */
|
||||
extern struct regs * _isr125(struct regs*); /* Does not actually take regs */
|
||||
extern struct regs * _isr126(struct regs*); /* Does not actually take regs */
|
||||
|
@ -233,11 +233,14 @@ void relative_time(unsigned long seconds, unsigned long subseconds, unsigned lon
|
||||
}
|
||||
}
|
||||
|
||||
void arch_tick_others(void);
|
||||
|
||||
int cmos_time_stuff(struct regs *r) {
|
||||
uint64_t timer_ticks, timer_subticks;
|
||||
update_ticks(&timer_ticks, &timer_subticks);
|
||||
wakeup_sleepers(timer_ticks, timer_subticks);
|
||||
irq_ack(0);
|
||||
arch_tick_others();
|
||||
switch_task(1);
|
||||
asm volatile (
|
||||
".global _ret_from_preempt_source\n"
|
||||
|
@ -86,6 +86,7 @@ void idt_install(void) {
|
||||
idt_set_gate(46, _irq14, 0x08, 0x8E, 0);
|
||||
idt_set_gate(47, _irq15, 0x08, 0x8E, 0);
|
||||
|
||||
idt_set_gate(123, _isr123, 0x08, 0x8E, 0); /* Clock interrupt for other processors */
|
||||
idt_set_gate(124, _isr124, 0x08, 0x8E, 0); /* Bad TLB shootdown. */
|
||||
idt_set_gate(125, _isr125, 0x08, 0x8E, 0); /* Halts everyone. */
|
||||
idt_set_gate(126, _isr126, 0x08, 0x8E, 0); /* Does nothing, used to exit wait-for-interrupt sleep. */
|
||||
@ -234,6 +235,10 @@ struct regs * isr_handler(struct regs * r) {
|
||||
asm volatile("sti");
|
||||
return r;
|
||||
}
|
||||
case 123: {
|
||||
switch_task(1);
|
||||
return r;
|
||||
}
|
||||
case 39: {
|
||||
/* Spurious interrupt */
|
||||
break;
|
||||
|
@ -80,6 +80,27 @@ IRQ 15, 47
|
||||
/* syscall entry point */
|
||||
ISR_NOERR 127
|
||||
|
||||
.global _isr123
|
||||
.type _isr123, @function
|
||||
_isr123:
|
||||
/* Acknowledge IPI */
|
||||
pushq %r12
|
||||
mov (lapic_final), %r12
|
||||
add $0xb0, %r12
|
||||
movl $0, (%r12)
|
||||
popq %r12
|
||||
/* Are we in userspace? */
|
||||
cmpq $8, 8(%rsp)
|
||||
je 1f
|
||||
/* Then we can proceed! */
|
||||
pushq $0x00
|
||||
pushq $123
|
||||
jmp isr_common
|
||||
1:
|
||||
/* If we were not in userspace, nothing to do; we were already idle. */
|
||||
iretq
|
||||
|
||||
|
||||
.global _isr124
|
||||
.type _isr124, @function
|
||||
_isr124:
|
||||
|
@ -296,6 +296,11 @@ void arch_wakeup_others(void) {
|
||||
lapic_send_ipi(0, 0x7E | (3 << 18));
|
||||
}
|
||||
|
||||
void arch_tick_others(void) {
|
||||
if (!lapic_final || processor_count < 2) return;
|
||||
lapic_send_ipi(0, 0x7b | (3 << 18));
|
||||
}
|
||||
|
||||
void arch_tlb_shootdown(uintptr_t vaddr) {
|
||||
if (!lapic_final || processor_count < 2) return;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user