From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1JoK6x-0000Zo-HO for qemu-devel@nongnu.org; Tue, 22 Apr 2008 11:08:48 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1JoK6w-0000ZL-Tb for qemu-devel@nongnu.org; Tue, 22 Apr 2008 11:08:47 -0400 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1JoK6w-0000Z9-Jr for qemu-devel@nongnu.org; Tue, 22 Apr 2008 11:08:46 -0400 Received: from os.inf.tu-dresden.de ([141.76.48.99]) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1JoK6u-0001QK-6d for qemu-devel@nongnu.org; Tue, 22 Apr 2008 11:08:44 -0400 Received: from os-dhcp018.inf.tu-dresden.de ([141.76.49.18] helo=schlepp) by os.inf.tu-dresden.de with esmtpsa (TLSv1:AES256-SHA:256) (Exim 4.69) id 1JoK6r-0000T0-CK for qemu-devel@nongnu.org; Tue, 22 Apr 2008 17:08:41 +0200 Date: Tue, 22 Apr 2008 17:08:41 +0200 From: Henning Schild Message-ID: <20080422170841.2a6e9570@schlepp> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="MP_/A=FrSw0vK1XX41eTgK3AQTe" Subject: [Qemu-devel] kqemu descriptor table cache patch Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org --MP_/A=FrSw0vK1XX41eTgK3AQTe Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Content-Disposition: inline Hello, i am currently porting kqemu to l4linux (http://os.inf.tu-dresden.de/L4/LinuxOnL4/). During my work i found that NetBSD does not map its GDT completely which is the reason why it cant be used on kqemu. The GDT limit is 0xffff on NetBSD but only the first page of the GDT is mapped. Walking the pagetable for the 2nd page fails. Maybe there are other OSs out there that do the same thing ... Kqemu returns pagefaults to the guest OS when LDT/GDT are not mapped according to the given limits. I wrote a patch that keeps kqemu from faulting when it updates its dt cache, instead all pages that are not mapped will be skipped. ftp://ftp.netbsd.org/pub/NetBSD/iso/livecd/netbsd-live-2007.iso wont work with kqemu-1.3.0pre11, after applying the patch it will. tested on a Linux host regards, Henning Schild --MP_/A=FrSw0vK1XX41eTgK3AQTe Content-Type: text/x-patch; name=kqemu-1.3.0pre11_dont_fault_dt.patch Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=kqemu-1.3.0pre11_dont_fault_dt.patch --- /tmp/kqemu-1.3.0pre11/common/monitor.c 2007-02-06 22:02:00.000000000 +0100 +++ common/monitor.c 2008-04-19 18:27:18.000000000 +0200 @@ -548,6 +548,8 @@ static inline int ram_get_dirty(struct kqemu_state *s, unsigned long ram_addr, int dirty_flags) { + if (ram_addr == -1) + return 0; return s->ram_dirty[ram_addr >> PAGE_SHIFT] & dirty_flags; } @@ -961,8 +963,8 @@ return 1; } -static void soft_tlb_fill(struct kqemu_state *s, unsigned long vaddr, - int is_write, int is_user) +static int soft_tlb_fill(struct kqemu_state *s, unsigned long vaddr, + int is_write, int is_user, int fault) { long ret; #ifdef PROFILE_SOFTMMU @@ -972,13 +974,18 @@ ret = cpu_x86_handle_mmu_fault(s, vaddr, is_write, is_user, 1); #ifdef PROFILE_SOFTMMU ti = getclock() - ti; - monitor_log(s, "soft_tlb_fill: w=%d u=%d addr=%p cycle=%d\n", - is_write, is_user, (void *)vaddr, ti); + monitor_log(s, "soft_tlb_fill: w=%d u=%d addr=%p cycle=%d ret=%08lx\n", + is_write, is_user, (void *)vaddr, ti, ret); #endif - if (ret == 1) - raise_exception(s, EXCP0E_PAGE); + if (ret == 1) { + if (fault) + raise_exception(s, EXCP0E_PAGE); + else + return 1; + } else if (ret == 2) raise_exception(s, KQEMU_RET_SOFTMMU); + return 0; } static void *map_vaddr(struct kqemu_state *s, unsigned long addr, @@ -990,8 +997,10 @@ e = &s->soft_tlb[(addr >> PAGE_SHIFT) & (SOFT_TLB_SIZE - 1)]; redo: if (e->vaddr[(is_user << 1) + is_write] != (addr & PAGE_MASK)) { - soft_tlb_fill(s, addr, is_write, is_user); - goto redo; + if (!soft_tlb_fill(s, addr, is_write, is_user, 0)) + goto redo; + else + return NULL; } else { taddr = e->addend + addr; } @@ -1008,7 +1017,7 @@ e = &s->soft_tlb[(addr >> PAGE_SHIFT) & (SOFT_TLB_SIZE - 1)]; redo: if (unlikely(e->vaddr[(is_user << 1)] != (addr & PAGE_MASK))) { - soft_tlb_fill(s, addr, 0, is_user); + soft_tlb_fill(s, addr, 0, is_user, 1); goto redo; } else { taddr = e->addend + addr; @@ -1039,7 +1048,7 @@ val = v0 | (v1 << 8); } } else { - soft_tlb_fill(s, addr, 0, is_user); + soft_tlb_fill(s, addr, 0, is_user, 1); goto redo; } } else { @@ -1075,7 +1084,7 @@ val = (v0 >> shift) | (v1 << (32 - shift)); } } else { - soft_tlb_fill(s, addr, 0, is_user); + soft_tlb_fill(s, addr, 0, is_user, 1); goto redo; } } else { @@ -1111,7 +1120,7 @@ val = (v0 >> shift) | (v1 << (64 - shift)); } } else { - soft_tlb_fill(s, addr, 0, is_user); + soft_tlb_fill(s, addr, 0, is_user, 1); goto redo; } } else { @@ -1131,7 +1140,7 @@ e = &s->soft_tlb[(addr >> PAGE_SHIFT) & (SOFT_TLB_SIZE - 1)]; redo: if (unlikely(e->vaddr[(is_user << 1) + 1] != (addr & PAGE_MASK))) { - soft_tlb_fill(s, addr, 1, is_user); + soft_tlb_fill(s, addr, 1, is_user, 1); goto redo; } else { taddr = e->addend + addr; @@ -1158,7 +1167,7 @@ stb_slow(s, addr + 1, val >> 8, is_user); } } else { - soft_tlb_fill(s, addr, 1, is_user); + soft_tlb_fill(s, addr, 1, is_user, 1); goto redo; } } else { @@ -1189,7 +1198,7 @@ stb_slow(s, addr + 3, val >> 24, is_user); } } else { - soft_tlb_fill(s, addr, 1, is_user); + soft_tlb_fill(s, addr, 1, is_user, 1); goto redo; } } else { @@ -1224,7 +1233,7 @@ stb_slow(s, addr + 7, val >> 56, is_user); } } else { - soft_tlb_fill(s, addr, 1, is_user); + soft_tlb_fill(s, addr, 1, is_user, 1); goto redo; } } else { @@ -1802,13 +1811,18 @@ page_end = dt_end; sel2 = sel + (page_end - dt_ptr); ptr = map_vaddr(s, dt_ptr, 0, 0); - ram_addr = ram_ptr_to_ram_addr(s, ptr); + if (ptr) + ram_addr = ram_ptr_to_ram_addr(s, ptr); + else + ram_addr = -1; if (dt_changed || s->dt_ram_addr[dt_type][pindex] != ram_addr || ram_get_dirty(s, ram_addr, DT_DIRTY_FLAG)) { s->dt_ram_addr[dt_type][pindex] = ram_addr; - check_dt_entries_page(s, dt_type, sel, sel2, ptr); - ram_reset_dirty(s, ram_addr, DT_DIRTY_FLAG); + if (ptr) { + check_dt_entries_page(s, dt_type, sel, sel2, ptr); + ram_reset_dirty(s, ram_addr, DT_DIRTY_FLAG); + } } sel = sel2; pindex++; --MP_/A=FrSw0vK1XX41eTgK3AQTe--