smp: Force userspace preemption on other cores.

This commit is contained in:
K. Lange 2021-09-02 21:38:30 +09:00
parent db9c2a6d3f
commit 6eaeff3451
6 changed files with 39 additions and 0 deletions

4
apps/test-loop.c Normal file
View File

@ -0,0 +1,4 @@
int main(int argc, char * argv[]) {
while (1);
return 0;
}

View File

@ -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 */

View File

@ -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"

View File

@ -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;

View File

@ -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:

View File

@ -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;