Re: [PATCH] cpu_number: Short circuit if smp init not done

2023-02-03 Thread Samuel Thibault
Damien Zammit, le sam. 04 févr. 2023 03:30:45 +, a ecrit:
> This depends on serialised AP init patch.
> 
> Fixes warnings spewing at boot with APIC and SMP
> ---
>  i386/i386/cpu_number.c | 8 
>  1 file changed, 8 insertions(+)
> 
> diff --git a/i386/i386/cpu_number.c b/i386/i386/cpu_number.c
> index ad4c4b01..eca95d7a 100644
> --- a/i386/i386/cpu_number.c
> +++ b/i386/i386/cpu_number.c
> @@ -21,10 +21,16 @@
>  #include 
>  #include 
> 
> +extern int bspdone;

Please avoid introducing more such in-C extern declarations. We want
them in headers.

Samuel



[PATCH] cpu_number: Short circuit if smp init not done

2023-02-03 Thread Damien Zammit
This depends on serialised AP init patch.

Fixes warnings spewing at boot with APIC and SMP
---
 i386/i386/cpu_number.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/i386/i386/cpu_number.c b/i386/i386/cpu_number.c
index ad4c4b01..eca95d7a 100644
--- a/i386/i386/cpu_number.c
+++ b/i386/i386/cpu_number.c
@@ -21,10 +21,16 @@
 #include 
 #include 

+extern int bspdone;
+
 #if NCPUS > 1
 int cpu_number(void)
 {
int kernel_id, apic_id;
+
+   if (bspdone == 0)
+   return 0;
+
apic_id = apic_get_current_cpu();
if (apic_id < 0) {
printf("apic_get_current_cpu() failed, assuming BSP\n");
@@ -36,5 +42,7 @@ int cpu_number(void)
printf("apic_get_cpu_kernel_id() failed, assuming BSP\n");
kernel_id = 0;
}
+
+   return kernel_id;
 }
 #endif
--
2.34.1





Re: [PATCH 2/5 gnumach] i386: Refactor int stacks to be per cpu for SMP

2023-02-03 Thread Damien Zammit
On 4/2/23 12:27, Almudena Garcia wrote:
> But, added to interrupt stacks, the APs needs their own stacks once these are 
> running, to store data of the process which are executing.

I thought this kind of stack is dynamically allocated by the thread manager (?)

Damien




Re: [PATCH 2/5 gnumach] i386: Refactor int stacks to be per cpu for SMP

2023-02-03 Thread Almudena Garcia
But, added to interrupt stacks, the APs needs their own stacks once these
are running, to store data of the process which are executing.

El sáb., 4 feb. 2023 2:24, Damien Zammit  escribió:

> Hi Almu,
>
> On 3/2/23 02:56, Almudena Garcia wrote:
> > I already suggested move this to a function
> >
> > +#ifndef MACH_HYP
> > +/* Turn paging on.
> > + * TODO: Why does setting the WP bit here cause a crash?
> > + */
> > +set_cr0(get_cr0() | CR0_PG /* | CR0_WP */);
> > +set_cr0(get_cr0() & ~(CR0_CD | CR0_NW));
> > +if (CPU_HAS_FEATURE(CPU_FEATURE_PGE))
> > +set_cr4(get_cr4() | CR4_PGE);
>
> I moved this to a function called paging_enable()
>
>
> > I miss the stack's memory reserve and assignation for AP processors,
> which was usually make before startup these. Where are this?
>
> Interrupt stacks are pre-assigned by the compiler at a fixed location per
> cpu.  See "solid_intstack".
>
> Damien
>
>


Re: [PATCH 2/5 gnumach] i386: Refactor int stacks to be per cpu for SMP

2023-02-03 Thread Damien Zammit
Hi Almu,

On 3/2/23 02:56, Almudena Garcia wrote:
> I already suggested move this to a function
>
> +#ifndef MACH_HYP
> +    /* Turn paging on.
> +     * TODO: Why does setting the WP bit here cause a crash?
> +     */
> +    set_cr0(get_cr0() | CR0_PG /* | CR0_WP */);
> +    set_cr0(get_cr0() & ~(CR0_CD | CR0_NW));
> +    if (CPU_HAS_FEATURE(CPU_FEATURE_PGE))
> +        set_cr4(get_cr4() | CR4_PGE);

I moved this to a function called paging_enable()


> I miss the stack's memory reserve and assignation for AP processors, which 
> was usually make before startup these. Where are this?

Interrupt stacks are pre-assigned by the compiler at a fixed location per cpu.  
See "solid_intstack".

Damien




[PATCH v3] i386: Refactor int stacks to be per cpu for SMP

2023-02-03 Thread Damien Zammit
This also serialises the AP bringup, so paging can be enabled per cpu
one by one.

Also-by: Almudena Garcia 
---
 i386/i386/mp_desc.c | 230 
 i386/i386/mp_desc.h |   7 +-
 i386/i386at/boothdr.S   |  18 +++-
 i386/i386at/ioapic.c|   5 +-
 i386/i386at/model_dep.c |  33 +++---
 5 files changed, 201 insertions(+), 92 deletions(-)

diff --git a/i386/i386/mp_desc.c b/i386/i386/mp_desc.c
index bcf2fbe7..03b2ea68 100644
--- a/i386/i386/mp_desc.c
+++ b/i386/i386/mp_desc.c
@@ -24,25 +24,36 @@
  * the rights to redistribute these changes.
  */

-#ifNCPUS > 1
-
-#include 
-
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 #include 
 #include 
 #include 

 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 

+#include 
+#include 
+
 /*
  * The i386 needs an interrupt stack to keep the PCB stack from being
  * overrun by interrupts.  All interrupt stacks MUST lie at lower addresses
@@ -52,20 +63,35 @@
 /*
  * Addresses of bottom and top of interrupt stacks.
  */
