[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 3/3 gnumach] i386/x86_64: Add remote AST via IPI mechanism
From: |
Damien Zammit |
Subject: |
[PATCH 3/3 gnumach] i386/x86_64: Add remote AST via IPI mechanism |
Date: |
Fri, 11 Aug 2023 08:35:04 +0000 |
---
i386/i386/ast_check.c | 4 ++++
i386/i386/i386asm.sym | 1 +
i386/i386/locore.S | 1 +
i386/i386/smp.c | 16 +++++++++++++---
i386/i386/smp.h | 1 +
i386/i386at/idt.h | 3 +++
i386/i386at/int_init.c | 4 ++++
i386/i386at/interrupt.S | 8 ++++++++
x86_64/interrupt.S | 7 +++++++
9 files changed, 42 insertions(+), 3 deletions(-)
diff --git a/i386/i386/ast_check.c b/i386/i386/ast_check.c
index 5121abf1..61cd5e87 100644
--- a/i386/i386/ast_check.c
+++ b/i386/i386/ast_check.c
@@ -34,6 +34,9 @@
#include <kern/ast.h>
#include <kern/processor.h>
+#include <kern/smp.h>
+#include <machine/cpu_number.h>
+#include <machine/apic.h>
/*
* Initialize for remote invocation of ast_check.
@@ -47,6 +50,7 @@ void init_ast_check(const processor_t processor)
*/
void cause_ast_check(const processor_t processor)
{
+ smp_remote_ast(apic_get_cpu_apic_id(processor->slot_num));
}
#endif /* NCPUS > 1 */
diff --git a/i386/i386/i386asm.sym b/i386/i386/i386asm.sym
index 8af0c5d6..18b208e9 100644
--- a/i386/i386/i386asm.sym
+++ b/i386/i386/i386asm.sym
@@ -48,6 +48,7 @@
#include <i386/apic.h>
#include <i386/xen.h>
+expr CALL_LOCAL_AST_BASE
expr CALL_SINGLE_FUNCTION_BASE
offset ApicLocalUnit lu apic_id APIC_ID
diff --git a/i386/i386/locore.S b/i386/i386/locore.S
index 67fe4257..96ed958b 100644
--- a/i386/i386/locore.S
+++ b/i386/i386/locore.S
@@ -652,6 +652,7 @@ INTERRUPT(21)
INTERRUPT(22)
INTERRUPT(23)
#endif
+INTERRUPT(CALL_LOCAL_AST_BASE)
/* Invalidate TLB IPI to call pmap_update_interrupt() on a specific cpu */
INTERRUPT(CALL_SINGLE_FUNCTION_BASE)
#ifdef APIC
diff --git a/i386/i386/smp.c b/i386/i386/smp.c
index c0149a3b..f3810370 100644
--- a/i386/i386/smp.c
+++ b/i386/i386/smp.c
@@ -45,19 +45,19 @@ static void smp_data_init(void)
}
-void smp_pmap_update(unsigned apic_id)
+static void smp_send_ipi(unsigned apic_id, unsigned vector)
{
unsigned long flags;
cpu_intr_save(&flags);
- apic_send_ipi(NO_SHORTHAND, FIXED, PHYSICAL, ASSERT, EDGE,
CALL_SINGLE_FUNCTION_BASE, apic_id);
+ apic_send_ipi(NO_SHORTHAND, FIXED, PHYSICAL, ASSERT, EDGE, vector,
apic_id);
do {
cpu_pause();
} while(lapic->icr_low.delivery_status == SEND_PENDING);
- apic_send_ipi(NO_SHORTHAND, FIXED, PHYSICAL, DE_ASSERT, EDGE,
CALL_SINGLE_FUNCTION_BASE, apic_id);
+ apic_send_ipi(NO_SHORTHAND, FIXED, PHYSICAL, DE_ASSERT, EDGE, vector,
apic_id);
do {
cpu_pause();
@@ -66,6 +66,16 @@ void smp_pmap_update(unsigned apic_id)
cpu_intr_restore(flags);
}
+void smp_remote_ast(unsigned apic_id)
+{
+ smp_send_ipi(apic_id, CALL_LOCAL_AST_BASE);
+}
+
+void smp_pmap_update(unsigned apic_id)
+{
+ smp_send_ipi(apic_id, CALL_SINGLE_FUNCTION_BASE);
+}
+
/* See Intel IA32/64 Software Developer's Manual 3A Section 8.4.4.1 */
void smp_startup_cpu(unsigned apic_id, unsigned vector)
{
diff --git a/i386/i386/smp.h b/i386/i386/smp.h
index 1faa39cd..784936ea 100644
--- a/i386/i386/smp.h
+++ b/i386/i386/smp.h
@@ -22,6 +22,7 @@
#define _SMP_H_
int smp_init(void);
+void smp_remote_ast(unsigned apic_id);
void smp_pmap_update(unsigned apic_id);
void smp_startup_cpu(unsigned apic_id, unsigned vector);
diff --git a/i386/i386at/idt.h b/i386/i386at/idt.h
index f080bb12..1c30eb7d 100644
--- a/i386/i386at/idt.h
+++ b/i386/i386at/idt.h
@@ -37,6 +37,9 @@
/* IOAPIC spurious interrupt vector set to 0xff */
#define IOAPIC_SPURIOUS_BASE 0xff
+/* Remote -> local AST requests */
+#define CALL_LOCAL_AST_BASE 0xfa
+
/* Currently for TLB shootdowns */
#define CALL_SINGLE_FUNCTION_BASE 0xfb
diff --git a/i386/i386at/int_init.c b/i386/i386at/int_init.c
index e7fe7e31..e3c4b8c8 100644
--- a/i386/i386at/int_init.c
+++ b/i386/i386at/int_init.c
@@ -45,6 +45,10 @@ int_fill(struct real_gate *myidt)
int_entry_table[i], KERNEL_CS,
ACC_PL_K|ACC_INTR_GATE, 0);
}
+ fill_idt_gate(myidt, CALL_LOCAL_AST_BASE,
+ int_entry_table[i], KERNEL_CS,
+ ACC_PL_K|ACC_INTR_GATE, 0);
+ i++;
fill_idt_gate(myidt, CALL_SINGLE_FUNCTION_BASE,
int_entry_table[i], KERNEL_CS,
ACC_PL_K|ACC_INTR_GATE, 0);
diff --git a/i386/i386at/interrupt.S b/i386/i386at/interrupt.S
index 1f661f8d..a20707da 100644
--- a/i386/i386at/interrupt.S
+++ b/i386/i386at/interrupt.S
@@ -46,6 +46,9 @@ ENTRY(interrupt)
cmpl $CALL_SINGLE_FUNCTION_BASE,%eax /* was this a SMP call
single function request? */
je _call_single
+ cmpl $CALL_LOCAL_AST_BASE,%eax /* was this a SMP remote ->
local ast request? */
+ je _call_local_ast
+
subl $24,%esp /* Two local variables + 4 parameters */
movl %eax,S_IRQ /* save irq number */
call spl7 /* set ipl */
@@ -127,4 +130,9 @@ _call_single:
call EXT(lapic_eoi) /* lapic EOI before the handler to
allow extra update */
call EXT(pmap_update_interrupt) /* TODO: Allow other functions */
ret
+
+_call_local_ast:
+ call EXT(ast_check) /* AST check on this cpu */
+ call EXT(lapic_eoi) /* lapic EOI */
+ ret
END(interrupt)
diff --git a/x86_64/interrupt.S b/x86_64/interrupt.S
index eabf934e..ec6dc96c 100644
--- a/x86_64/interrupt.S
+++ b/x86_64/interrupt.S
@@ -45,6 +45,9 @@ ENTRY(interrupt)
cmpl $CALL_SINGLE_FUNCTION_BASE,%eax /* was this a SMP call single
function request? */
je _call_single
+
+ cmpl $CALL_LOCAL_AST_BASE,%eax /* was this a SMP remote ->
local ast request? */
+ je _call_local_ast
#endif
subq $16,%rsp /* Two local variables */
movl %eax,S_IRQ /* save irq number */
@@ -122,6 +125,10 @@ _call_single:
call EXT(lapic_eoi) /* lapic EOI before the handler to
allow extra update */
call EXT(pmap_update_interrupt) /* TODO: Allow other functions */
ret
+_call_local_ast:
+ call EXT(ast_check) /* AST check on this cpu */
+ call EXT(lapic_eoi) /* lapic EOI */
+ ret
#endif
addq $16,%rsp /* pop local variables */
_no_eoi:
--
2.40.1