Date: Thu, 5 Mar 1998 16:14:43 +1100 From: Bruce Evans <bde@zeta.org.au> To: adkin003@tc.umn.edu, Tor.Egge@idi.ntnu.no Cc: smp@FreeBSD.ORG Subject: Re: Current SMP kernel panics on booting Message-ID: <199803050514.QAA02534@godzilla.zeta.org.au>
next in thread | raw e-mail | index | archive | help
>Please try a kernel with the NO_F00F_HACK option. f00f_hack() is >broken, since it causes further calls to setidt() to have very little >effect. Here are my (very old :-() fixes for this. I think you only want the first hunk. Only one page is necessary for the buggy version and for a version that maps the page read-write in setidt(), so I'm saving some space and preparing for a better setidt() by only allocating one. The other changes are mostly style fixes. This should all be done differently, perhaps by allocating a page or two of physical memory earlier as in NetBSD. It would have been better to allocate one idt without padding in the text section and mapping it read/write in setidt(), but the 4MB page breaks the read-onlyness of the text section. Bruce diff -c2 machdep.c~ machdep.c *** machdep.c~ Tue Mar 3 12:58:07 1998 --- machdep.c Tue Mar 3 12:58:10 1998 *************** *** 1056,1061 **** int selec; { ! struct gate_descriptor *ip = idt + idx; ip->gd_looffset = (int)func; ip->gd_selector = selec; --- 1119,1129 ---- int selec; { ! struct gate_descriptor *ip; + #if defined(I586_CPU) && !defined(NO_F00F_HACK) + ip = (t_idt != NULL ? t_idt : idt) + idx; + #else + ip = idt + idx; + #endif ip->gd_looffset = (int)func; ip->gd_selector = selec; *************** *** 1560,1593 **** #if defined(I586_CPU) && !defined(NO_F00F_HACK) ! static void f00f_hack(void *unused); ! SYSINIT(f00f_hack, SI_SUB_INTRINSIC, SI_ORDER_FIRST, f00f_hack, NULL); static void ! f00f_hack(void *unused) { struct region_descriptor r_idt; vm_offset_t tmp; - int i; if (!has_f00f_bug) return; ! ! printf("Intel Pentium F00F detected, installing workaround\n"); ! ! r_idt.rd_limit = sizeof(idt) - 1; ! tmp = kmem_alloc(kernel_map, PAGE_SIZE * 2); if (tmp == 0) panic("kmem_alloc returned 0"); ! if (((unsigned int)tmp & (PAGE_SIZE-1)) != 0) ! panic("kmem_alloc returned non-page-aligned memory"); ! /* Put the first seven entries in the lower page */ ! t_idt = (struct gate_descriptor*)(tmp + PAGE_SIZE - (7*8)); bcopy(idt, t_idt, sizeof(idt)); ! r_idt.rd_base = (int)t_idt; ! lidt(&r_idt); ! if (vm_map_protect(kernel_map, tmp, tmp + PAGE_SIZE, ! VM_PROT_READ, FALSE) != KERN_SUCCESS) panic("vm_map_protect failed"); ! return; } #endif /* defined(I586_CPU) && !NO_F00F_HACK */ --- 1623,1662 ---- #if defined(I586_CPU) && !defined(NO_F00F_HACK) ! static void f00f_hack __P((void *unused)); ! SYSINIT(f00f_hack, SI_SUB_INTRINSIC, SI_ORDER_FIRST, f00f_hack, NULL) static void ! f00f_hack(unused) ! void *unused; ! { struct region_descriptor r_idt; vm_offset_t tmp; if (!has_f00f_bug) return; ! printf("Intel Pentium detected, installing workaround for F00F bug\n"); ! #if 0 tmp = kmem_alloc(kernel_map, PAGE_SIZE * 2); + #else + tmp = kmem_alloc(kernel_map, PAGE_SIZE * 1); + #endif if (tmp == 0) panic("kmem_alloc returned 0"); ! ! /* Put the problematic entry (#6) at the end of the lower page. */ ! t_idt = (struct gate_descriptor *) ! #if 0 ! (tmp + PAGE_SIZE - 7 * sizeof(struct gate_descriptor)); ! #else ! tmp; ! #endif ! bcopy(idt, t_idt, sizeof(idt)); ! if (vm_map_protect(kernel_map, tmp, tmp + PAGE_SIZE, VM_PROT_READ, ! FALSE) != KERN_SUCCESS) panic("vm_map_protect failed"); ! r_idt.rd_limit = sizeof(idt) - 1; ! r_idt.rd_base = (unsigned)t_idt; ! lidt(&r_idt); } #endif /* defined(I586_CPU) && !NO_F00F_HACK */ To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-smp" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199803050514.QAA02534>