[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH 2/4] i386: Add AP variants of descriptor tables
From: |
Samuel Thibault |
Subject: |
Re: [PATCH 2/4] i386: Add AP variants of descriptor tables |
Date: |
Sun, 29 Jan 2023 23:50:11 +0100 |
User-agent: |
NeoMutt/20170609 (1.8.3) |
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.
- [PATCH 0/4] gnumach smp preparation, Damien Zammit, 2023/01/21
- [PATCH 1/4] i386/apic: Add ifdefs for APIC for mask/unmask irqs, Damien Zammit, 2023/01/21
- [PATCH 2/4] i386: Add AP variants of descriptor tables, Damien Zammit, 2023/01/21
- Re: [PATCH 2/4] i386: Add AP variants of descriptor tables,
Samuel Thibault <=
- [PATCH 4/4] Add cpu_number and cpuboot, Damien Zammit, 2023/01/21
- Re: [PATCH 4/4] Add cpu_number and cpuboot, Flávio Cruz, 2023/01/24
- Re: [PATCH 4/4] Add cpu_number and cpuboot, Samuel Thibault, 2023/01/24
- Re: [PATCH 4/4] Add cpu_number and cpuboot, Almudena Garcia, 2023/01/24
- Re: [PATCH 4/4] Add cpu_number and cpuboot, Flávio Cruz, 2023/01/25
- Re: [PATCH 4/4] Add cpu_number and cpuboot, Jessica Clarke, 2023/01/25
- Re: [PATCH 4/4] Add cpu_number and cpuboot, Flávio Cruz, 2023/01/25
- Re: [PATCH 4/4] Add cpu_number and cpuboot, Samuel Thibault, 2023/01/29
- [PATCH 3/4] i386: Fix lapic and ioapic for smp, Damien Zammit, 2023/01/21