-vm_offset_tinterrupt_stack[NCPUS];
 vm_offset_tint_stack_top[NCPUS];
 vm_offset_tint_stack_base[NCPUS];

-/*
- * Barrier address.
- */
-vm_offset_tint_stack_high;
+/* Interrupt stack allocation */
+uint8_t solid_intstack[NCPUS*INTSTACK_SIZE] __aligned(NCPUS*INTSTACK_SIZE);
+
+void
+interrupt_stack_alloc(void)
+{
+   int i;
+
+   /*
+* Set up pointers to the top of the interrupt stack.
+*/
+
+   for (i = 0; i < NCPUS; i++) {
+   int_stack_base[i] = (vm_offset_t) &solid_intstack[i * 
INTSTACK_SIZE];
+   int_stack_top[i] = (vm_offset_t) &solid_intstack[(i + 1) * 
INTSTACK_SIZE] - 4;
+   }
+}

+#ifNCPUS > 1
 /*
- * First cpu`s interrupt stack.
+ * Flag to mark SMP init by BSP complete
  */
-extern char_intstack[];/* bottom */
-extern char_eintstack[];   /* top */
+int bspdone;
+
+extern void *apboot, *apbootend;
+extern volatile ApicLocalUnit* lapic;

 /*
  * Multiprocessor i386/i486 systems use a separate copy of the
@@ -77,7 +103,7 @@ extern char  _eintstack[];   /* top */
  */

 /*
- * Allocated descriptor tables.
+ * Descriptor tables.
  */
 struct mp_desc_table   *mp_desc_table[NCPUS] = { 0 };

@@ -102,12 +128,13 @@ extern struct real_descriptor ldt[LDTSZ];
  * Allocate and initialize the per-processor descriptor tables.
  */

