[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.