It seems most of my comments didn't get applied. To be able to progress at all, I commited this along with the changes I requested.
Samuel Damien Zammit, le sam. 21 janv. 2023 08:04:52 +0000, a ecrit: > --- > i386/i386/apic.c | 6 ++++++ > i386/i386/gdt.c | 47 ++++++++++++++++++++++++++++++----------- > i386/i386/gdt.h | 1 + > i386/i386/i386asm.sym | 1 + > i386/i386/idt-gen.h | 4 ++-- > i386/i386/idt.c | 25 ++++++++++++++++------ > i386/i386/ktss.c | 30 +++++++++++++++++++------- > i386/i386/ktss.h | 1 + > i386/i386/ldt.c | 31 ++++++++++++++++++++------- > i386/i386/ldt.h | 9 ++++---- > i386/i386/locore.S | 4 ++++ > i386/i386/mp_desc.h | 2 ++ > i386/i386at/idt.h | 4 ++++ > i386/i386at/int_init.c | 39 +++++++++++++++++++++++++--------- > i386/i386at/int_init.h | 1 + > i386/i386at/interrupt.S | 8 +++++++ > i386/i386at/ioapic.c | 6 ------ > 17 files changed, 163 insertions(+), 56 deletions(-) > > diff --git a/i386/i386/apic.c b/i386/i386/apic.c > index 2e0c1776..d30084e2 100644 > --- a/i386/i386/apic.c > +++ b/i386/i386/apic.c > @@ -234,3 +234,9 @@ void apic_print_info(void) > } > } > } > + > +void > +lapic_eoi(void) > +{ > + lapic->eoi.r = 0; > +} > diff --git a/i386/i386/gdt.c b/i386/i386/gdt.c > index fb18360e..ddda603b 100644 > --- a/i386/i386/gdt.c > +++ b/i386/i386/gdt.c > @@ -39,6 +39,7 @@ > #include "vm_param.h" > #include "seg.h" > #include "gdt.h" > +#include "mp_desc.h" > > #ifdef MACH_PV_DESCRIPTORS > /* It is actually defined in xen_boothdr.S */ > @@ -46,28 +47,28 @@ extern > #endif /* MACH_PV_DESCRIPTORS */ > struct real_descriptor gdt[GDTSZ]; > > -void > -gdt_init(void) > +static void > +gdt_fill(struct real_descriptor *mygdt) > { > /* Initialize the kernel code and data segment descriptors. */ > #ifdef __x86_64__ > assert(LINEAR_MIN_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS == 0); > - fill_gdt_descriptor(KERNEL_CS, 0, 0, ACC_PL_K|ACC_CODE_R, SZ_64); > - fill_gdt_descriptor(KERNEL_DS, 0, 0, ACC_PL_K|ACC_DATA_W, SZ_64); > + _fill_gdt_descriptor(mygdt, KERNEL_CS, 0, 0, ACC_PL_K|ACC_CODE_R, > SZ_64); > + _fill_gdt_descriptor(mygdt, KERNEL_DS, 0, 0, ACC_PL_K|ACC_DATA_W, > SZ_64); > #ifndef MACH_PV_DESCRIPTORS > - fill_gdt_descriptor(LINEAR_DS, 0, 0, ACC_PL_K|ACC_DATA_W, SZ_64); > + _fill_gdt_descriptor(mygdt, LINEAR_DS, 0, 0, ACC_PL_K|ACC_DATA_W, > SZ_64); > #endif /* MACH_PV_DESCRIPTORS */ > #else > - fill_gdt_descriptor(KERNEL_CS, > + _fill_gdt_descriptor(mygdt, KERNEL_CS, > LINEAR_MIN_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS, > LINEAR_MAX_KERNEL_ADDRESS - > (LINEAR_MIN_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS) - 1, > ACC_PL_K|ACC_CODE_R, SZ_32); > - fill_gdt_descriptor(KERNEL_DS, > + _fill_gdt_descriptor(mygdt, KERNEL_DS, > LINEAR_MIN_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS, > LINEAR_MAX_KERNEL_ADDRESS - > (LINEAR_MIN_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS) - 1, > ACC_PL_K|ACC_DATA_W, SZ_32); > #ifndef MACH_PV_DESCRIPTORS > - fill_gdt_descriptor(LINEAR_DS, > + _fill_gdt_descriptor(mygdt, LINEAR_DS, > 0, > 0xffffffff, > ACC_PL_K|ACC_DATA_W, SZ_32); > @@ -75,8 +76,8 @@ gdt_init(void) > #endif > > #ifdef MACH_PV_DESCRIPTORS > - unsigned long frame = kv_to_mfn(gdt); > - pmap_set_page_readonly(gdt); > + unsigned long frame = kv_to_mfn(mygdt); > + pmap_set_page_readonly(mygdt); > if (hyp_set_gdt(kv_to_la(&frame), GDTSZ)) > panic("couldn't set gdt\n"); > #endif > @@ -94,12 +95,16 @@ gdt_init(void) > { > struct pseudo_descriptor pdesc; > > - pdesc.limit = sizeof(gdt)-1; > - pdesc.linear_base = kvtolin(&gdt); > + pdesc.limit = (GDTSZ * sizeof(struct real_descriptor))-1; > + pdesc.linear_base = kvtolin(mygdt); > lgdt(&pdesc); > } > #endif /* MACH_PV_DESCRIPTORS */ > +} > > +static void > +reload_segs(void) > +{ > /* Reload all the segment registers from the new GDT. > We must load ds and es with 0 before loading them with KERNEL_DS > because some processors will "optimize out" the loads > @@ -117,6 +122,15 @@ gdt_init(void) > "movw %w1,%%ss\n" > : : "i" (KERNEL_CS), "r" (KERNEL_DS), "r" (0)); > #endif > +} > + > +void > +gdt_init(void) > +{ > + gdt_fill(gdt); > + > + reload_segs(); > + > #ifdef MACH_PV_PAGETABLES > #if VM_MIN_KERNEL_ADDRESS != LINEAR_MIN_KERNEL_ADDRESS > /* things now get shifted */ > @@ -128,3 +142,12 @@ gdt_init(void) > #endif /* MACH_PV_PAGETABLES */ > } > > +#if NCPUS > 1 > +void > +ap_gdt_init(int cpu) > +{ > + gdt_fill(mp_gdt[cpu]); > + > + reload_segs(); > +} > +#endif > diff --git a/i386/i386/gdt.h b/i386/i386/gdt.h > index 9879ad3e..5def73cb 100644 > --- a/i386/i386/gdt.h > +++ b/i386/i386/gdt.h > @@ -115,5 +115,6 @@ extern struct real_descriptor gdt[GDTSZ]; > #endif > > extern void gdt_init(void); > +extern void ap_gdt_init(int cpu); > > #endif /* _I386_GDT_ */ > diff --git a/i386/i386/i386asm.sym b/i386/i386/i386asm.sym > index 9f4ebe55..85658b30 100644 > --- a/i386/i386/i386asm.sym > +++ b/i386/i386/i386asm.sym > @@ -47,6 +47,7 @@ > #include <i386/mp_desc.h> > #include <i386/xen.h> > > +expr CALL_SINGLE_FUNCTION_BASE > > offset thread th pcb > offset thread th task > diff --git a/i386/i386/idt-gen.h b/i386/i386/idt-gen.h > index f86afb41..daa6aaf2 100644 > --- a/i386/i386/idt-gen.h > +++ b/i386/i386/idt-gen.h > @@ -41,7 +41,7 @@ > extern struct real_gate idt[IDTSZ]; > > /* Fill a gate in the IDT. */ > -#define fill_idt_gate(int_num, entry, selector, access, dword_count) \ > - fill_gate(&idt[int_num], entry, selector, access, dword_count) > +#define fill_idt_gate(_idt, int_num, entry, selector, access, dword_count) \ > + fill_gate(&_idt[int_num], entry, selector, access, dword_count) > > #endif /* _I386_IDT_ */ > diff --git a/i386/i386/idt.c b/i386/i386/idt.c > index c6a778f1..06ff6dbc 100644 > --- a/i386/i386/idt.c > +++ b/i386/i386/idt.c > @@ -25,6 +25,7 @@ > #include <i386/seg.h> > #include <i386at/idt.h> > #include <i386/gdt.h> > +#include <i386/mp_desc.h> > > struct real_gate idt[IDTSZ]; > > @@ -36,7 +37,8 @@ struct idt_init_entry > }; > extern struct idt_init_entry idt_inittab[]; > > -void idt_init(void) > +static void > +idt_fill(struct real_gate *myidt) > { > #ifdef MACH_PV_DESCRIPTORS > if (hyp_set_trap_table(kvtolin(idt_inittab))) > @@ -47,18 +49,29 @@ void idt_init(void) > /* Initialize the exception vectors from the idt_inittab. */ > while (iie->entrypoint) > { > - fill_idt_gate(iie->vector, iie->entrypoint, KERNEL_CS, > iie->type, 0); > + fill_idt_gate(myidt, iie->vector, iie->entrypoint, KERNEL_CS, > iie->type, 0); > iie++; > } > +#endif /* MACH_PV_DESCRIPTORS */ > > - /* Load the IDT pointer into the processor. */ > + /* Load the IDT pointer into the processor */ > { > struct pseudo_descriptor pdesc; > > - pdesc.limit = sizeof(idt)-1; > - pdesc.linear_base = kvtolin(&idt); > + pdesc.limit = (IDTSZ * sizeof(struct real_gate))-1; > + pdesc.linear_base = kvtolin(myidt); > lidt(&pdesc); > } > -#endif /* MACH_PV_DESCRIPTORS */ > } > > +void idt_init(void) > +{ > + idt_fill(idt); > +} > + > +#if NCPUS > 1 > +void ap_idt_init(int cpu) > +{ > + idt_fill(mp_desc_table[cpu]->idt); > +} > +#endif > diff --git a/i386/i386/ktss.c b/i386/i386/ktss.c > index 0d21d3eb..5cc260fc 100644 > --- a/i386/i386/ktss.c > +++ b/i386/i386/ktss.c > @@ -35,12 +35,13 @@ > #include "seg.h" > #include "gdt.h" > #include "ktss.h" > +#include "mp_desc.h" > > /* A kernel TSS with a complete I/O bitmap. */ > struct task_tss ktss; > > void > -ktss_init(void) > +ktss_fill(struct task_tss *myktss, struct real_descriptor *mygdt) > { > /* XXX temporary exception stack */ > static int exception_stack[1024]; > @@ -52,24 +53,37 @@ ktss_init(void) > panic("couldn't register exception stack\n"); > #else /* MACH_RING1 */ > /* Initialize the master TSS descriptor. */ > - fill_gdt_sys_descriptor(KERNEL_TSS, > - kvtolin(&ktss), sizeof(struct task_tss) - 1, > + _fill_gdt_sys_descriptor(mygdt, KERNEL_TSS, > + kvtolin(myktss), sizeof(struct task_tss) - 1, > ACC_PL_K|ACC_TSS, 0); > > /* Initialize the master TSS. */ > #ifdef __x86_64__ > - ktss.tss.rsp0 = (unsigned long)(exception_stack+1024); > + myktss->tss.rsp0 = (unsigned long)(exception_stack+1024); > #else /* ! __x86_64__ */ > - ktss.tss.ss0 = KERNEL_DS; > - ktss.tss.esp0 = (unsigned long)(exception_stack+1024); > + myktss->tss.ss0 = KERNEL_DS; > + myktss->tss.esp0 = (unsigned long)(exception_stack+1024); > #endif /* __x86_64__ */ > > - ktss.tss.io_bit_map_offset = IOPB_INVAL; > + myktss->tss.io_bit_map_offset = IOPB_INVAL; > /* Set the last byte in the I/O bitmap to all 1's. */ > - ktss.barrier = 0xff; > + myktss->barrier = 0xff; > > /* Load the TSS. */ > ltr(KERNEL_TSS); > #endif /* MACH_RING1 */ > } > > +void > +ktss_init(void) > +{ > + ktss_fill(&ktss, gdt); > +} > + > +#if NCPUS > 1 > +void > +ap_ktss_init(int cpu) > +{ > + ktss_fill(&mp_desc_table[cpu]->ktss, mp_gdt[cpu]); > +} > +#endif > diff --git a/i386/i386/ktss.h b/i386/i386/ktss.h > index 304a877a..171332da 100644 > --- a/i386/i386/ktss.h > +++ b/i386/i386/ktss.h > @@ -28,5 +28,6 @@ > extern struct task_tss ktss; > > extern void ktss_init(void); > +extern void ap_ktss_init(int cpu); > > #endif /* _I386_KTSS_ */ > diff --git a/i386/i386/ldt.c b/i386/i386/ldt.c > index 261df93a..3f9ac8ff 100644 > --- a/i386/i386/ldt.c > +++ b/i386/i386/ldt.c > @@ -37,6 +37,7 @@ > #include "gdt.h" > #include "ldt.h" > #include "locore.h" > +#include "mp_desc.h" > > #ifdef MACH_PV_DESCRIPTORS > /* It is actually defined in xen_boothdr.S */ > @@ -45,37 +46,51 @@ extern > struct real_descriptor ldt[LDTSZ]; > > void > -ldt_init(void) > +ldt_fill(struct real_descriptor *myldt, struct real_descriptor *mygdt) > { > #ifdef MACH_PV_DESCRIPTORS > #ifdef MACH_PV_PAGETABLES > - pmap_set_page_readwrite(ldt); > + pmap_set_page_readwrite(myldt); > #endif /* MACH_PV_PAGETABLES */ > #else /* MACH_PV_DESCRIPTORS */ > /* Initialize the master LDT descriptor in the GDT. */ > - fill_gdt_sys_descriptor(KERNEL_LDT, > - kvtolin(&ldt), sizeof(ldt)-1, > + _fill_gdt_sys_descriptor(mygdt, KERNEL_LDT, > + kvtolin(myldt), (LDTSZ * sizeof(struct > real_descriptor))-1, > ACC_PL_K|ACC_LDT, 0); > #endif /* MACH_PV_DESCRIPTORS */ > > /* Initialize the 32bit LDT descriptors. */ > - fill_ldt_gate(USER_SCALL, > + fill_ldt_gate(myldt, USER_SCALL, > (vm_offset_t)&syscall, KERNEL_CS, > ACC_PL_U|ACC_CALL_GATE, 0); > - fill_ldt_descriptor(USER_CS, > + fill_ldt_descriptor(myldt, USER_CS, > VM_MIN_ADDRESS, > VM_MAX_ADDRESS-VM_MIN_ADDRESS-4096, > /* XXX LINEAR_... */ > ACC_PL_U|ACC_CODE_R, SZ_32); > - fill_ldt_descriptor(USER_DS, > + fill_ldt_descriptor(myldt, USER_DS, > VM_MIN_ADDRESS, > VM_MAX_ADDRESS-VM_MIN_ADDRESS-4096, > ACC_PL_U|ACC_DATA_W, SZ_32); > > /* Activate the LDT. */ > #ifdef MACH_PV_DESCRIPTORS > - hyp_set_ldt(&ldt, LDTSZ); > + hyp_set_ldt(myldt, LDTSZ); > #else /* MACH_PV_DESCRIPTORS */ > lldt(KERNEL_LDT); > #endif /* MACH_PV_DESCRIPTORS */ > } > + > +void > +ldt_init(void) > +{ > + ldt_fill(ldt, gdt); > +} > + > +#if NCPUS > 1 > +void > +ap_ldt_init(int cpu) > +{ > + ldt_fill(mp_desc_table[cpu]->ldt, mp_gdt[cpu]); > +} > +#endif > diff --git a/i386/i386/ldt.h b/i386/i386/ldt.h > index 1f0d7014..b15f11a5 100644 > --- a/i386/i386/ldt.h > +++ b/i386/i386/ldt.h > @@ -57,14 +57,15 @@ > extern struct real_descriptor ldt[LDTSZ]; > > /* Fill a 32bit segment descriptor in the LDT. */ > -#define fill_ldt_descriptor(selector, base, limit, access, sizebits) \ > - fill_descriptor(&ldt[sel_idx(selector)], base, limit, access, sizebits) > +#define fill_ldt_descriptor(_ldt, selector, base, limit, access, sizebits) \ > + fill_descriptor(&_ldt[sel_idx(selector)], base, limit, access, sizebits) > > -#define fill_ldt_gate(selector, offset, dest_selector, access, word_count) \ > - fill_gate((struct real_gate*)&ldt[sel_idx(selector)], \ > +#define fill_ldt_gate(_ldt, selector, offset, dest_selector, access, > word_count) \ > + fill_gate((struct real_gate*)&_ldt[sel_idx(selector)], \ > offset, dest_selector, access, word_count) > > void ldt_init(void); > +void ap_ldt_init(int cpu); > > #endif /* !__ASSEMBLER__ */ > > diff --git a/i386/i386/locore.S b/i386/i386/locore.S > index f50aca5d..ff78e80d 100644 > --- a/i386/i386/locore.S > +++ b/i386/i386/locore.S > @@ -649,6 +649,10 @@ INTERRUPT(20) > INTERRUPT(21) > INTERRUPT(22) > INTERRUPT(23) > +#endif > +/* Invalidate TLB IPI to call pmap_update_interrupt() on a specific cpu */ > +INTERRUPT(CALL_SINGLE_FUNCTION_BASE) > +#ifdef APIC > /* Spurious interrupt, set irq number to vect number */ > INTERRUPT(255) > #endif > diff --git a/i386/i386/mp_desc.h b/i386/i386/mp_desc.h > index ebe1471d..ede8775f 100644 > --- a/i386/i386/mp_desc.h > +++ b/i386/i386/mp_desc.h > @@ -27,6 +27,8 @@ > #ifndef _I386_MP_DESC_H_ > #define _I386_MP_DESC_H_ > > +#include <mach/kern_return.h> > + > #if MULTIPROCESSOR > > /* > diff --git a/i386/i386at/idt.h b/i386/i386at/idt.h > index ac065aef..f080bb12 100644 > --- a/i386/i386at/idt.h > +++ b/i386/i386at/idt.h > @@ -37,10 +37,14 @@ > /* IOAPIC spurious interrupt vector set to 0xff */ > #define IOAPIC_SPURIOUS_BASE 0xff > > +/* Currently for TLB shootdowns */ > +#define CALL_SINGLE_FUNCTION_BASE 0xfb > + > #include <i386/idt-gen.h> > > #ifndef __ASSEMBLER__ > extern void idt_init (void); > +extern void ap_idt_init (int cpu); > #endif /* __ASSEMBLER__ */ > > #endif /* _I386AT_IDT_ */ > diff --git a/i386/i386at/int_init.c b/i386/i386at/int_init.c > index 6da627dd..da552106 100644 > --- a/i386/i386at/int_init.c > +++ b/i386/i386at/int_init.c > @@ -22,29 +22,48 @@ > */ > > #include <i386at/idt.h> > -#include <i386/gdt.h> > +#include <i386/mp_desc.h> > +#include <i386/i386asm.h> > > /* defined in locore.S */ > extern vm_offset_t int_entry_table[]; > > -void int_init(void) > +void > +int_fill(struct real_gate *myidt) > { > int i; > #ifndef APIC > - for (i = 0; i < 16; i++) { > - fill_idt_gate(PIC_INT_BASE + i, > + int base = PIC_INT_BASE; > + int nirq = 16; > +#else > + int base = IOAPIC_INT_BASE; > + int nirq = 24; > +#endif > + > + for (i = 0; i < nirq; i++) { > + fill_idt_gate(myidt, base + i, > int_entry_table[i], KERNEL_CS, > ACC_PL_K|ACC_INTR_GATE, 0); > } > -#else > - for (i = 0; i < 24; i++) { > - fill_idt_gate(IOAPIC_INT_BASE + i, > + fill_idt_gate(myidt, CALL_SINGLE_FUNCTION_BASE, > int_entry_table[i], KERNEL_CS, > ACC_PL_K|ACC_INTR_GATE, 0); > - } > - fill_idt_gate(IOAPIC_SPURIOUS_BASE, > - int_entry_table[24], KERNEL_CS, > +#ifdef APIC > + fill_idt_gate(myidt, IOAPIC_SPURIOUS_BASE, > + int_entry_table[25], KERNEL_CS, > ACC_PL_K|ACC_INTR_GATE, 0); > #endif > } > > +void > +int_init(void) > +{ > + int_fill(idt); > +} > + > +#if NCPUS > 1 > +void ap_int_init(int cpu) > +{ > + int_fill(mp_desc_table[cpu]->idt); > +} > +#endif > diff --git a/i386/i386at/int_init.h b/i386/i386at/int_init.h > index f9b03b74..3c11ebce 100644 > --- a/i386/i386at/int_init.h > +++ b/i386/i386at/int_init.h > @@ -29,6 +29,7 @@ > > #ifndef __ASSEMBLER__ > extern void int_init (void); > +extern void ap_int_init (int cpu); > #endif /* __ASSEMBLER__ */ > > #endif /* _INT_INIT_H_ */ > diff --git a/i386/i386at/interrupt.S b/i386/i386at/interrupt.S > index 16e0df10..12aa15e1 100644 > --- a/i386/i386at/interrupt.S > +++ b/i386/i386at/interrupt.S > @@ -58,6 +58,9 @@ ENTRY(interrupt) > movl %eax,12(%esp) /* address of interrupted registers as > 4th arg */ > > movl S_IRQ,%eax /* copy irq number */ > + cmpl $251,%eax /* was this a SMP call single function > request? */ > + je _call_single > + > shll $2,%eax /* irq * 4 */ > movl EXT(iunit)(%eax),%edx /* get device unit number */ > movl %edx,(%esp) /* unit number as 1st arg */ > @@ -117,4 +120,9 @@ _isa_eoi: > addl $24,%esp /* pop local variables */ > _no_eoi: > ret > +_call_single: > + call EXT(pmap_update_interrupt) /* TODO: Allow other functions */ > + call EXT(lapic_eoi) /* lapic EOI */ > + addl $24,%esp > + ret > END(interrupt) > diff --git a/i386/i386at/ioapic.c b/i386/i386at/ioapic.c > index 3373aa71..c5eb3536 100644 > --- a/i386/i386at/ioapic.c > +++ b/i386/i386at/ioapic.c > @@ -233,12 +233,6 @@ ioapic_toggle(int pin, int mask) > ioapic_toggle_entry(apic, pin, mask); > } > > -void > -lapic_eoi(void) > -{ > - lapic->eoi.r = 0; > -} > - > void > ioapic_irq_eoi(int pin) > { > -- > 2.34.1 > > > -- Samuel --- Pour une évaluation indépendante, transparente et rigoureuse ! Je soutiens la Commission d'Évaluation de l'Inria.