-struct mp_desc_table *
+int
 mp_desc_init(int mycpu)
 {
struct mp_desc_table *mpt;
+   vm_offset_t mem;

-   if (mycpu == master_cpu) {
+   if (mycpu == 0) {
/*
 * Master CPU uses the tables built at boot time.
 * Just set the TSS and GDT pointers.
@@ -118,61 +145,28 @@ mp_desc_init(int mycpu)
}
else {
/*
-* Other CPUs allocate the table from the bottom of
-* the interrupt stack.
+* Allocate tables for other CPUs
 */
-   mpt = (struct mp_desc_table *) interrupt_stack[mycpu];
+   if (!init_alloc_aligned(sizeof(struct mp_desc_table), &mem))
+   panic("not enough memory for descriptor tables");
+   mpt = (struct mp_desc_table *)phystokv(mem);

mp_desc_table[mycpu] = mpt;
mp_ktss[mycpu] = &mpt->ktss;
mp_gdt[mycpu] = mpt->gdt;

/*
-* Copy the tables
+* Zero the tables
 */
-   memcpy(mpt->idt,
- idt,
- sizeof(idt));
-   memcpy(mpt->gdt,
- gdt,
- sizeof(gdt));
-   memcpy(mpt->ldt,
- ldt,
- sizeof(ldt));
-   memset(&mpt->ktss, 0,
- sizeof(struct task_tss));
+   memset(mpt->idt, 0, sizeof(idt));
+   memset(mpt->gdt, 0, sizeof(gdt));
+   memset(mpt->ldt, 0, sizeof(ldt));
+   memset(&mpt->ktss, 0, sizeof(struct task_tss));

-   /*
-* Fix up the entries in the GDT to point to
-* this LDT and this TSS.
-*/
-#ifdef MACH_RING1
-   panic("TODO %s:%d\n",__FILE__,__LINE__);
-#else  /* MACH_RING1 */
-   _fill_gdt_sys_descriptor(mpt->gdt, KERNEL_LDT,
-   (unsigned)&mpt->ldt,
-   LDTSZ * sizeof(struct real_descriptor) - 1,
-   ACC_P|ACC_PL_K|ACC_LDT, 0);
-   _fill_gdt_sys_descriptor(mpt->gdt, KERNEL_TSS,
-   (unsigned)&mpt->ktss,
-   sizeof(struct task_tss) - 1,
-   ACC_P|ACC_PL_K|ACC_TSS, 0);
-
-   mpt->ktss.tss.ss0 = KERNEL_DS;
-   mpt->ktss.tss.io_bit_map_offset = IOPB_INVAL;
-  

Mixing 32 and 64 bit userspace tasks (was: Re: [PATCH gnumach] Define rpc_vm_size_array_t and rpc_vm_offset_array_t)

2023-02-03 Thread Luca Dariz

Il 01/02/23 10:36, Sergey Bugaev ha scritto:

Note that another way to handle the size conversion between rpc_* and
regular types would be to add some new VM types to
include/mach/message.h; in this case, the shrink/expand would happen in
copyinmsg()/copyoutmsg() instead of the mig-generated code (as for mach
ports), but this approach would require to plan for a staged
introduction of this change.


Actually, yes, that's what I've been thinking about. Currently
vm_size_t & friends are conditionally (but statically) defined to
either MACH_MSG_TYPE_INTEGER_32 or MACH_MSG_TYPE_INTEGER_64. But what
if we also had MACH_MSG_TYPE_INTEGER_PTRSIZE (name TBD), which would
be equivalent to MACH_MSG_TYPE_INTEGER_{32,64} for {32,64}-bit tasks;
but the kernel would know about this and change its size accordingly
when transferring messages between 64- and 32-bit tasks. A value sent
as MACH_MSG_TYPE_INTEGER_32 is always received as
MACH_MSG_TYPE_INTEGER_32, no matter if the intent was to send a
pointer-sized value, whereas a 32-bit value sent by a 32-bit task as
MACH_MSG_TYPE_INTEGER_PTRSIZE would get received as a 64-bit value,
still MACH_MSG_TYPE_INTEGER_PTRSIZE, by a 64-bit task.


While this shouldn't be a problem for normal data transfers, where the 
kernel already copies the data from one task to the other adjusting the 
size of vm fields, I wonder if there are cases where the virtual address 
is not supposed to be translated between tasks, e.g. if we really need 
to send a task-specific virtual address. For example, are there cases 
where a task allocates memory on behalf of another task? (except for the 
exec task)




This would allow 32- and 64- bit tasks (including the kernel task) to
communicate transparently, without requiring separate rpc_* versions
of all the pointer-sized types. Possibly. Maybe. Uness there are a lot
of subtler details to this, which there of course are.
I think a more difficult case is the rpc_time_value_t type, but this 
case could be solved by adding yet another MACH_MSG_TYPE_TIME_VALUE value.


However the problem exists for any struct type (which are just int[] of 
fixed size in mig), because there could be differences due to both 
alignment and pointer-type fields. So either the kernel knows all the 
data structures exchanged by user-space tasks, or the task needs to 
handle a message differently depending if the sender is a 32 or 64 bit 
task. Maybe this could be handled by the mig stubs, I'm not sure. The 
information about the sending task could be encoded in one of the unused 
bits of the msg header.


Something similar to rpc_ types would still be needed for regular 
syscalls, but then they could be renamed to vm_offset_32_t and similar, 
since syscalls would have different entry points.



But I'm sure it has been a conscious decision to go with the current
design and not this way?


For the parts that I wrote, the choice was based on some information 
that I found in the wiki, on irc and to some extent it seemed faster to 
implement. Considering the above issue with struct, I'm not sure how 
much a new vm type would simplify message handling.



I'm also not arguing that mixing 32- and 64-bit tasks is worth
supporting. This was a hard requirement for OS X, since they had to be
able to run existing proprietary binaries unmodified. We build
everything from source, so just having all of the userland be 64-bit
(and fixing any issues we find on the way) sounds very viable. Using
32-bit win32 software via Wine has been the single reason to run
32-bit processes on my GNU/Linux system, but apparently that's now
changing too (WoW64). And I don't know how relevant using Wine on the
Hurd is anyway.


Maybe one advantage could be a reduced memory usage for 32-bit subhurds, 
if we want also 64-bit subhurds on the same machine.



Luca




Re: [PATCH v2 2/3 gnumach] linux: Keep existing timer interrupt handler for APIC

2023-02-03 Thread Samuel Thibault
I applied it but moved the #ifndef APIC to inside restore_IRQ, to
restore raising spl back to high, as the rest of the initialization code
expects.

Damien Zammit, le ven. 03 févr. 2023 10:01:55 +, a ecrit:
> ---
>  linux/dev/arch/i386/kernel/irq.c | 2 +-
>  linux/dev/init/main.c| 2 ++
>  2 files changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/linux/dev/arch/i386/kernel/irq.c 
> b/linux/dev/arch/i386/kernel/irq.c
> index 67feea84..b48d1312 100644
> --- a/linux/dev/arch/i386/kernel/irq.c
> +++ b/linux/dev/arch/i386/kernel/irq.c
> @@ -721,13 +721,13 @@ init_IRQ (void)
>outb_p (PIT_C0 | PIT_SQUAREMODE | PIT_READMODE, PITCTL_PORT);
>outb_p (latch & 0xff, PITCTR0_PORT);
>outb (latch >> 8, PITCTR0_PORT);
> -#endif
> 
>/*
> * Install our clock interrupt handler.
> */
>old_clock_handler = ivect[0];
>ivect[0] = linux_timer_intr;
> +#endif
> 
>reserve_mach_irqs ();
> 
> diff --git a/linux/dev/init/main.c b/linux/dev/init/main.c
> index 6d853957..207724f3 100644
> --- a/linux/dev/init/main.c
> +++ b/linux/dev/init/main.c
> @@ -160,7 +160,9 @@ linux_init (void)
>pcmcia_init ();
>  #endif
> 
> +#ifndef APIC
>restore_IRQ ();
> +#endif
> 
>linux_auto_config = 0;
>  }
> --
> 2.34.1



Re: [PATCH v2 1/3 gnumach] pmap: Refactor temporary mapping functions

2023-02-03 Thread Samuel Thibault
Applied, thanks!

Damien Zammit, le ven. 03 févr. 2023 10:01:49 +, a ecrit:
> ---
>  i386/i386at/model_dep.c | 73 +---
>  i386/intel/pmap.c   | 93 +
>  i386/intel/pmap.h   |  6 +++
>  3 files changed, 101 insertions(+), 71 deletions(-)
> 
> diff --git a/i386/i386at/model_dep.c b/i386/i386at/model_dep.c
> index fe11bffc..98408c06 100644
> --- a/i386/i386at/model_dep.c
> +++ b/i386/i386at/model_dep.c
> @@ -359,10 +359,6 @@ register_boot_data(const struct multiboot_raw_info *mbi)
>  static void
>  i386at_init(void)
>  {
> - /* XXX move to intel/pmap.h */
> - extern pt_entry_t *kernel_page_dir;
> - int i;
> -
>   /*
>* Initialize the PIC prior to any possible call to an spl.
>*/
> @@ -448,47 +444,8 @@ i386at_init(void)
>*/
>   biosmem_setup();
> 
> - /*
> -  * We'll have to temporarily install a direct mapping
> -  * between physical memory and low linear memory,
> -  * until we start using our new kernel segment descriptors.
> -  */
> -#if INIT_VM_MIN_KERNEL_ADDRESS != LINEAR_MIN_KERNEL_ADDRESS
> - vm_offset_t delta = INIT_VM_MIN_KERNEL_ADDRESS - 
> LINEAR_MIN_KERNEL_ADDRESS;
> - if ((vm_offset_t)(-delta) < delta)
> - delta = (vm_offset_t)(-delta);
> - int nb_direct = delta >> PDESHIFT;
> - for (i = 0; i < nb_direct; i++)
> - kernel_page_dir[lin2pdenum_cont(INIT_VM_MIN_KERNEL_ADDRESS) + 
> i] =
> - 
> kernel_page_dir[lin2pdenum_cont(LINEAR_MIN_KERNEL_ADDRESS) + i];
> -#endif
> - /* We need BIOS memory mapped at 0xc & co for BIOS accesses */
> -#if VM_MIN_KERNEL_ADDRESS != 0
> - kernel_page_dir[lin2pdenum_cont(LINEAR_MIN_KERNEL_ADDRESS - 
> VM_MIN_KERNEL_ADDRESS)] =
> - kernel_page_dir[lin2pdenum_cont(LINEAR_MIN_KERNEL_ADDRESS)];
> -#endif
> + pmap_make_temporary_mapping();
> 
> -#ifdef   MACH_PV_PAGETABLES
> - for (i = 0; i < PDPNUM; i++)
> - pmap_set_page_readonly_init((void*) kernel_page_dir + i * 
> INTEL_PGBYTES);
> -#if PAE
> - pmap_set_page_readonly_init(kernel_pmap->pdpbase);
> -#endif   /* PAE */
> -#endif   /* MACH_PV_PAGETABLES */
> -#if PAE
> -#ifdef __x86_64__
> - set_cr3((unsigned long)_kvtophys(kernel_pmap->l4base));
> -#else
> - set_cr3((unsigned long)_kvtophys(kernel_pmap->pdpbase));
> -#endif
> -#ifndef  MACH_HYP
> - if (!CPU_HAS_FEATURE(CPU_FEATURE_PAE))
> - panic("CPU doesn't have support for PAE.");
> - set_cr4(get_cr4() | CR4_PAE);
> -#endif   /* MACH_HYP */
> -#else
> - set_cr3((unsigned long)_kvtophys(kernel_page_dir));
> -#endif   /* PAE */
>  #ifndef  MACH_HYP
>   /* Turn paging on.
>* Also set the WP bit so that on 486 or better processors
> @@ -520,33 +477,7 @@ i386at_init(void)
>   mp_desc_init(0);
>  #endif // NCPUS
> 
> -#if INIT_VM_MIN_KERNEL_ADDRESS != LINEAR_MIN_KERNEL_ADDRESS
> - /* Get rid of the temporary direct mapping and flush it out of the TLB. 
>  */
> - for (i = 0 ; i < nb_direct; i++) {
> -#ifdef   MACH_XEN
> -#ifdef   MACH_PSEUDO_PHYS
> - if 
> (!hyp_mmu_update_pte(kv_to_ma(&kernel_page_dir[lin2pdenum_cont(VM_MIN_KERNEL_ADDRESS)
>  + i]), 0))
> -#else/* MACH_PSEUDO_PHYS */
> - if (hyp_do_update_va_mapping(VM_MIN_KERNEL_ADDRESS + i * 
> INTEL_PGBYTES, 0, UVMF_INVLPG | UVMF_ALL))
> -#endif   /* MACH_PSEUDO_PHYS */
> - printf("couldn't unmap frame %d\n", i);
> -#else/* MACH_XEN */
> - kernel_page_dir[lin2pdenum_cont(INIT_VM_MIN_KERNEL_ADDRESS) + 
> i] = 0;
> -#endif   /* MACH_XEN */
> - }
> -#endif
> - /* Keep BIOS memory mapped */
> -#if VM_MIN_KERNEL_ADDRESS != 0
> - kernel_page_dir[lin2pdenum_cont(LINEAR_MIN_KERNEL_ADDRESS - 
> VM_MIN_KERNEL_ADDRESS)] =
> - kernel_page_dir[lin2pdenum_cont(LINEAR_MIN_KERNEL_ADDRESS)];
> -#endif
> -
> - /* Not used after boot, better give it back.  */
> -#ifdef   MACH_XEN
> - hyp_free_page(0, (void*) VM_MIN_KERNEL_ADDRESS);
> -#endif   /* MACH_XEN */
> -
> - flush_tlb();
> + pmap_remove_temporary_mapping();
> 
>  #ifdef   MACH_XEN
>   hyp_p2m_init();
> diff --git a/i386/intel/pmap.c b/i386/intel/pmap.c
> index 0505cfa2..3c57d732 100644
> --- a/i386/intel/pmap.c
> +++ b/i386/intel/pmap.c
> @@ -3009,3 +3009,96 @@ pmap_unmap_page_zero (void)
>  #endif   /* MACH_PV_PAGETABLES */
>  }
>  #endif /* __i386__ */
> +
> +void
> +pmap_make_temporary_mapping(void)
> +{
> + int i;
> +
> + /*
> +  * We'll have to temporarily install a direct mapping
> +  * between physical memory and low linear memory,
> +  * until we start using our new kernel segment descriptors.
> +  */
> +#if INIT_VM_MIN_KERNEL_ADDRESS != LINEAR_MIN_KERNEL_ADDRESS
> + vm_offset_t delta = INIT_VM_MIN_KERNEL_ADDRESS - 
> LINEAR_MIN_KERNEL_ADDRESS;
> + if ((vm_offset_t)(-del

Re: [PATCHv2] libstdc++: Mark pieces of gnu-linux/os_support.h linux-specific

2023-02-03 Thread Jonathan Wakely
On Fri, 7 Oct 2022 at 21:45, Samuel Thibault wrote:
>
> This is notably needed because in glibc 2.34, the move of pthread functions
> into libc.so happened for Linux only, not GNU/Hurd.
>
> The pthread_self() function can also always be used fine as it is on
> GNU/Hurd.

Sorry for the delay, I'm going to push this to trunk today.


>
> libstdc++-v3/ChangeLog:
>
> * config/os/gnu-linux/os_defines.h [!__linux__]
>   (_GLIBCXX_NATIVE_THREAD_ID, _GLIBCXX_GTHREAD_USE_WEAK): Do not 
> define.
>
> diff --git a/libstdc++-v3/config/os/gnu-linux/os_defines.h 
> b/libstdc++-v3/config/os/gnu-linux/os_defines.h
> index c0caa21a013..4de93d752e1 100644
> --- a/libstdc++-v3/config/os/gnu-linux/os_defines.h
> +++ b/libstdc++-v3/config/os/gnu-linux/os_defines.h
> @@ -49,22 +49,24 @@
>  // version dynamically in case it has changed since libstdc++ was configured.
>  #define _GLIBCXX_NO_OBSOLETE_ISINF_ISNAN_DYNAMIC __GLIBC_PREREQ(2,23)
>
> -#if __GLIBC_PREREQ(2, 27)
> -// Since glibc 2.27 pthread_self() is usable without linking to libpthread.
> -# define _GLIBCXX_NATIVE_THREAD_ID pthread_self()
> -#else
> +#ifdef __linux__
> +# if __GLIBC_PREREQ(2, 27)
> +// Since glibc 2.27 Linux' pthread_self() is usable without linking to 
> libpthread.
> +#  define _GLIBCXX_NATIVE_THREAD_ID pthread_self()
> +# else
>  // Before then it was in libc.so.6 but not libc.a, and always returns 0,
>  // which breaks the invariant this_thread::get_id() != thread::id{}.
>  // So only use it if we know the libpthread version is available.
>  // Otherwise use (__gthread_t)1 as the ID of the main (and only) thread.
> -# define _GLIBCXX_NATIVE_THREAD_ID \
> -  (__gthread_active_p() ? __gthread_self() : (__gthread_t)1)
> -#endif
> +#  define _GLIBCXX_NATIVE_THREAD_ID \
> +   (__gthread_active_p() ? __gthread_self() : (__gthread_t)1)
> +# endif
>
> -#if __GLIBC_PREREQ(2, 34)
> -// Since glibc 2.34 all pthreads functions are usable without linking to
> +# if __GLIBC_PREREQ(2, 34)
> +// Since glibc 2.34 all Linux pthreads functions are usable without linking 
> to
>  // libpthread.
> -# define _GLIBCXX_GTHREAD_USE_WEAK 0
> +#  define _GLIBCXX_GTHREAD_USE_WEAK 0
> +# endif
>  #endif
>
>  #endif
>




Re: [PATCH v2 3/3 gnumach] i386: Refactor int stacks to be per cpu for SMP

2023-02-03 Thread Almudena Garcia
+#ifndef MACH_HYP
+/* Turn paging on.
+ * TODO: Why does setting the WP bit here cause a crash?
+ */
+set_cr0(get_cr0() | CR0_PG /* | CR0_WP */);
+set_cr0(get_cr0() & ~(CR0_CD | CR0_NW));
+if (CPU_HAS_FEATURE(CPU_FEATURE_PGE))
+set_cr4(get_cr4() | CR4_PGE);

Again, you need some checks more. And, why not separate this in a function?
Check my original function

https://github.com/AlmuHS/GNUMach_SMP/blob/a31999c018c22d23402d3e02b5dfd595d4a29230/i386/i386/mp_desc.c#L365-L392

I copy its code here, if you don't want to follow the link

void paging_setup(){

#if PAE
set_cr3(pdpbase_addr);
#ifndef MACH_HYP
if (!CPU_HAS_FEATURE(CPU_FEATURE_PAE))
set_cr4(get_cr4() | CR4_PAE);
#endif  /* MACH_HYP */
#else
set_cr3(kernel_page_dir_addr);
#endif  /* PAE */
#ifndef MACH_HYP
/* Turn paging on.
 * Also set the WP bit so that on 486 or better processors
 * page-level write protection works in kernel mode.
 */
set_cr0(get_cr0() | CR0_PG | CR0_WP);
set_cr0(get_cr0() & ~(CR0_CD | CR0_NW));

if (CPU_HAS_FEATURE(CPU_FEATURE_PGE))
set_cr4(get_cr4() | CR4_PGE);

#endif  /* MACH_HYP */

flush_instr_queue();
flush_tlb();

}


El vie, 3 feb 2023 a las 11:03, Damien Zammit ()
escribió:

> This also serialises the AP bringup, so paging can be enabled per cpu
> one by one.
>
> Also-by: Almudena Garcia 
> ---
>  i386/i386/mp_desc.c | 226 
>  i386/i386/mp_desc.h |   7 +-
>  i386/i386at/boothdr.S   |  18 +++-
>  i386/i386at/ioapic.c|   5 +-
>  i386/i386at/model_dep.c |  33 +++---
>  5 files changed, 197 insertions(+), 92 deletions(-)
>
> diff --git a/i386/i386/mp_desc.c b/i386/i386/mp_desc.c
> index bcf2fbe7..0db29291 100644
> --- a/i386/i386/mp_desc.c
> +++ b/i386/i386/mp_desc.c
> @@ -24,25 +24,36 @@
>   * the rights to redistribute these changes.
>   */
>
> -#ifNCPUS > 1
> -
> -#include 
> -
>  #include 
>  #include 
>  #include 
> +#include 
> +#include 
> +#include 
>  #include 
>  #include 
>  #include 
>
>  #include 
>  #include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
>
> +#include 
> +#include 
> +
>  /*
>   * The i386 needs an interrupt stack to keep the PCB stack from being
>   * overrun by interrupts.  All interrupt stacks MUST lie at lower
> addresses
> @@ -52,20 +63,35 @@
>  /*
>   * Addresses of bottom and top of interrupt stacks.
>   */
> -vm_offset_tinterrupt_stack[NCPUS];
>  vm_offset_tint_stack_top[NCPUS];
>  vm_offset_tint_stack_base[NCPUS];
>
> -/*
> - * Barrier address.
> - */
> -vm_offset_tint_stack_high;
> +/* Interrupt stack allocation */
> +uint8_t solid_intstack[NCPUS*INTSTACK_SIZE]
> __aligned(NCPUS*INTSTACK_SIZE);
> +
> +void
> +interrupt_stack_alloc(void)
> +{
> +   int i;
> +
> +   /*
> +* Set up pointers to the top of the interrupt stack.
> +*/
>
> +   for (i = 0; i < NCPUS; i++) {
> +   int_stack_base[i] = (vm_offset_t) &solid_intstack[i *
> INTSTACK_SIZE];
> +   int_stack_top[i] = (vm_offset_t) &solid_intstack[(i + 1) *
> INTSTACK_SIZE] - 4;
> +   }
> +}
> +
> +#ifNCPUS > 1
>  /*
> - * First cpu`s interrupt stack.
> + * Flag to mark SMP init by BSP complete
>   */
> -extern char_intstack[];/* bottom */
> -extern char_eintstack[];   /* top */
> +int bspdone;
> +
> +extern void *apboot, *apbootend;
> +extern volatile ApicLocalUnit* lapic;
>
>  /*
>   * Multiprocessor i386/i486 systems use a separate copy of the
> @@ -77,7 +103,7 @@ extern char  _eintstack[];   /* top */
>   */
>
>  /*
> - * Allocated descriptor tables.
> + * Descriptor tables.
>   */
>  struct mp_desc_table   *mp_desc_table[NCPUS] = { 0 };
>
> @@ -102,12 +128,13 @@ extern struct real_descriptor ldt[LDTSZ];
>   * Allocate and initialize the per-processor descriptor tables.
>   */
>
> -struct mp_desc_table *
> +int
>  mp_desc_init(int mycpu)
>  {
> struct mp_desc_table *mpt;
> +   vm_offset_t mem;
>
> -   if (mycpu == master_cpu) {
> +   if (mycpu == 0) {
> /*
>  * Master CPU uses the tables built at boot time.
>  * Just set the TSS and GDT pointers.
> @@ -118,61 +145,28 @@ mp_desc_init(int mycpu)
> }
> else {
> /*
> -* Other CPUs allocate the table from the bottom of
> -* the interrupt stack.
> +* Allocate tables for other CPUs
>  */
> -   mpt = (struct mp_desc_table *) interrupt_stack[mycpu];
> +   if (!init_alloc_aligned(sizeof(struct mp_desc_table),
> &mem))
> +   panic("not enough memory for descriptor tables");
> +   mpt = (struct mp_desc_table *)phystokv(mem);
>
> mp_desc_table[mycpu] = mpt;
> m

[PATCH v2 3/3 gnumach] i386: Refactor int stacks to be per cpu for SMP

2023-02-03 Thread Damien Zammit
This also serialises the AP bringup, so paging can be enabled per cpu
one by one.

Also-by: Almudena Garcia 
---
 i386/i386/mp_desc.c | 226 
 i386/i386/mp_desc.h |   7 +-
 i386/i386at/boothdr.S   |  18 +++-
 i386/i386at/ioapic.c|   5 +-
 i386/i386at/model_dep.c |  33 +++---
 5 files changed, 197 insertions(+), 92 deletions(-)

diff --git a/i386/i386/mp_desc.c b/i386/i386/mp_desc.c
index bcf2fbe7..0db29291 100644
--- a/i386/i386/mp_desc.c
+++ b/i386/i386/mp_desc.c
@@ -24,25 +24,36 @@
  * the rights to redistribute these changes.
  */

-#ifNCPUS > 1
-
-#include 
-
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 #include 
 #include 
 #include 

 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 

+#include 
+#include 
+
 /*
  * The i386 needs an interrupt stack to keep the PCB stack from being
  * overrun by interrupts.  All interrupt stacks MUST lie at lower addresses
@@ -52,20 +63,35 @@
 /*
  * Addresses of bottom and top of interrupt stacks.
  */
-vm_offset_tinterrupt_stack[NCPUS];
 vm_offset_tint_stack_top[NCPUS];
 vm_offset_tint_stack_base[NCPUS];

-/*
- * Barrier address.
- */
-vm_offset_tint_stack_high;
+/* Interrupt stack allocation */
+uint8_t solid_intstack[NCPUS*INTSTACK_SIZE] __aligned(NCPUS*INTSTACK_SIZE);
+
+void
+interrupt_stack_alloc(void)
+{
+   int i;
+
+   /*
+* Set up pointers to the top of the interrupt stack.
+*/

+   for (i = 0; i < NCPUS; i++) {
+   int_stack_base[i] = (vm_offset_t) &solid_intstack[i * 
INTSTACK_SIZE];
+   int_stack_top[i] = (vm_offset_t) &solid_intstack[(i + 1) * 
INTSTACK_SIZE] - 4;
+   }
+}
+
+#ifNCPUS > 1
 /*
- * First cpu`s interrupt stack.
+ * Flag to mark SMP init by BSP complete
  */
-extern char_intstack[];/* bottom */
-extern char_eintstack[];   /* top */
+int bspdone;
+
+extern void *apboot, *apbootend;
+extern volatile ApicLocalUnit* lapic;

 /*
  * Multiprocessor i386/i486 systems use a separate copy of the
@@ -77,7 +103,7 @@ extern char  _eintstack[];   /* top */
  */

 /*
- * Allocated descriptor tables.
+ * Descriptor tables.
  */
 struct mp_desc_table   *mp_desc_table[NCPUS] = { 0 };

@@ -102,12 +128,13 @@ extern struct real_descriptor ldt[LDTSZ];
  * Allocate and initialize the per-processor descriptor tables.
  */

-struct mp_desc_table *
+int
 mp_desc_init(int mycpu)
 {
struct mp_desc_table *mpt;
+   vm_offset_t mem;

-   if (mycpu == master_cpu) {
+   if (mycpu == 0) {
/*
 * Master CPU uses the tables built at boot time.
 * Just set the TSS and GDT pointers.
@@ -118,61 +145,28 @@ mp_desc_init(int mycpu)
}
else {
/*
-* Other CPUs allocate the table from the bottom of
-* the interrupt stack.
+* Allocate tables for other CPUs
 */
-   mpt = (struct mp_desc_table *) interrupt_stack[mycpu];
+   if (!init_alloc_aligned(sizeof(struct mp_desc_table), &mem))
+   panic("not enough memory for descriptor tables");
+   mpt = (struct mp_desc_table *)phystokv(mem);

mp_desc_table[mycpu] = mpt;
mp_ktss[mycpu] = &mpt->ktss;
mp_gdt[mycpu] = mpt->gdt;

/*
-* Copy the tables
+* Zero the tables
 */
-   memcpy(mpt->idt,
- idt,
- sizeof(idt));
-   memcpy(mpt->gdt,
- gdt,
- sizeof(gdt));
-   memcpy(mpt->ldt,
- ldt,
- sizeof(ldt));
-   memset(&mpt->ktss, 0,
- sizeof(struct task_tss));
+   memset(mpt->idt, 0, sizeof(idt));
+   memset(mpt->gdt, 0, sizeof(gdt));
+   memset(mpt->ldt, 0, sizeof(ldt));
+   memset(&mpt->ktss, 0, sizeof(struct task_tss));

-   /*
-* Fix up the entries in the GDT to point to
-* this LDT and this TSS.
-*/
-#ifdef MACH_RING1
-   panic("TODO %s:%d\n",__FILE__,__LINE__);
-#else  /* MACH_RING1 */
-   _fill_gdt_sys_descriptor(mpt->gdt, KERNEL_LDT,
-   (unsigned)&mpt->ldt,
-   LDTSZ * sizeof(struct real_descriptor) - 1,
-   ACC_P|ACC_PL_K|ACC_LDT, 0);
-   _fill_gdt_sys_descriptor(mpt->gdt, KERNEL_TSS,
-   (unsigned)&mpt->ktss,
-   sizeof(struct task_tss) - 1,
-   ACC_P|ACC_PL_K|ACC_TSS, 0);
-
-   mpt->ktss.tss.ss0 = KERNEL_DS;
-   mpt->ktss.tss.io_bit_map_offset = IOPB_INVAL;
-  

[PATCH v2 2/3 gnumach] linux: Keep existing timer interrupt handler for APIC

2023-02-03 Thread Damien Zammit
---
 linux/dev/arch/i386/kernel/irq.c | 2 +-
 linux/dev/init/main.c| 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/linux/dev/arch/i386/kernel/irq.c b/linux/dev/arch/i386/kernel/irq.c
index 67feea84..b48d1312 100644
--- a/linux/dev/arch/i386/kernel/irq.c
+++ b/linux/dev/arch/i386/kernel/irq.c
@@ -721,13 +721,13 @@ init_IRQ (void)
   outb_p (PIT_C0 | PIT_SQUAREMODE | PIT_READMODE, PITCTL_PORT);
   outb_p (latch & 0xff, PITCTR0_PORT);
   outb (latch >> 8, PITCTR0_PORT);
-#endif

   /*
* Install our clock interrupt handler.
*/
   old_clock_handler = ivect[0];
   ivect[0] = linux_timer_intr;
+#endif

   reserve_mach_irqs ();

diff --git a/linux/dev/init/main.c b/linux/dev/init/main.c
index 6d853957..207724f3 100644
--- a/linux/dev/init/main.c
+++ b/linux/dev/init/main.c
@@ -160,7 +160,9 @@ linux_init (void)
   pcmcia_init ();
 #endif

+#ifndef APIC
   restore_IRQ ();
+#endif

   linux_auto_config = 0;
 }
--
2.34.1





[PATCH v2 1/3 gnumach] pmap: Refactor temporary mapping functions

2023-02-03 Thread Damien Zammit
---
 i386/i386at/model_dep.c | 73 +---
 i386/intel/pmap.c   | 93 +
 i386/intel/pmap.h   |  6 +++
 3 files changed, 101 insertions(+), 71 deletions(-)

diff --git a/i386/i386at/model_dep.c b/i386/i386at/model_dep.c
index fe11bffc..98408c06 100644
--- a/i386/i386at/model_dep.c
+++ b/i386/i386at/model_dep.c
@@ -359,10 +359,6 @@ register_boot_data(const struct multiboot_raw_info *mbi)
 static void
 i386at_init(void)
 {
-   /* XXX move to intel/pmap.h */
-   extern pt_entry_t *kernel_page_dir;
-   int i;
-
/*
 * Initialize the PIC prior to any possible call to an spl.
 */
@@ -448,47 +444,8 @@ i386at_init(void)
 */
biosmem_setup();

-   /*
-* We'll have to temporarily install a direct mapping
-* between physical memory and low linear memory,
-* until we start using our new kernel segment descriptors.
-*/
-#if INIT_VM_MIN_KERNEL_ADDRESS != LINEAR_MIN_KERNEL_ADDRESS
-   vm_offset_t delta = INIT_VM_MIN_KERNEL_ADDRESS - 
LINEAR_MIN_KERNEL_ADDRESS;
-   if ((vm_offset_t)(-delta) < delta)
-   delta = (vm_offset_t)(-delta);
-   int nb_direct = delta >> PDESHIFT;
-   for (i = 0; i < nb_direct; i++)
-   kernel_page_dir[lin2pdenum_cont(INIT_VM_MIN_KERNEL_ADDRESS) + 
i] =
-   
kernel_page_dir[lin2pdenum_cont(LINEAR_MIN_KERNEL_ADDRESS) + i];
-#endif
-   /* We need BIOS memory mapped at 0xc & co for BIOS accesses */
-#if VM_MIN_KERNEL_ADDRESS != 0
-   kernel_page_dir[lin2pdenum_cont(LINEAR_MIN_KERNEL_ADDRESS - 
VM_MIN_KERNEL_ADDRESS)] =
-   kernel_page_dir[lin2pdenum_cont(LINEAR_MIN_KERNEL_ADDRESS)];
-#endif
+   pmap_make_temporary_mapping();

-#ifdef MACH_PV_PAGETABLES
-   for (i = 0; i < PDPNUM; i++)
-   pmap_set_page_readonly_init((void*) kernel_page_dir + i * 
INTEL_PGBYTES);
-#if PAE
-   pmap_set_page_readonly_init(kernel_pmap->pdpbase);
-#endif /* PAE */
-#endif /* MACH_PV_PAGETABLES */
-#if PAE
-#ifdef __x86_64__
-   set_cr3((unsigned long)_kvtophys(kernel_pmap->l4base));
-#else
-   set_cr3((unsigned long)_kvtophys(kernel_pmap->pdpbase));
-#endif
-#ifndefMACH_HYP
-   if (!CPU_HAS_FEATURE(CPU_FEATURE_PAE))
-   panic("CPU doesn't have support for PAE.");
-   set_cr4(get_cr4() | CR4_PAE);
-#endif /* MACH_HYP */
-#else
-   set_cr3((unsigned long)_kvtophys(kernel_page_dir));
-#endif /* PAE */
 #ifndefMACH_HYP
/* Turn paging on.
 * Also set the WP bit so that on 486 or better processors
@@ -520,33 +477,7 @@ i386at_init(void)
mp_desc_init(0);
 #endif // NCPUS

-#if INIT_VM_MIN_KERNEL_ADDRESS != LINEAR_MIN_KERNEL_ADDRESS
-   /* Get rid of the temporary direct mapping and flush it out of the TLB. 
 */
-   for (i = 0 ; i < nb_direct; i++) {
-#ifdef MACH_XEN
-#ifdef MACH_PSEUDO_PHYS
-   if 
(!hyp_mmu_update_pte(kv_to_ma(&kernel_page_dir[lin2pdenum_cont(VM_MIN_KERNEL_ADDRESS)
 + i]), 0))
-#else  /* MACH_PSEUDO_PHYS */
-   if (hyp_do_update_va_mapping(VM_MIN_KERNEL_ADDRESS + i * 
INTEL_PGBYTES, 0, UVMF_INVLPG | UVMF_ALL))
-#endif /* MACH_PSEUDO_PHYS */
-   printf("couldn't unmap frame %d\n", i);
-#else  /* MACH_XEN */
-   kernel_page_dir[lin2pdenum_cont(INIT_VM_MIN_KERNEL_ADDRESS) + 
i] = 0;
-#endif /* MACH_XEN */
-   }
-#endif
-   /* Keep BIOS memory mapped */
-#if VM_MIN_KERNEL_ADDRESS != 0
-   kernel_page_dir[lin2pdenum_cont(LINEAR_MIN_KERNEL_ADDRESS - 
VM_MIN_KERNEL_ADDRESS)] =
-   kernel_page_dir[lin2pdenum_cont(LINEAR_MIN_KERNEL_ADDRESS)];
-#endif
-
-   /* Not used after boot, better give it back.  */
-#ifdef MACH_XEN
-   hyp_free_page(0, (void*) VM_MIN_KERNEL_ADDRESS);
-#endif /* MACH_XEN */
-
-   flush_tlb();
+   pmap_remove_temporary_mapping();

 #ifdef MACH_XEN
hyp_p2m_init();
diff --git a/i386/intel/pmap.c b/i386/intel/pmap.c
index 0505cfa2..3c57d732 100644
--- a/i386/intel/pmap.c
+++ b/i386/intel/pmap.c
@@ -3009,3 +3009,96 @@ pmap_unmap_page_zero (void)
 #endif /* MACH_PV_PAGETABLES */
 }
 #endif /* __i386__ */
+
+void
+pmap_make_temporary_mapping(void)
+{
+   int i;
+
+   /*
+* We'll have to temporarily install a direct mapping
+* between physical memory and low linear memory,
+* until we start using our new kernel segment descriptors.
+*/
+#if INIT_VM_MIN_KERNEL_ADDRESS != LINEAR_MIN_KERNEL_ADDRESS
+   vm_offset_t delta = INIT_VM_MIN_KERNEL_ADDRESS - 
LINEAR_MIN_KERNEL_ADDRESS;
+   if ((vm_offset_t)(-delta) < delta)
+   delta = (vm_offset_t)(-delta);
+   int nb_direct = delta >> PDESHIFT;
+   for (i = 0; i < nb_direct; i++)
+   kernel_page_dir[lin2pdenum_cont(INIT_VM_MIN_KERNEL_ADDRESS) + 
i] =
+   
kernel_page_dir[lin2pdenum_cont(LINEAR_MIN_KERNEL_ADDRESS) + i];
+#endif
+