[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Lost] [Patch 1/3] kernel2: RPC



Am Donnerstag, 31. Juli 2008 18.24:09 schrieb Kevin Wolf:
> + kernel2: mmc_automap_user() mappt virtuell zusammenhängenden Speicher aus
> einem anderen Kontext (z.B. den Stack eines Tasks, der per RPC aufgerufen
> werden soll)
> + kernel2: syscall_fastrpc
> + kernel2: syscall_fastrpc_ret
>
> Dieser Patch ist irgendwas zwischen ziemlich und extrem kaputt. Ich würde
> es trotzdem vorziehen, ihn erstmal so einzuchecken und die Details später
> zu fixen.

> Index: trunk/src/kernel2/src/syscalls/rpc.c
> ===================================================================
> --- trunk.orig/src/kernel2/src/syscalls/rpc.c
> +++ trunk/src/kernel2/src/syscalls/rpc.c
> ....
> +    // Der aufgerufene Task darf wieder laufen
> +    if (callee->status == PM_STATUS_WAIT_FOR_RPC) {
> +        callee->status = PM_STATUS_READY;
> +    }
> +
Muss da das if wirklich hin? Wenn ja, deckt es auch alle Fälle? Irgendwie bin 
ich da grad etwas unsicher.

> +/**
> + * Wird nach der Ausführung eines RPC-Handlers aufgerufen.
> + *
> + * Nach der Rückkehr vom RPC-Handler wird der neueste Zustand vom
> RPC-Stack + * gepopt und zur Wiederherstellung des ursprünglichen
> Prozessorzustands + * benutzt.
> + *
> + * Dies betrifft eip, esp, eax und eflags. Die übrigen Register sind vom
> + * RPC-Handler zu sicher und vor dem Aufruf von SYSCALL_FASTRPC_RET
s/sicher/sichern/ ;-)

> + * wiederherzustellen. eax ist davon ausgenommen, da es die
> Funktionsnummer + * des Syscalls enthalten muß.
> + *
> + * @param esp Interrupt-Stackframe des vom RPC-Handler zurückkehrenden
> Tasks + */
> +void syscall_fastrpc_ret(void)
> +{
> +    rpc_t* rpc = list_pop(cpu_get_current()->thread->process->rpcs);
> +    interrupt_stack_frame_t* callee_isf =
> +        cpu_get_current()->thread->kernel_stack;
> +
> +    // Wenn der Task vom RPC-Handler zurückkehrt, obwohl der Handler
> +    // gar nicht aufgerufen wurde, läuft was schief
> +    if (rpc == NULL) {
> +#if 0
> +        if(debug_test_flag(DEBUG_FLAG_STACK_BACKTRACE)) {
> +            stack_backtrace_ebp(callee_isf->ebp, callee_isf->eip);
> +        }
> +#endif
> +        kprintf("Unerwartete Rueckkehr vom RPC-Handler\n");
Und dann kommt absichtlich ein PF? ;-)

> Index: trunk/src/kernel2/src/arch/i386/mm/virt.c
> ===================================================================
> --- trunk.orig/src/kernel2/src/arch/i386/mm/virt.c
> +++ trunk/src/kernel2/src/arch/i386/mm/virt.c
> @@ -147,32 +147,35 @@ void vmm_kernel_unmap(vaddr_t start, siz
>      }
>  }
>
> -#if 0
>  /**
>   * Vergr�ssert den Userspace-Stack eines Tasks um pages Seiten
s/Tasks/Threads/ oder? ;-)

>   *
>   * @param task_ptr Pointer zur Task-Struktur
>   * @param pages Anzahl der zu mappenden Seiten
>   */
> -void increase_user_stack_size(struct task * task_ptr, int pages)
> +void increase_user_stack_size(pm_thread_t* task_ptr, int pages)
Wäre es soviel arbeit task_ptr anders zu benennen? ;-)

...

> -        map_page((mmc_context_t) task_ptr->cr3,
> task_ptr->user_stack_bottom, phys_alloc_page(), PTE_P | PTE_W | PTE_U); +  
>      mmc_map(&task_ptr->process->context,
> +            task_ptr->kernel_stack_bottom,
> +            pmm_alloc(1), PTE_P | PTE_W | PTE_U, 1);
>  	}
>  }
> -#endif
Gibts hier nicht ein Makro USERSPACE_DATA oder so?

> Index: trunk/src/kernel2/src/arch/i386/mm/mm_context.c
> ===================================================================
> --- trunk.orig/src/kernel2/src/arch/i386/mm/mm_context.c
> +++ trunk/src/kernel2/src/arch/i386/mm/mm_context.c
> @@ -509,7 +509,7 @@ static vaddr_t find_contiguous_pages
>   * Mappt einen Speicherbereich in einen MM-Kontext an eine freie Adresse
> in * einem vorgegebenen Adressberech.
>   *
> - * @param page_directory Kontext, in den gemappt werden soll
> + * @param context Kontext, in den gemappt werden soll
>   * @param start Physische Startadresse des zu mappenden Speicherbereichs
>   * @param count Anzahl der zu mappenden Seiten
>   * @param lower_limit Niedrigste zul�ssige virtuelle Adresse
> @@ -532,3 +532,44 @@ vaddr_t mmc_automap(mmc_context_t* conte
>          return NULL;
>      }
>  }
> +
> +/**
> + * Mappt einen Speicherbereich eines anderen Tasks in einen MM-Kontext an
> eine + * freie Adresse in einem vorgegebenen Adressberech.
> + *
> + * @param target_ctx Kontext, in den gemappt werden soll
> + * @param source_ctx Kontext, aus dem Speicher gemappt werden soll
> + * @param start Virtuelle Startadresse des zu mappenden Speicherbereichs
> + *      bezueglich source_ctx
> + * @param count Anzahl der zu mappenden Seiten
> + * @param lower_limit Niedrigste zulaessige virtuelle Adresse
> + * @param upper_limit Hoechste zulaessige virtuelle Adresse
> + * @param flags Flags fuer die Pagetable
> + */
> +vaddr_t mmc_automap_user(mmc_context_t* target_ctx, mmc_context_t*
> source_ctx, +    vaddr_t start, size_t count, uintptr_t lower_limit,
> uintptr_t upper_limit, +    int flags)
> +{
> +    size_t i;
> +    paddr_t paddr;
> +    vaddr_t vaddr;
> +    vaddr_t free_page =
> +        find_contiguous_pages(target_ctx, count, lower_limit,
> upper_limit); +
> +    if (free_page == NULL) {
> +        return NULL;
> +    }
> +
> +    // FIXME Hier wird unter Umstaenden ziemlich oft dieselbe Pagetable
> gemappt +    // und wieder ungemappt (in mmc_resolve)
> +    for (i = 0; i < count; i++) {
> +        paddr = mmc_resolve(source_ctx, start + (i * PAGE_SIZE));
> +        vaddr = free_page + (i * PAGE_SIZE);
> +        if (!mmc_map(target_ctx, vaddr, paddr, flags, count)) {
> +            mmc_unmap(target_ctx, free_page, i);

Und phyisch freigeben?

> +            return NULL;
> +        }
> +    }
> +
> +    return free_page;
> +}


Wenn du das angepasst hast, kannst du direkt einchecken.