? bigpatch.diff ? build ? crossbuild.sh ? current-modified.diff ? device_attached.diff ? dmesg.xaron ? dosorca.dmesg ? hypervisor.diff ? kern_trace.diff ? kern_trace2.diff ? mpacpi_output.dmesg ? netbsd-0001-port-xen-map-memory-directly-in-privcmd-PRIVCMD_MMAP.patch ? netbsd-generic.objdump ? netbsd_tcprespond.diff ? netbsd_tcprespond2.diff ? nfs_debug.diff ? numa_x86.diff ? pcireg.h.dif ? pfsync.diff ? radix.diff ? xen.diff ? xen_makedev.diff ? external/bsd/dhcpcd/dist/netbsd_dhcpcd.diff ? external/bsd/flex/dist/parse.c ? external/bsd/flex/dist/parse.h ? sys/memcpy.list ? sys/net_radix.diff ? sys/arch/x86/x86/cpu.c.new ? sys/arch/xen/x86/cpu.c.new ? sys/arch/xen/xen/xengnt.diff ? sys/dev/pci/if_bge.diff ? sys/dev/pci/if_bge2.diff ? sys/nfs/nfs_vnops.diff Index: etc/etc.amd64/MAKEDEV.conf =================================================================== RCS file: /cvsroot/src/etc/etc.amd64/MAKEDEV.conf,v retrieving revision 1.20 diff -u -p -r1.20 MAKEDEV.conf --- etc/etc.amd64/MAKEDEV.conf 23 Sep 2012 01:15:17 -0000 1.20 +++ etc/etc.amd64/MAKEDEV.conf 25 Oct 2012 14:04:58 -0000 @@ -44,5 +44,18 @@ all_md) ;; xen) + makedir xen 755 + unit=0 + for dev in evtchn xsd_kva + do + mkdev xen/$dev c 141 $unit + unit=$(($unit + 1)) + done + unit=0 + for dev in xencons gnttab + do + mkdev xen/$dev c 143 $unit + unit=$(($unit + 1)) + done makedev xenevt xencons xsd_kva ;; Index: etc/etc.i386/MAKEDEV.conf =================================================================== RCS file: /cvsroot/src/etc/etc.i386/MAKEDEV.conf,v retrieving revision 1.25 diff -u -p -r1.25 MAKEDEV.conf --- etc/etc.i386/MAKEDEV.conf 23 Sep 2012 01:15:17 -0000 1.25 +++ etc/etc.i386/MAKEDEV.conf 25 Oct 2012 14:04:58 -0000 @@ -48,6 +48,19 @@ all_md) ;; xen) + makedir xen 755 + unit=0 + for dev in evtchn xsd_kva + do + mkdev xen/$dev c 141 $unit + unit=$(($unit + 1)) + done + unit=0 + for dev in xencons gnttab + do + mkdev xen/$dev c 143 $unit + unit=$(($unit + 1)) + done makedev xenevt xencons xsd_kva ;; Index: external/bsd/dhcpcd/dist/configure.c =================================================================== RCS file: /cvsroot/src/external/bsd/dhcpcd/dist/configure.c,v retrieving revision 1.1.1.18 diff -u -p -r1.1.1.18 configure.c --- external/bsd/dhcpcd/dist/configure.c 3 Sep 2012 09:46:13 -0000 1.1.1.18 +++ external/bsd/dhcpcd/dist/configure.c 25 Oct 2012 14:05:00 -0000 @@ -560,8 +560,8 @@ add_subnet_route(struct rt *rt, const st if (iface->net.s_addr == INADDR_BROADCAST || iface->net.s_addr == INADDR_ANY || (iface->state->options->options & - (DHCPCD_INFORM | DHCPCD_STATIC) && - iface->state->options->req_addr.s_addr == INADDR_ANY)) + (DHCPCD_INFORM | DHCPCD_STATIC) && + iface->state->options->req_addr.s_addr == INADDR_ANY)) return rt; r = xmalloc(sizeof(*r)); @@ -573,7 +573,7 @@ add_subnet_route(struct rt *rt, const st } static struct rt * -get_routes(const struct interface *iface) +if_get_routes(const struct interface *iface) { struct rt *rt, *nrt = NULL, *r = NULL; @@ -774,7 +774,7 @@ configure(struct interface *iface) struct dhcp_message *dhcp = iface->state->new; struct dhcp_lease *lease = &iface->state->lease; struct if_options *ifo = iface->state->options; - struct rt *rt; + struct rt *rt, *crt, *rtp;; /* As we are now adjusting an interface, we need to ensure * we have them in the right order for routing and configuration. */ @@ -791,9 +791,7 @@ configure(struct interface *iface) } /* This also changes netmask */ - if (!(ifo->options & DHCPCD_INFORM) || - !has_address(iface->name, &lease->addr, &lease->net)) - { + if (!has_address(iface->name, &lease->addr, &lease->net)) { syslog(LOG_DEBUG, "%s: adding IP address %s/%d", iface->name, inet_ntoa(lease->addr), inet_ntocidr(lease->net)); @@ -815,7 +813,8 @@ configure(struct interface *iface) iface->net.s_addr = lease->net.s_addr; /* We need to delete the subnet route to have our metric or - * prefer the interface. */ + * prefer the interface, but don't touch it if it already exists + * in the kernel routing table. */ rt = get_subnet_route(dhcp); if (rt != NULL) { rt->iface = iface; Index: external/bsd/dhcpcd/dist/net.c =================================================================== RCS file: /cvsroot/src/external/bsd/dhcpcd/dist/net.c,v retrieving revision 1.1.1.21 diff -u -p -r1.1.1.21 net.c --- external/bsd/dhcpcd/dist/net.c 12 Jul 2012 16:47:59 -0000 1.1.1.21 +++ external/bsd/dhcpcd/dist/net.c 25 Oct 2012 14:05:00 -0000 @@ -413,9 +413,6 @@ discover_interfaces(int argc, char * con #endif } ifp->hwlen = sdl->sdl_alen; -#ifndef CLLADDR -# define CLLADDR(s) ((const char *)((s)->sdl_data + (s)->sdl_nlen)) -#endif memcpy(ifp->hwaddr, CLLADDR(sdl), ifp->hwlen); #elif AF_PACKET sll = (const struct sockaddr_ll *)(void *)ifa->ifa_addr; Index: external/bsd/dhcpcd/dist/net.h =================================================================== RCS file: /cvsroot/src/external/bsd/dhcpcd/dist/net.h,v retrieving revision 1.1.1.13 diff -u -p -r1.1.1.13 net.h --- external/bsd/dhcpcd/dist/net.h 12 Jul 2012 16:48:02 -0000 1.1.1.13 +++ external/bsd/dhcpcd/dist/net.h 25 Oct 2012 14:05:00 -0000 @@ -89,6 +89,10 @@ # define IN_LINKLOCAL(addr) ((addr & IN_CLASSB_NET) == LINKLOCAL_ADDR) #endif +#ifndef CLLADDR +# define CLLADDR(s) ((const char *)((s)->sdl_data + (s)->sdl_nlen)) +#endif + struct rt { struct in_addr dest; struct in_addr net; @@ -139,6 +143,7 @@ int if_route(const struct rt *rt, int); #define del_route(rt) if_route(rt, -1) #define del_src_route(rt) if_route(rt, -2); void free_routes(struct rt *); +struct rt *get_routes(void); int if_address6(const struct interface *, const struct ipv6_addr *, int); #define add_address6(ifp, a) if_address6(ifp, a, 1) Index: sys/arch/amd64/amd64/mainbus.c =================================================================== RCS file: /cvsroot/src/sys/arch/amd64/amd64/mainbus.c,v retrieving revision 1.33 diff -u -p -r1.33 mainbus.c --- sys/arch/amd64/amd64/mainbus.c 17 May 2011 17:34:47 -0000 1.33 +++ sys/arch/amd64/amd64/mainbus.c 25 Oct 2012 14:05:50 -0000 @@ -61,6 +61,8 @@ __KERNEL_RCSID(0, "$NetBSD: mainbus.c,v #if NACPICA > 0 #include +#include +#include #endif #if NIPMI > 0 @@ -157,6 +159,7 @@ mainbus_attach(device_t parent, device_t #endif #if NACPICA > 0 int acpi_present = 0; + int rc; #endif #ifdef MPBIOS int mpbios_present = 0; @@ -201,8 +204,30 @@ mainbus_attach(device_t parent, device_t * Building the interrupt routing structures can only * be done later (via a callback). */ - if (acpi_present) + if (acpi_present) { mpacpi_active = mpacpi_scan_apics(self, &numcpus); + if (!acpisrat_exist()) { + aprint_error_dev(self, "ACPI SRAT table not present\n"); + } else { + if ((rc = acpisrat_init()) != 0) + aprint_error_dev(self, + "ACPI SRAT initialization failed, rc: %i\n", + rc); + else + acpisrat_dump(); + } + + if (!acpislit_exist()) { + aprint_error_dev(self, "ACPI SLIT table not present\n"); + } else { + if ((rc = acpislit_init()) != 0) + aprint_error_dev(self, + "ACPI SLIT initialization failed, rc: %i\n", + rc); + else + acpislit_dump(); + } + } #endif if (!mpacpi_active) { Index: sys/arch/amd64/conf/GENERIC =================================================================== RCS file: /cvsroot/src/sys/arch/amd64/conf/GENERIC,v retrieving revision 1.365 diff -u -p -r1.365 GENERIC --- sys/arch/amd64/conf/GENERIC 17 Oct 2012 14:48:08 -0000 1.365 +++ sys/arch/amd64/conf/GENERIC 25 Oct 2012 14:05:50 -0000 @@ -89,7 +89,7 @@ options BUFQ_PRIOCSCAN options DIAGNOSTIC # expensive kernel consistency checks # XXX to be commented out on release branch #options DEBUG # expensive debugging checks/support -#options LOCKDEBUG # expensive locking checks/support +options LOCKDEBUG # expensive locking checks/support #options KMEMSTATS # kernel memory statistics (vmstat -m) # @@ -103,7 +103,7 @@ options DDB # in-kernel debugger options DDB_HISTORY_SIZE=512 # enable history editing in DDB #options KGDB # remote debugger #options KGDB_DEVNAME="\"com\"",KGDB_DEVADDR=0x3f8,KGDB_DEVRATE=9600 -#makeoptions DEBUG="-g" # compile full symbol table +makeoptions DEBUG="-g" # compile full symbol table #options SYSCALL_STATS # per syscall counts #options SYSCALL_TIMES # per syscall times #options SYSCALL_TIMES_HASCOUNTER # use 'broken' rdtsc (soekris) @@ -211,13 +211,14 @@ options IPFILTER_COMPAT # Compat for IP # These options enable verbose messages for several subsystems. # Warning, these may compile large string tables into the kernel! +#options ACPI_DEBUG #options ACPIVERBOSE # verbose ACPI configuration messages #options MIIVERBOSE # verbose PHY autoconfig messages -#options PCIVERBOSE # verbose PCI device autoconfig messages +options PCIVERBOSE # verbose PCI device autoconfig messages #options PCI_CONFIG_DUMP # verbosely dump PCI config space #options PCMCIAVERBOSE # verbose PCMCIA configuration messages options SCSIVERBOSE # human readable SCSI error messages -#options USBVERBOSE # verbose USB device autoconfig messages +options USBVERBOSE # verbose USB device autoconfig messages options NFS_BOOT_DHCP,NFS_BOOT_BOOTPARAM @@ -286,8 +287,8 @@ acpiec* at acpi? # ACPI Embedded Contr acpiecdt* at acpi? # ACPI Embedded Controller (early) acpifan* at acpi? # ACPI Fan acpilid* at acpi? # ACPI Lid Switch -#acpipmtr* at acpi? # ACPI Power Meter (experimental) -#acpismbus* at acpi? # ACPI SMBus CMI (experimental) +acpipmtr* at acpi? # ACPI Power Meter (experimental) +acpismbus* at acpi? # ACPI SMBus CMI (experimental) acpitz* at acpi? # ACPI Thermal Zone acpivga* at acpi? # ACPI Display Adapter acpiout* at acpivga? # ACPI Display Output Device @@ -338,8 +339,8 @@ ppb* at pci? dev ? function ? # PCI-PCI # XXX 'puc's aren't really bridges, but there's no better place for them here puc* at pci? dev ? function ? # PCI "universal" comm. cards -#amdpcib* at pci? dev ? function ? # AMD 8111 PCI-ISA w/ HPET -#hpet* at amdpcib? +amdpcib* at pci? dev ? function ? # AMD 8111 PCI-ISA w/ HPET +hpet* at amdpcib? pwdog* at pci? dev ? function ? # QUANCOM PWDOG1 @@ -466,7 +467,7 @@ amdtemp* at amdnb_misc? # AMD CPU Temp # AMD 768 and 8111 power/ACPI controllers amdpm* at pci? dev ? function ? # RNG and SMBus 1.0 interface -#iic* at amdpm? # sensors below are on this bus +iic* at amdpm? # sensors below are on this bus # NVIDIA nForce2/3/4 SMBus controller nfsmbc* at pci? dev ? function ? @@ -499,10 +500,10 @@ iic* at ichsmb? #ug0 at isa? port 0xe0 # Serial Presence Detect capable memory modules -#spdmem* at iic? addr 0x50 -#spdmem* at iic? addr 0x51 -#spdmem* at iic? addr 0x52 -#spdmem* at iic? addr 0x53 +spdmem* at iic? addr 0x50 +spdmem* at iic? addr 0x51 +spdmem* at iic? addr 0x52 +spdmem* at iic? addr 0x53 #spdmem* at iic? addr 0x54 #spdmem* at iic? addr 0x55 #spdmem* at iic? addr 0x56 Index: sys/arch/amd64/conf/Makefile.amd64 =================================================================== RCS file: /cvsroot/src/sys/arch/amd64/conf/Makefile.amd64,v retrieving revision 1.40 diff -u -p -r1.40 Makefile.amd64 --- sys/arch/amd64/conf/Makefile.amd64 19 Dec 2011 14:06:16 -0000 1.40 +++ sys/arch/amd64/conf/Makefile.amd64 25 Oct 2012 14:05:50 -0000 @@ -27,9 +27,12 @@ USE_SSP?= yes ## ## (1) port identification ## +XEN= $S/arch/xen AMD64= $S/arch/amd64 GENASSYM_CONF= ${AMD64}/amd64/genassym.cf +XEN_INC= $S/arch/xen/include + ## ## (2) compile settings ## @@ -38,6 +41,8 @@ CPPFLAGS+= -Damd64 -Dx86_64 CFLAGS+= -mcmodel=kernel CFLAGS+= -mno-red-zone -mno-sse -mno-sse2 -mno-sse3 +EXTRA_INCLUDES= -I${.CURDIR}/xen + ## ## (3) libkern and compat ## @@ -63,6 +68,14 @@ copy.o: ${AMD64}/amd64/copy.S assym.h spl.o: ${AMD64}/amd64/spl.S assym.h ${NORMAL_S} +.ifndef noBEGIN +.if !make(obj) && !make(clean) && !make(cleandir) +.BEGIN: + -rm -f xen + ln -s ${XEN_INC} xen +.endif +.endif + AFLAGS.locore.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:} AFLAGS.mptramp.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:} AFLAGS.spl.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:} Index: sys/arch/amd64/conf/XEN3_DOM0 =================================================================== RCS file: /cvsroot/src/sys/arch/amd64/conf/XEN3_DOM0,v retrieving revision 1.90 diff -u -p -r1.90 XEN3_DOM0 --- sys/arch/amd64/conf/XEN3_DOM0 17 Oct 2012 14:48:08 -0000 1.90 +++ sys/arch/amd64/conf/XEN3_DOM0 25 Oct 2012 14:05:50 -0000 @@ -48,14 +48,15 @@ options BUFQ_PRIOCSCAN # Diagnostic/debugging support options options DIAGNOSTIC # expensive kernel consistency checks -#options DEBUG # expensive debugging checks/support +options DEBUG # expensive debugging checks/support +options LOCKDEBUG options KMEMSTATS # kernel memory statistics (vmstat -m) options DDB # in-kernel debugger options DDB_ONPANIC=1 # see also sysctl(8): `ddb.onpanic' options DDB_HISTORY_SIZE=512 # enable history editing in DDB #options KGDB # remote debugger #options KGDB_DEVNAME="\"com\"",KGDB_DEVADDR=0x2f8,KGDB_DEVRATE=57600 -#makeoptions DEBUG="-g" # compile full symbol table +makeoptions DEBUG="-g" # compile full symbol table makeoptions COPTS="-O2 -fno-omit-frame-pointer" options DDB_COMMANDONENTER="trace;show registers" @@ -153,13 +154,17 @@ options IPFILTER_LOOKUP # ippool(8) sup #options ALTQ_WFQ # Weighted Fair Queueing options NFS_BOOT_DHCP,NFS_BOOT_BOOTPARAM -#options NFS_BOOT_BOOTSTATIC +options NFS_BOOT_BOOTSTATIC +options NFS_BOOT_RWSIZE=8192 +#options NFS_BOOT_RWSIZE=16384 #options NFS_BOOTSTATIC_MYIP="\"169.254.1.2\"" #options NFS_BOOTSTATIC_GWIP="\"169.254.1.1\"" #options NFS_BOOTSTATIC_MASK="\"255.255.255.0\"" #options NFS_BOOTSTATIC_SERVADDR="\"169.254.1.1\"" #options NFS_BOOTSTATIC_SERVER="\"server:/path/to/root\"" +#options MBUFTRACE + # # wscons options # @@ -209,11 +214,12 @@ xencons* at hypervisor? # Xen virtual c balloon* at xenbus? # Xen balloon device acpi0 at hypervisor? +options ACPI_DEBUG #options ACPI_ACTIVATE_DEV # If set, activate inactive devices options ACPI_SCANPCI # find PCI roots using ACPI #options ACPICA_PEDANTIC # force strict conformance to the Spec. #options ACPIVERBOSE # verbose ACPI configuration messages -#options MIIVERBOSE # verbose PHY autoconfig messages +options MIIVERBOSE # verbose PHY autoconfig messages options MPBIOS # configure CPUs and APICs using MPBIOS #options MPDEBUG # MPBIOS configures PCI roots #options MPVERBOSE # verbose MPBIOS autoconfig messages @@ -221,8 +227,8 @@ options MPBIOS_SCANPCI # MPBIOS config #options PCI_ADDR_FIXUP # fixup PCI I/O addresses #options PCI_BUS_FIXUP # fixup PCI bus numbering #options PCI_INTR_FIXUP # fixup PCI interrupt routing -#options PCIVERBOSE # verbose PCI device autoconfig messages -#options USBVERBOSE # verbose USB device autoconfig messages +options PCIVERBOSE # verbose PCI device autoconfig messages +options USBVERBOSE # verbose USB device autoconfig messages ioapic* at mainbus? apid ? @@ -298,6 +304,7 @@ lpt0 at isa? port 0x378 irq 7 # standard amdnb_misc* at pci? # AMD NB Misc Configuration amdtemp* at amdnb_misc? # AMD CPU Temperature sensors +amdnb_l3dis* at amdnb_misc? # AMD NB L3 cache index disable # AMD 768 and 8111 power/ACPI controllers amdpm* at pci? dev ? function ? # RNG and SMBus 1.0 interface @@ -842,5 +849,23 @@ pseudo-device xenevt pseudo-device xvif pseudo-device xbdback +#options FILEASSOC # fileassoc(9) - required for Veriexec + +# Veriexec +# +# a pseudo device needed for veriexec +#pseudo-device veriexec 1 +# +# Uncomment the fingerprint methods below that are desired. Note that +# removing fingerprint methods will have almost no impact on the kernel +# code size. +# +#options VERIFIED_EXEC_FP_RMD160 +#options VERIFIED_EXEC_FP_SHA256 +#options VERIFIED_EXEC_FP_SHA384 +#options VERIFIED_EXEC_FP_SHA512 +#options VERIFIED_EXEC_FP_SHA1 +#options VERIFIED_EXEC_FP_MD5 + options PAX_MPROTECT=0 # PaX mprotect(2) restrictions options PAX_ASLR=0 # PaX Address Space Layout Randomization Index: sys/arch/amd64/conf/XEN3_DOMU =================================================================== RCS file: /cvsroot/src/sys/arch/amd64/conf/XEN3_DOMU,v retrieving revision 1.41 diff -u -p -r1.41 XEN3_DOMU --- sys/arch/amd64/conf/XEN3_DOMU 17 Oct 2012 14:48:08 -0000 1.41 +++ sys/arch/amd64/conf/XEN3_DOMU 25 Oct 2012 14:05:50 -0000 @@ -141,7 +141,7 @@ options IPFILTER_COMPAT # Compat for IP #options ALTQ_WFQ # Weighted Fair Queueing options NFS_BOOT_DHCP,NFS_BOOT_BOOTPARAM -#options NFS_BOOT_BOOTSTATIC +options NFS_BOOT_BOOTSTATIC #options NFS_BOOTSTATIC_MYIP="\"169.254.1.2\"" #options NFS_BOOTSTATIC_GWIP="\"169.254.1.1\"" #options NFS_BOOTSTATIC_MASK="\"255.255.255.0\"" Index: sys/arch/i386/conf/GENERIC =================================================================== RCS file: /cvsroot/src/sys/arch/i386/conf/GENERIC,v retrieving revision 1.1082 diff -u -p -r1.1082 GENERIC --- sys/arch/i386/conf/GENERIC 17 Oct 2012 14:48:13 -0000 1.1082 +++ sys/arch/i386/conf/GENERIC 25 Oct 2012 14:05:52 -0000 @@ -118,7 +118,7 @@ options DDB_HISTORY_SIZE=512 # enable h #options DDB_VERBOSE_HELP #options KGDB # remote debugger #options KGDB_DEVNAME="\"com\"",KGDB_DEVADDR=0x3f8,KGDB_DEVRATE=9600 -#makeoptions DEBUG="-g" # compile full symbol table +makeoptions DEBUG="-g" # compile full symbol table #options SYSCALL_STATS # per syscall counts #options SYSCALL_TIMES # per syscall times #options SYSCALL_TIMES_HASCOUNTER # use 'broken' rdtsc (soekris) Index: sys/arch/i386/conf/XEN3_DOM0 =================================================================== RCS file: /cvsroot/src/sys/arch/i386/conf/XEN3_DOM0,v retrieving revision 1.71 diff -u -p -r1.71 XEN3_DOM0 --- sys/arch/i386/conf/XEN3_DOM0 17 Oct 2012 14:48:13 -0000 1.71 +++ sys/arch/i386/conf/XEN3_DOM0 25 Oct 2012 14:05:53 -0000 @@ -184,12 +184,13 @@ options SCSIVERBOSE # human readable SC #options USBVERBOSE # verbose USB device autoconfig messages options NFS_BOOT_DHCP,NFS_BOOT_BOOTPARAM -#options NFS_BOOT_BOOTSTATIC +options NFS_BOOT_BOOTSTATIC #options NFS_BOOTSTATIC_MYIP="\"169.254.1.2\"" #options NFS_BOOTSTATIC_GWIP="\"169.254.1.1\"" #options NFS_BOOTSTATIC_MASK="\"255.255.255.0\"" #options NFS_BOOTSTATIC_SERVADDR="\"169.254.1.1\"" #options NFS_BOOTSTATIC_SERVER="\"server:/path/to/root\"" +options NFS_BOOT_RWSIZE=8192 options WSEMUL_VT100 # VT100 / VT220 emulation options WS_KERNEL_FG=WSCOL_GREEN @@ -847,6 +848,10 @@ options MPBIOS #options PCI_BUS_FIXUP # fixup PCI bus numbering #options PCI_INTR_FIXUP # fixup PCI interrupt routing +options LOCKDEBUG +options VNODE_LOCKDEBUG +options MALLOC_DEBUG +options UVMHIST ioapic* at mainbus? apid ? # ACPI devices Index: sys/arch/i386/i386/mainbus.c =================================================================== RCS file: /cvsroot/src/sys/arch/i386/i386/mainbus.c,v retrieving revision 1.96 diff -u -p -r1.96 mainbus.c --- sys/arch/i386/i386/mainbus.c 30 Sep 2012 20:54:52 -0000 1.96 +++ sys/arch/i386/i386/mainbus.c 25 Oct 2012 14:05:53 -0000 @@ -69,6 +69,8 @@ __KERNEL_RCSID(0, "$NetBSD: mainbus.c,v #if NACPICA > 0 #include +#include +#include #endif #if NMCA > 0 @@ -215,6 +217,9 @@ mainbus_attach(device_t parent, device_t #if defined(PCI_BUS_FIXUP) int pci_maxbus = 0; #endif +#if NACPICA > 0 + int rc; +#endif int numcpus = 0; sc->sc_dev = self; @@ -253,8 +258,30 @@ mainbus_attach(device_t parent, device_t * Building the interrupt routing structures can only * be done later (via a callback). */ - if (sc->sc_acpi_present) + if (sc->sc_acpi_present) { sc->sc_mpacpi_active = mpacpi_scan_apics(self, &numcpus) != 0; + if (!acpisrat_exist()) { + aprint_error_dev(self, "ACPI SRAT table not present\n"); + } else { + if ((rc = acpisrat_init()) != 0) + aprint_error_dev(self, + "ACPI SRAT initialization failed, rc: %i\n", + rc); + else + acpisrat_dump(); + } + + if (!acpislit_exist()) { + aprint_error_dev(self, "ACPI SLIT table not present\n"); + } else { + if ((rc = acpislit_init()) != 0) + aprint_error_dev(self, + "ACPI SLIT initialization failed, rc: %i\n", + rc); + else + acpislit_dump(); + } + } #endif if (!sc->sc_mpacpi_active) { Index: sys/arch/i386/include/frameasm.h =================================================================== RCS file: /cvsroot/src/sys/arch/i386/include/frameasm.h,v retrieving revision 1.15 diff -u -p -r1.15 frameasm.h --- sys/arch/i386/include/frameasm.h 26 Jul 2011 12:57:35 -0000 1.15 +++ sys/arch/i386/include/frameasm.h 25 Oct 2012 14:05:53 -0000 @@ -25,6 +25,9 @@ #define STIC(reg) movl CPUVAR(VCPU),reg ; \ XEN_UNBLOCK_EVENTS(reg) ; \ testb $0xff,EVTCHN_UPCALL_PENDING(reg) + +#define HYPERVISOR_iret hypercall_page + (__HYPERVISOR_iret * 32) +//#define iret pushl $0 ; jmp HYPERVISOR_iret #endif #ifndef TRAPLOG Index: sys/arch/x86/include/Makefile =================================================================== RCS file: /cvsroot/src/sys/arch/x86/include/Makefile,v retrieving revision 1.17 diff -u -p -r1.17 Makefile --- sys/arch/x86/include/Makefile 29 Aug 2012 17:13:22 -0000 1.17 +++ sys/arch/x86/include/Makefile 25 Oct 2012 14:05:57 -0000 @@ -9,6 +9,7 @@ INCS= aout_machdep.h \ cpu_ucode.h \ cputypes.h \ cpuvar.h \ + errata.h \ float.h \ ieee.h ieeefp.h \ intr.h intrdefs.h \ Index: sys/arch/x86/include/errata.h =================================================================== RCS file: sys/arch/x86/include/errata.h diff -N sys/arch/x86/include/errata.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/x86/include/errata.h 25 Oct 2012 14:05:57 -0000 @@ -0,0 +1,85 @@ +/* $NetBSD: $ */ + +/* + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Advanced Micro Devices, Inc.. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _X86_ERRATA_H +#define _X86_ERRATA_H + +#include + +/* AMD errata checking + * + * Errata are defined using the AMD_LEGACY_ERRATUM() or AMD_OSVW_ERRATUM() + * macros. The latter is intended for newer errata that have an OSVW id + * assigned, which it takes as first argument. Both take a variable number + * of family-specific model-stepping ranges created by AMD_MODEL_RANGE(). + * + * Example 1: + * #define AMD_ERRATUM_319 \ + * AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0x4, 0x2), \ + * AMD_MODEL_RANGE(0x10, 0x8, 0x0, 0x8, 0x0), \ + * AMD_MODEL_RANGE(0x10, 0x9, 0x0, 0x9, 0x0)) + * Example 2: + * #define AMD_ERRATUM_400 \ + * AMD_OSVW_ERRATUM(1, AMD_MODEL_RANGE(0xf, 0x41, 0x2, 0xff, 0xf), \ + * AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0xff, 0xf)) + * + */ + +#define AMD_LEGACY_ERRATUM(...) 0 /* legacy */, __VA_ARGS__, 0 +#define AMD_OSVW_ERRATUM(osvw_id, ...) 1 /* osvw */, osvw_id, __VA_ARGS__, 0 +#define AMD_MODEL_RANGE(f, m_start, s_start, m_end, s_end) \ + ((f << 24) | (m_start << 16) | (s_start << 12) | (m_end << 4) | (s_end)) +#define AMD_MODEL_RANGE_FAMILY(range) (((range) >> 24) & 0xff) +#define AMD_MODEL_RANGE_START(range) (((range) >> 12) & 0xfff) +#define AMD_MODEL_RANGE_END(range) ((range) & 0xfff) + +#define X86_AMD_ERRATUM_86 \ + AMD_LEGACY_ERRATUM( \ + /* SH_B3 */ AMD_MODEL_RANGE(0x0f, 0x5, 0x1, 0x5, 0x1), \ + /* SH_C0 */ AMD_MODEL_RANGE(0x0f, 0x4, 0x8, 0x5, 0x8), \ + /* SH_CG */ AMD_MODEL_RANGE(0x0f, 0x4, 0xa, 0x7, 0xa), \ + /* CH_CG */ AMD_MODEL_RANGE(0x0f, 0x8, 0x2, 0xb, 0x2), \ + /* DH_CG */ AMD_MODEL_RANGE(0x0f, 0xc, 0x0, 0xf, 0x0)) + +#define X86_AMD_ERRATUM_81 \ + AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x0f, 0x5, 0x1, 0x5, 0x1)) + +#define X86_AMD_ERRATUM_400 \ + AMD_OSVW_ERRATUM(1, AMD_MODEL_RANGE(0xf, 0x41, 0x2, 0xff, 0xf), \ + AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0xff, 0xf)) + +/* + * Check for the presence of an AMD erratum. Arguments are in + * errata.h for each known erratum. Return true if erratum is found. + */ +bool x86_amd_errata(const struct cpu_info *, int, ...); + +#endif /* _X86_ERRATA_H */ Index: sys/arch/x86/include/intrdefs.h =================================================================== RCS file: /cvsroot/src/sys/arch/x86/include/intrdefs.h,v retrieving revision 1.17 diff -u -p -r1.17 intrdefs.h --- sys/arch/x86/include/intrdefs.h 6 Nov 2011 11:40:47 -0000 1.17 +++ sys/arch/x86/include/intrdefs.h 25 Oct 2012 14:05:57 -0000 @@ -13,7 +13,8 @@ #define IPL_VM 0x6 /* low I/O, memory allocation */ #define IPL_SCHED 0x7 /* medium I/O, scheduler, clock */ #define IPL_HIGH 0x8 /* high I/O, statclock, IPIs */ -#define NIPL 9 +#define IPL_MCA 0x9 /* machine check */ +#define NIPL 10 /* Interrupt sharing types. */ #define IST_NONE 0 /* none */ Index: sys/arch/x86/include/pte.h =================================================================== RCS file: /cvsroot/src/sys/arch/x86/include/pte.h,v retrieving revision 1.1 diff -u -p -r1.1 pte.h --- sys/arch/x86/include/pte.h 6 Jul 2010 20:50:35 -0000 1.1 +++ sys/arch/x86/include/pte.h 25 Oct 2012 14:05:57 -0000 @@ -34,10 +34,15 @@ /* Cacheability bits when we are using PAT */ #define PGC_WB 0 /* The default */ -#define PGC_WC PG_WT /* WT and CD is WC */ #define PGC_UCMINUS PG_N /* UC but mtrr can override */ #define PGC_UC (PG_WT | PG_N) /* hard UC */ +#ifdef XEN +#define PGC_WC (PG_PAT | PG_N) /* WT and CD is WC */ +#else +#define PGC_WC PG_WT /* WT and CD is WC */ +#endif + /* * page protection exception bits */ Index: sys/arch/x86/include/specialreg.h =================================================================== RCS file: /cvsroot/src/sys/arch/x86/include/specialreg.h,v retrieving revision 1.60 diff -u -p -r1.60 specialreg.h --- sys/arch/x86/include/specialreg.h 17 Oct 2012 16:13:01 -0000 1.60 +++ sys/arch/x86/include/specialreg.h 25 Oct 2012 14:05:57 -0000 @@ -226,11 +226,12 @@ #define CPUID_AMD_SVM_FlushByASID 0x00000040 #define CPUID_AMD_SVM_DecodeAssist 0x00000080 #define CPUID_AMD_SVM_PauseFilter 0x00000400 +#define CPUID_AMD_SVM_PauseFilterThres 0x00001000 #define CPUID_AMD_SVM_FLAGS "\20\1NP\2LbrVirt\3SVML\4NRIPS" \ "\5TSCRate\6VMCBCleanBits\7FlushByASID" \ "\10DecodeAssist\11B08" \ "\12B09\13PauseFilter" \ - "\14B11\15B12" \ + "\14B11\15PauseFilterThreshold" \ "\16B13\17B17\20B18\21B19" /* Index: sys/arch/x86/include/x86_mcheck.h =================================================================== RCS file: sys/arch/x86/include/x86_mcheck.h diff -N sys/arch/x86/include/x86_mcheck.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/x86/include/x86_mcheck.h 25 Oct 2012 14:05:57 -0000 @@ -0,0 +1,60 @@ +/* $NetBSD: $ */ +/* + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christoph Egger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _X86_MCHECK_H_ +#define _X86_MCHECK_H_ + +#include +#include + +struct mcheck_softc; + +struct mcheck_cache { + uint64_t mc_addr; + uint64_t mc_status; +}; + +void mcheck_init(void); +void mcheck_exit(void); + +struct mcheck_softc *mcheck_create(device_t); +void mcheck_destroy(struct mcheck_softc *); + +int mcheck_register_cache(device_t, + bool (*cache_check)(void *, struct mcheck_cache *), + int (*cache_recover)(void *, struct mcheck_cache *), void *, void *); + +int mcheck_recover_cache(device_t, struct mcheck_cache *); + +#ifdef DEBUG +device_t mcheck_get_northbridge(int); +#endif + +#endif Index: sys/arch/x86/include/x86_mcheckreg.h =================================================================== RCS file: sys/arch/x86/include/x86_mcheckreg.h diff -N sys/arch/x86/include/x86_mcheckreg.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/x86/include/x86_mcheckreg.h 25 Oct 2012 14:05:57 -0000 @@ -0,0 +1,103 @@ +/* $NetBSD: $ */ +/* + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christoph Egger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _X86_MCHECKREG_H_ +#define _X86_MCHECKREG_H_ + +/* Definitions unique to x86 machine check support */ + +/* Bitfield of the MSR_MCG_CAP register */ +#define MCG_CAP_COUNT 0x00000000000000ffULL +#define MCG_CTL_P 0x0000000000000100ULL +/* Other bits are reserved */ + +/* Bitfield of the MSR_MCG_STATUS register */ +#define MCG_STATUS_RIPV 0x0000000000000001ULL +#define MCG_STATUS_EIPV 0x0000000000000002ULL +#define MCG_STATUS_MCIP 0x0000000000000004ULL +/* Other bits are reserved */ + +/* Bitfield of the MSR_MCi_STATUS registers */ +/* MCA error code */ +#define MCi_STATUS_MCA 0x000000000000ffffULL +/* model-specific error code */ +#define MCi_STATUS_MSEC 0x00000000ffff0000ULL +/* Other information */ +#define MCi_STATUS_OTHER 0x01ffffff00000000ULL +/* processor context corrupt */ +#define MCi_STATUS_PCC 0x0200000000000000ULL +/* MSR_MCi_ADDR register valid */ +#define MCi_STATUS_ADDRV 0x0400000000000000ULL +/* MSR_MCi_MISC register valid */ +#define MCi_STATUS_MISCV 0x0800000000000000ULL +/* error condition enabled */ +#define MCi_STATUS_EN 0x1000000000000000ULL +/* uncorrected error */ +#define MCi_STATUS_UC 0x2000000000000000ULL +/* status register overflow */ +#define MCi_STATUS_OVER 0x4000000000000000ULL +/* valid */ +#define MCi_STATUS_VAL 0x8000000000000000ULL + +/* AMD specific bitfields of the MSR_MCi_STATUS registers */ +/* ECC Syndrome bits 15:8 */ +#define MCi_AMD_STATUS_SYNDROME_H 0x00000000ff000000ULL +/* DRAM Scrubber */ +#define MCi_AMD_STATUS_SCRUB 0x0000010000000000ULL +/* McaStatSubCache - L3 Cache */ +#define MCi_AMD_STATUS_L3SUBCACHE 0x0000020000000000ULL +/* SubLink */ +#define MCi_AMD_STATUS_SUBLINK 0x00000c0000000000ULL +/* */ +/* ErrCPU */ +#define MCi_AMD_STATUS_ERRCPU 0x0000000f00000000ULL + +/* AMD specific ErrorCodeExt field */ +#define MC_AMD_ERREXT_CRC 0x1 /* CRC Error */ +#define MC_AMD_ERREXT_SYNC 0x2 /* Sync Error */ +#define MC_AMD_ERREXT_MSTABORT 0x3 /* Master Abort */ +#define MC_AMD_ERREXT_TGTABORT 0x4 /* Target Abort */ +#define MC_AMD_ERREXT_GART 0x5 /* GART Error */ +#define MC_AMD_ERREXT_RMW 0x6 /* RMW Error */ +#define MC_AMD_ERREXT_WDT 0x7 /* WDT Error */ +#define MC_AMD_ERREXT_ECC 0x8 /* ECC Error */ +#define MC_AMD_ERREXT_LINKDATA 0xa /* Link Data Error */ +#define MC_AMD_ERREXT_PROTO 0xb /* Protocol Error */ +#define MC_AMD_ERREXT_NBARRAY 0xc /* NB Array Error */ +#define MC_AMD_ERREXT_DRAMPARITY 0xd /* DRAM Parity Error */ +#define MC_AMD_ERREXT_LINKRETRY 0xe /* Link Retry */ +#define MC_AMD_ERREXT_GARTTABLE 0xf /* GART Table Walk Data Error */ +#define MC_AMD_ERREXT_COMPUNIT 0x19 /* Compute Unit Data Error */ +#define MC_AMD_ERREXT_L3DATA 0x1c /* L3 Cache Data Error */ +#define MC_AMD_ERREXT_L3TAG 0x1d /* L3 Cache Tag Error */ +#define MC_AMD_ERREXT_L3LRU 0x1e /* L3 Cache LRU Error */ +#define MC_AMD_ERREXT_PROBEFLT 0x1f /* Probe Filter Error */ + +#endif Index: sys/arch/x86/pci/amdnb_l3disable.c =================================================================== RCS file: sys/arch/x86/pci/amdnb_l3disable.c diff -N sys/arch/x86/pci/amdnb_l3disable.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/x86/pci/amdnb_l3disable.c 25 Oct 2012 14:05:57 -0000 @@ -0,0 +1,240 @@ +/* $NetBSD: $ */ +/* + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christoph Egger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD: $"); + +#include +#include + +#include + +#include +#include +#include + +#include +#include + +static int amdnb_l3dis_match(device_t, cfdata_t match, void *); +static void amdnb_l3dis_attach(device_t, device_t, void *); +static int amdnb_l3dis_detach(device_t, int); + +struct amdnb_l3dis_softc { + device_t sc_dev; + pci_chipset_tag_t sc_pc; + pcitag_t sc_tag; + struct mcheck_softc *sc_mc; +}; + +CFATTACH_DECL_NEW(amdnb_l3dis, sizeof(struct amdnb_l3dis_softc), + amdnb_l3dis_match, amdnb_l3dis_attach, amdnb_l3dis_detach, NULL); + +/* Function 3 Registers */ +#define PCI_NB_L3CACHE_DISABLE0 0x1bc +#define PCI_NB_L3CACHE_DISABLE1 0x1c0 +#define NORTHBRIDGE_CAP_R 0xe8 +#define CPUID_FAMILY_MODEL_R 0xfc + +static bool amdnb_l3cache_check(void *, struct mcheck_cache *); +static int amdnb_l3cache_recover(void *, struct mcheck_cache *); + +static int +amdnb_l3dis_match(device_t parent, cfdata_t match, void *aux) +{ + struct pci_attach_args *pa = aux; + pcireg_t cpu_signature; + pcireg_t data; + uint32_t family; + uint32_t l3present; + + /* amdnb_misc should guarantee this */ + KASSERT(PCI_VENDOR(pa->pa_id) == PCI_VENDOR_AMD); + + cpu_signature = pci_conf_read(pa->pa_pc, + pa->pa_tag, CPUID_FAMILY_MODEL_R); + + family = CPUID2FAMILY(cpu_signature); + if (family == 0xf) + family += CPUID2EXTFAMILY(cpu_signature); + + /* L3 cache index disable got introduced in family 0x10 */ + if (family < 0x10) + return 0; + + data = pci_conf_read(pa->pa_pc, pa->pa_tag, NORTHBRIDGE_CAP_R); + l3present = (data >> 25); + if (!l3present) + return 0; + + /* Errata 382: This has been fixed in Revision D0. */ + if (family == 0x10 && CPUID2MODEL(cpu_signature) < 8) + return 0; + + return 1; +} + +static void +amdnb_l3dis_attach(device_t parent, device_t self, void *aux) +{ + struct amdnb_l3dis_softc *sc = device_private(self); + struct pci_attach_args *pa = aux; + int rc; + + sc->sc_dev = self; + sc->sc_pc = pa->pa_pc; + sc->sc_tag = pa->pa_tag; + + aprint_naive("\n"); + aprint_normal(": AMD NB L3 cache index disable\n"); + + if (!pmf_device_register(self, NULL, NULL)) + aprint_error_dev(self, "couldn't establish power handler\n"); + + sc->sc_mc = mcheck_create(self); + if (sc->sc_mc == NULL) { + aprint_error_dev(self, "mcheck_create failed\n"); + return; + } + + rc = mcheck_register_cache(self, amdnb_l3cache_check, + amdnb_l3cache_recover, sc, sc); + if (rc) { + aprint_error_dev(self, "mcheck_register_cache failed\n"); + goto err0; + } + + return; + +err0: + mcheck_destroy(sc->sc_mc); + return; +} + +static int +amdnb_l3dis_detach(device_t self, int flags) +{ + struct amdnb_l3dis_softc *sc = device_private(self); + pmf_device_deregister(self); + mcheck_destroy(sc->sc_mc); + return 0; +} + + +static bool +amdnb_l3cache_check(void *arg, struct mcheck_cache *cache) +{ + switch ((cache->mc_status & MCi_STATUS_MSEC) >> 16) { + case MC_AMD_ERREXT_L3DATA: + printf_nolog("l3cache: Data Error detected\n"); + return 1; + case MC_AMD_ERREXT_L3TAG: + printf_nolog("l3cache: Tag Error detected\n"); + return 1; + case MC_AMD_ERREXT_L3LRU: + printf_nolog("l3cache: LRU Error detected\n"); + return 1; + default: + printf_nolog("%s: status 0x%"PRIx64"/0x%"PRIx64"/0x%"PRIx64"\n", + __func__, cache->mc_status, + (uint64_t)(cache->mc_status & MCi_STATUS_MSEC), + (uint64_t)((cache->mc_status & MCi_STATUS_MSEC) >> 16)); + return 0; + } +} + +static int +amdnb_l3cache_recover(void *arg, struct mcheck_cache *cache) +{ + /* Must run on a core on the same node as the target l3 cache. */ + struct amdnb_l3dis_softc *sc = arg; + int reg = PCI_NB_L3CACHE_DISABLE0; + pcireg_t val; + uint32_t subcache; + uint32_t cacheline; + +#define L3CACHE_ADDR_CACHEINDEX(addr) (((addr) >> 6) & 0x7ff) + + subcache = (cache->mc_status & MCi_AMD_STATUS_L3SUBCACHE) >> 42; + cacheline = L3CACHE_ADDR_CACHEINDEX(cache->mc_addr); + +#define L3CACHE_INDEX_READ_DISABLE (1U << 31) +#define L3CACHE_INDEX_ALLOC_DISABLE (1U << 30) +#define L3CACHE_INDEX_SUBCACHE(subcache) ((subcache) << 20) +#define L3CACHE_PCI_SUBCACHE(subcache) (((subcache) >> 20) & 0x3U) +#define L3CACHE_INDEX_CACHELINE(cacheline) ((cacheline) & 0xfff) + + for (;;) { + val = pci_conf_read(sc->sc_pc, sc->sc_tag, reg); + + /* This index is already disabled? */ + if ((L3CACHE_PCI_SUBCACHE(val) == subcache) + && (L3CACHE_INDEX_CACHELINE(val) == cacheline)) + return 0; /* .. in this case return success. */ + + if ((val & L3CACHE_INDEX_ALLOC_DISABLE) + && (val & L3CACHE_INDEX_READ_DISABLE)) + { + /* L3 Cache Index specified by PCI_NB_L3CACHE_DISABLE0 + * is already disabled. + * Switch to PCI_NB_L3CACHE_DISABLE1. + */ + + /* We can only disable two cache indeces, just one + * with each register. */ + if (reg == PCI_NB_L3CACHE_DISABLE1) + return EIO; + reg = PCI_NB_L3CACHE_DISABLE1; + continue; + } + break; + } + + val &= ~L3CACHE_INDEX_READ_DISABLE; + val |= L3CACHE_INDEX_ALLOC_DISABLE + | L3CACHE_INDEX_SUBCACHE(subcache) + | L3CACHE_INDEX_CACHELINE(cacheline); + + pci_conf_write(sc->sc_pc, sc->sc_tag, reg, val); + + wbinvd(); + + val |= (L3CACHE_INDEX_ALLOC_DISABLE | L3CACHE_INDEX_READ_DISABLE); + + pci_conf_write(sc->sc_pc, sc->sc_tag, reg, val); + + val = pci_conf_read(sc->sc_pc, sc->sc_tag, reg); + + if (!(val & L3CACHE_INDEX_ALLOC_DISABLE)) + return EIO; + if (!(val & L3CACHE_INDEX_READ_DISABLE)) + return EIO; + return 0; +} Index: sys/arch/x86/pci/amdnb_mcheck.c =================================================================== RCS file: sys/arch/x86/pci/amdnb_mcheck.c diff -N sys/arch/x86/pci/amdnb_mcheck.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/x86/pci/amdnb_mcheck.c 25 Oct 2012 14:05:57 -0000 @@ -0,0 +1,229 @@ +/* $NetBSD: $ */ +/* + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christoph Egger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD: $"); + +#include +#include + +#include + +#include +#include +#include + +#include +#include + +static int amdnb_mcheck_match(device_t, cfdata_t match, void *); +static void amdnb_mcheck_attach(device_t, device_t, void *); +static int amdnb_mcheck_detach(device_t, int); + +struct amdnb_mcheck_softc { + device_t sc_dev; + pci_chipset_tag_t sc_pc; + pcitag_t sc_tag; + struct mcheck_softc *sc_mc; +}; + +CFATTACH_DECL_NEW(amdnb_mcheck, sizeof(struct amdnb_mcheck_softc), + amdnb_mcheck_match, amdnb_mcheck_attach, amdnb_mcheck_detach, NULL); + +#define PCI_NB_L3CACHE_DISABLE0 0x1BC +#define PCI_NB_L3CACHE_DISABLE1 0x1D0 + +static bool amdnb_l3cache_check(void *, struct mcheck_cache *); +static int amdnb_mcheck_l3cache_recover(void *, struct mcheck_cache *); + +static int +amdnb_mcheck_match(device_t parent, cfdata_t match, void *aux) +{ + struct pci_attach_args *pa = aux; + + if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_AMD) + return 0; + + switch (PCI_PRODUCT(pa->pa_id)) { + case PCI_PRODUCT_AMD_AMD64_MISC: + case PCI_PRODUCT_AMD_AMD64_F10_MISC: + case PCI_PRODUCT_AMD_AMD64_F11_MISC: + case PCI_PRODUCT_AMD_F14_NB: + break; + default: + return 0; + } + + return 2; /* supercede pchb(4) */ +} + +static bool +amdnb_mcheck_suspend(device_t self, const pmf_qual_t *qual) +{ + return true; +} + +static bool +amdnb_mcheck_resume(device_t self, const pmf_qual_t *qual) +{ + return true; +} + +static void +amdnb_mcheck_attach(device_t parent, device_t self, void *aux) +{ + struct amdnb_mcheck_softc *sc = device_private(self); + struct pci_attach_args *pa = aux; + int rc; + + sc->sc_dev = self; + sc->sc_pc = pa->pa_pc; + sc->sc_tag = pa->pa_tag; + + aprint_naive("\n"); + aprint_normal(": AMD NB Machine Check Support\n"); + + if (!pmf_device_register(self, amdnb_mcheck_suspend, amdnb_mcheck_resume)) + aprint_error_dev(self, "couldn't establish power handler\n"); + + sc->sc_mc = mcheck_create(self); + if (sc->sc_mc == NULL) { + aprint_error_dev(self, "mcheck_create failed\n"); + return; + } + + rc = mcheck_register_cache(self, amdnb_l3cache_check, + amdnb_mcheck_l3cache_recover, sc, sc); + if (rc) { + aprint_error_dev(self, "mcheck_register_cache failed\n"); + goto err0; + } + + return; + +err0: + mcheck_destroy(sc->sc_mc); + return; +} + +static int +amdnb_mcheck_detach(device_t self, int flags) +{ + struct amdnb_mcheck_softc *sc = device_private(self); + pmf_device_deregister(self); + mcheck_destroy(sc->sc_mc); + return 0; +} + + +static bool +amdnb_l3cache_check(void *arg, struct mcheck_cache *cache) +{ + switch ((cache->mc_status & MCi_STATUS_MSEC) >> 16) { + case MC_AMD_ERREXT_L3DATA: + printf_nolog("l3cache: Data Error detected\n"); + return 1; + case MC_AMD_ERREXT_L3TAG: + printf_nolog("l3cache: Tag Error detected\n"); + return 1; + case MC_AMD_ERREXT_L3LRU: + printf_nolog("l3cache: LRU Error detected\n"); + return 1; + default: + printf_nolog("%s: status 0x%"PRIx64"/0x%"PRIx64"/0x%"PRIx64"\n", + __func__, cache->mc_status, + (uint64_t)(cache->mc_status & MCi_STATUS_MSEC), + (uint64_t)((cache->mc_status & MCi_STATUS_MSEC) >> 16)); + return 0; + } +} + +static int +amdnb_mcheck_l3cache_recover(void *arg, struct mcheck_cache *cache) +{ + /* Must run on a core on the same node as the target l3 cache. */ + struct amdnb_mcheck_softc *sc = arg; + int reg = PCI_NB_L3CACHE_DISABLE0; + pcireg_t val; + uint32_t subcache; + uint32_t cacheline; + +#define L3CACHE_ADDR_CACHEINDEX(addr) (((addr) >> 6) & 0x7ff) + + subcache = (cache->mc_status & MCi_AMD_STATUS_L3SUBCACHE) >> 42; + cacheline = L3CACHE_ADDR_CACHEINDEX(cache->mc_addr); + + printf_nolog("%s: subcache: 0x%x, cache index: 0x%x\n", + __func__, subcache, cacheline); + + for (;;) { + val = pci_conf_read(sc->sc_pc, sc->sc_tag, reg); + +#define L3CACHE_INDEX_ALLOC_DISABLE (1U << 31) +#define L3CACHE_INDEX_READ_DISABLE (1U << 30) +#define L3CACHE_INDEX_SUBCACHE(subcache) ((subcache) << 20) +#define L3CACHE_INDEX_CACHELINE(cacheline) ((cacheline) & 0xfff) + + if ((val & L3CACHE_INDEX_ALLOC_DISABLE) + && (val & L3CACHE_INDEX_READ_DISABLE)) + { + /* L3 Cache Index specified by PCI_NB_L3CACHE_DISABLE0 + * is already disabled. + * Switch to PCI_NB_L3CACHE_DISABLE1. + */ + + /* We can only disable two cache indeces, just one + * with each register. */ + if (reg == PCI_NB_L3CACHE_DISABLE1) + return EIO; + reg = PCI_NB_L3CACHE_DISABLE1; + continue; + } + break; + } + + val &= ~L3CACHE_INDEX_READ_DISABLE; + val |= L3CACHE_INDEX_ALLOC_DISABLE + | L3CACHE_INDEX_SUBCACHE(subcache) + | L3CACHE_INDEX_CACHELINE(cacheline); + + pci_conf_write(sc->sc_pc, sc->sc_tag, reg, val); + + wbinvd(); + + val |= (L3CACHE_INDEX_ALLOC_DISABLE | L3CACHE_INDEX_READ_DISABLE); + + pci_conf_write(sc->sc_pc, sc->sc_tag, reg, val); + + val = pci_conf_read(sc->sc_pc, sc->sc_tag, reg); + if (!(val & L3CACHE_INDEX_READ_DISABLE)) + return EIO; + return 0; +} Index: sys/arch/x86/pci/amdnb_misc.c =================================================================== RCS file: /cvsroot/src/sys/arch/x86/pci/amdnb_misc.c,v retrieving revision 1.2 diff -u -p -r1.2 amdnb_misc.c --- sys/arch/x86/pci/amdnb_misc.c 16 Apr 2012 16:07:24 -0000 1.2 +++ sys/arch/x86/pci/amdnb_misc.c 25 Oct 2012 14:05:57 -0000 @@ -75,41 +75,38 @@ amdnb_misc_match(device_t parent, cfdata return 2; /* supercede pchb(4) */ } -static int -amdnb_misc_search(device_t parent, cfdata_t cf, const int *locs, void *aux) +static bool +device_is_attached(device_t parent, cfdata_t cf) { device_t dev; deviter_t di; - bool attach; - - if (!config_match(parent, cf, aux)) - return 0; - - attach = true; + bool attached = false; - /* Figure out if found child 'cf' is already attached. - * No need to attach it twice. - */ - - /* XXX: I only want to iterate over the children of *this* device. - * Can we introduce a - * deviter_first_child(&di, parent, DEVITER_F_LEAVES_ONLY) - * or even better, can we introduce a query function that returns - * if a child is already attached? - */ for (dev = deviter_first(&di, DEVITER_F_LEAVES_FIRST); dev != NULL; - dev = deviter_next(&di)) + dev = deviter_next(&di)) { if (device_parent(dev) != parent) - continue; + continue; if (device_is_a(dev, cf->cf_name)) { - attach = false; + attached = true; break; } } deviter_release(&di); - if (!attach) + return attached; +} + +static int +amdnb_misc_search(device_t parent, cfdata_t cf, const int *locs, void *aux) +{ + if (!config_match(parent, cf, aux)) + return 0; + + /* Figure out if found child 'cf' is already attached. + * No need to attach it twice. + */ + if (device_is_attached(parent, cf)) return 0; config_attach_loc(parent, cf, locs, aux, NULL); Index: sys/arch/x86/pci/files.pci =================================================================== RCS file: /cvsroot/src/sys/arch/x86/pci/files.pci,v retrieving revision 1.14 diff -u -p -r1.14 files.pci --- sys/arch/x86/pci/files.pci 13 Apr 2012 13:11:17 -0000 1.14 +++ sys/arch/x86/pci/files.pci 25 Oct 2012 14:05:57 -0000 @@ -37,6 +37,10 @@ device amdtemp: sysmon_envsys attach amdtemp at amdnb_miscbus file arch/x86/pci/amdtemp.c amdtemp +device amdnb_l3dis +attach amdnb_l3dis at amdnb_miscbus +file arch/x86/pci/amdnb_l3disable.c amdnb_l3dis + # PCI-LPC bridges device rdcpcib: isabus, sysmon_wdog attach rdcpcib at pci Index: sys/arch/x86/x86/errata.c =================================================================== RCS file: /cvsroot/src/sys/arch/x86/x86/errata.c,v retrieving revision 1.20 diff -u -p -r1.20 errata.c --- sys/arch/x86/x86/errata.c 6 Apr 2012 17:23:39 -0000 1.20 +++ sys/arch/x86/x86/errata.c 25 Oct 2012 14:05:57 -0000 @@ -53,9 +53,11 @@ __KERNEL_RCSID(0, "$NetBSD: errata.c,v 1 #include #include #include +#include #include #include +#include typedef struct errata { u_short e_num; @@ -287,6 +289,66 @@ static errata_t errata[] = { }, }; +bool +x86_amd_errata(const struct cpu_info *ci, int osvw, ...) +{ + va_list ap; + uint32_t range, ms; + + uint32_t family; + uint16_t model, stepping; + + if (cpu_vendor != CPUVENDOR_AMD) + return false; + + family = CPUID2FAMILY(ci->ci_signature); + if (family == 0xf) + family += CPUID2EXTFAMILY(ci->ci_signature); + + model = CPUID2MODEL(ci->ci_signature); + if (model == 0xf) + model += CPUID2EXTMODEL(ci->ci_signature); + + stepping = CPUID2STEPPING(ci->ci_signature); + + va_start(ap, osvw); + + if (osvw) { + uint64_t osvw_len, osvw_bits; + uint16_t osvw_id = va_arg(ap, int); + + if (cpu_feature[3] & CPUID_OSVW) { + printf("checkpoint OSVW\n"); + osvw_len = rdmsr(MSR_OSVW_ID_LENGTH); + if (osvw_id < osvw_len) { + unsigned int msr; + + msr = MSR_OSVW_STATUS + (osvw_id >> 6); + osvw_bits = rdmsr(msr); + + va_end(ap); + return (osvw_bits >> (osvw_id & 0x3f)) & 0x01; + } + } + } + + printf("checkpoint legacy\n"); + /* OSVW unavailable or ID unknown, match family-model-stepping range */ + ms = (model << 4) | stepping; + while ((range = va_arg(ap, int))) { + if ((family == AMD_MODEL_RANGE_FAMILY(range)) && + (ms >= AMD_MODEL_RANGE_START(range)) && + (ms <= AMD_MODEL_RANGE_END(range))) + { + va_end(ap); + return true; + } + } + + va_end(ap); + return false; +} + static bool x86_errata_testmsr(struct cpu_info *ci, errata_t *e) { Index: sys/arch/x86/x86/ioapic.c =================================================================== RCS file: /cvsroot/src/sys/arch/x86/x86/ioapic.c,v retrieving revision 1.47 diff -u -p -r1.47 ioapic.c --- sys/arch/x86/x86/ioapic.c 30 Jan 2012 17:45:37 -0000 1.47 +++ sys/arch/x86/x86/ioapic.c 25 Oct 2012 14:05:57 -0000 @@ -342,7 +342,7 @@ ioapic_attach(device_t parent, device_t sc->sc_pins = malloc(sizeof(struct ioapic_pin) * sc->sc_apic_sz, M_DEVBUF, M_WAITOK); - for (i=0; isc_apic_sz; i++) { + for (i = 0; i < sc->sc_apic_sz; i++) { uint32_t redlo, redhi; sc->sc_pins[i].ip_next = NULL; Index: sys/arch/x86/x86/x86_mcheck.c =================================================================== RCS file: sys/arch/x86/x86/x86_mcheck.c diff -N sys/arch/x86/x86/x86_mcheck.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/x86/x86/x86_mcheck.c 25 Oct 2012 14:05:57 -0000 @@ -0,0 +1,181 @@ +/* $NetBSD: $ */ +/* + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christoph Egger. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD: $"); + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + + +struct mcheck_funcs { + int (*mc_cache_decode)(void *, uint32_t *, uint32_t *); + bool (*mc_cache_check)(void *, struct mcheck_cache *); + int (*mc_cache_recover)(void *, struct mcheck_cache *); + + void *mc_arg_check; + void *mc_arg_recover; +}; + +struct mcheck_softc { + struct cpu_info *mc_ci; + device_t mc_dev; + + TAILQ_ENTRY(mcheck_softc) mc_entry; + struct mcheck_funcs mc_funcs; +}; + +static TAILQ_HEAD(, mcheck_softc) mcheck_devs; + +void +mcheck_init(void) +{ + TAILQ_INIT(&mcheck_devs); +} + +void +mcheck_exit(void) +{ + struct mcheck_softc *sc_entry; + while (!TAILQ_EMPTY(&mcheck_devs)) { + sc_entry = TAILQ_FIRST(&mcheck_devs); + TAILQ_REMOVE(&mcheck_devs, sc_entry, mc_entry); + kmem_free(sc_entry, sizeof(struct mcheck_softc)); + } +} + +struct mcheck_softc * +mcheck_create(device_t self) +{ + struct mcheck_softc *mc_sc; + + mc_sc = kmem_zalloc(sizeof(struct mcheck_softc), KM_NOSLEEP); + if (mc_sc == NULL) + return NULL; + + TAILQ_INSERT_TAIL(&mcheck_devs, mc_sc, mc_entry); + mc_sc->mc_dev = self; + + return mc_sc; +} + +void +mcheck_destroy(struct mcheck_softc *mc) +{ + TAILQ_REMOVE(&mcheck_devs, mc, mc_entry); + kmem_free(mc, sizeof(struct mcheck_softc)); +} + +static struct mcheck_softc * +mcheck_dev2sc(device_t self) +{ + struct mcheck_softc *mc_sc; + + TAILQ_FOREACH(mc_sc, &mcheck_devs, mc_entry) { + if (mc_sc->mc_dev == self) + return mc_sc; + } + return NULL; +} + +#ifdef DEBUG +device_t +mcheck_get_northbridge(int node) +{ + struct mcheck_softc *mc_sc; + int i = 0; + + TAILQ_FOREACH(mc_sc, &mcheck_devs, mc_entry) { + if (i == node) + return mc_sc->mc_dev; + i++; + } + return NULL; +} +#endif + +int +mcheck_register_cache(device_t self, + bool (*cache_check)(void *, struct mcheck_cache *), + int (*cache_recover)(void *, struct mcheck_cache *), + void *arg_check, void *arg_recover) +{ + struct mcheck_softc *mc; + + mc = mcheck_dev2sc(self); + if (mc == NULL) + return ENODEV; + + mc->mc_funcs.mc_cache_check = cache_check; + mc->mc_funcs.mc_cache_recover = cache_recover; + mc->mc_funcs.mc_arg_check = arg_check; + mc->mc_funcs.mc_arg_recover = arg_recover; + return 0; +} + +int +mcheck_recover_cache(device_t northbridge_dev, struct mcheck_cache *cache) +{ + struct mcheck_softc *mc; + bool rv; + int rc; + + mc = mcheck_dev2sc(northbridge_dev); + if (mc == NULL) + return ENODEV; + + if (!(*mc->mc_funcs.mc_cache_check)) + return ENOENT; + + rv = (*mc->mc_funcs.mc_cache_check)(mc->mc_funcs.mc_arg_check, cache); + if (rv == false) + return 0; + + /* TODO: Logging */ + + if (!(*mc->mc_funcs.mc_cache_recover)) + return ENOENT; + + rc = (*mc->mc_funcs.mc_cache_recover)(mc->mc_funcs.mc_arg_recover, + cache); + /* TODO: Logging */ + return rc; +} Index: sys/arch/xen/conf/Makefile.xen =================================================================== RCS file: /cvsroot/src/sys/arch/xen/conf/Makefile.xen,v retrieving revision 1.35 diff -u -p -r1.35 Makefile.xen --- sys/arch/xen/conf/Makefile.xen 19 Dec 2011 14:06:17 -0000 1.35 +++ sys/arch/xen/conf/Makefile.xen 25 Oct 2012 14:05:57 -0000 @@ -58,13 +58,14 @@ KERN_AS= obj ## ## (4) local objects, compile rules, and dependencies ## -MD_OBJS= locore.o spl.o copy.o vector.o +MD_OBJS= locore.o spl.o copy.o vector.o x86_trap.o MD_CFILES= MD_SFILES= $S/arch/${XEN_BUILD}/${XEN_BUILD}/locore.S \ $S/arch/${XEN_BUILD}/${XEN_BUILD}/spl.S \ $S/arch/${XEN_BUILD}/${XEN_BUILD}/vector.S \ - $S/arch/${XEN_BUILD}/${XEN_BUILD}/copy.S + $S/arch/${XEN_BUILD}/${XEN_BUILD}/copy.S \ + $S/arch/xen/x86/x86_trap.S copy.o: $S/arch/${XEN_BUILD}/${XEN_BUILD}/copy.S assym.h ${NORMAL_S} @@ -77,6 +78,10 @@ spl.o: $S/arch/${XEN_BUILD}/${XEN_BUILD} vector.o: $S/arch/${XEN_BUILD}/${XEN_BUILD}/vector.S assym.h ${NORMAL_S} + +x86_trap.o: $S/arch/xen/x86/x86_trap.S assym.h + ${NORMAL_S} + .ifndef noBEGIN .if !make(obj) && !make(clean) && !make(cleandir) .BEGIN: Index: sys/arch/xen/conf/files.xen =================================================================== RCS file: /cvsroot/src/sys/arch/xen/conf/files.xen,v retrieving revision 1.129 diff -u -p -r1.129 files.xen --- sys/arch/xen/conf/files.xen 3 Oct 2012 18:58:32 -0000 1.129 +++ sys/arch/xen/conf/files.xen 25 Oct 2012 14:05:57 -0000 @@ -86,6 +86,7 @@ file arch/x86/x86/db_memrw.c ddb | kgdb file arch/x86/x86/db_trace.c ddb file arch/xen/x86/hypervisor_machdep.c # file arch/x86/x86/mtrr_i686.c mtrr +file arch/x86/x86/errata.c file arch/x86/x86/syscall.c file arch/xen/x86/x86_xpmap.c file arch/xen/x86/xen_pmap.c @@ -105,6 +106,8 @@ file arch/xen/xen/evtchn.c file arch/xen/xen/xengnt.c +file arch/xen/x86/xen_mca.c + file dev/cons.c @@ -139,6 +142,7 @@ file arch/x86/x86/tsc.c file arch/x86/x86/vm_machdep.c file arch/x86/x86/x86_machdep.c file arch/x86/x86/cpu_topology.c +file arch/x86/x86/x86_mcheck.c dom0ops include "arch/xen/conf/files.compat" Index: sys/arch/xen/include/i82489var.h =================================================================== RCS file: /cvsroot/src/sys/arch/xen/include/i82489var.h,v retrieving revision 1.2 diff -u -p -r1.2 i82489var.h --- sys/arch/xen/include/i82489var.h 14 Nov 2010 13:40:31 -0000 1.2 +++ sys/arch/xen/include/i82489var.h 25 Oct 2012 14:05:57 -0000 @@ -8,4 +8,22 @@ * decide itself to which physical CPU the interrupt should be routed to. */ #undef lapic_cpu_number -#define lapic_cpu_number() (0) + +static inline uint32_t +lapic_cpu_number(void) +{ +#ifdef VCPUOP_get_physid + struct vcpu_get_physid cpu_id; + int ret; + + ret = HYPERVISOR_vcpu_op(&VCPUOP_get_physid, 0, &cpu_id); + if (ret != 0) + return 0; + + return xen_vcpu_physid_to_x86_apicid(cpu_id.phys_id); +#else + printf("%s: WARNING: Xen 3.2.x or newer required to determine APIC ID\n", + __func__); + return 0; +#endif +} Index: sys/arch/xen/include/xenio.h =================================================================== RCS file: /cvsroot/src/sys/arch/xen/include/xenio.h,v retrieving revision 1.9 diff -u -p -r1.9 xenio.h --- sys/arch/xen/include/xenio.h 10 Jan 2011 11:13:03 -0000 1.9 +++ sys/arch/xen/include/xenio.h 25 Oct 2012 14:05:57 -0000 @@ -62,7 +62,7 @@ typedef struct privcmd_mmapbatch_v2 { int num; /* number of pages to populate */ domid_t dom; /* target domain */ uint64_t addr; /* virtual address */ - const xen_pfn_t *arr; /* array of mfns */ + const unsigned long *arr; /* array of mfns */ int *err; /* array of error codes */ } privcmd_mmapbatch_v2_t; Index: sys/arch/xen/include/xen-public/arch-x86/xen-mca.h =================================================================== RCS file: /cvsroot/src/sys/arch/xen/include/xen-public/arch-x86/xen-mca.h,v retrieving revision 1.1.1.2 diff -u -p -r1.1.1.2 xen-mca.h --- sys/arch/xen/include/xen-public/arch-x86/xen-mca.h 7 Dec 2011 14:41:17 -0000 1.1.1.2 +++ sys/arch/xen/include/xen-public/arch-x86/xen-mca.h 25 Oct 2012 14:05:57 -0000 @@ -105,6 +105,7 @@ #define MC_TYPE_BANK 1 #define MC_TYPE_EXTENDED 2 #define MC_TYPE_RECOVERY 3 +#define MC_TYPE_GLOBAL2 4 struct mcinfo_common { uint16_t type; /* structure type */ @@ -119,6 +120,7 @@ struct mcinfo_common { #define MC_FLAG_RESET (1 << 4) #define MC_FLAG_CMCI (1 << 5) #define MC_FLAG_MCE (1 << 6) + /* contains global x86 mc information */ struct mcinfo_global { struct mcinfo_common common; @@ -134,6 +136,21 @@ struct mcinfo_global { uint64_t mc_gstatus; /* global status */ }; +struct mcinfo_global2 { + struct mcinfo_common common; + + /* running domain at the time in error (most likely the impacted one) */ + uint16_t mc_domid; + uint16_t mc_vcpuid; /* virtual cpu scheduled for mc_domid */ + uint32_t mc_socketid; /* physical socket of the physical core */ + uint16_t mc_coreid; /* physical impacted core */ + uint16_t mc_core_threadid; /* core thread of physical core */ + uint32_t mc_apicid; + uint32_t mc_flags; + uint64_t mc_gstatus; /* global status */ + uint32_t mc_cpucore_nodeid; +}; + /* contains bank local x86 mc information */ struct mcinfo_bank { struct mcinfo_common common; @@ -210,11 +227,21 @@ struct page_offline_action struct cpu_offline_action { /* Params for passing the identity of the offlined CPU to DOM0 */ + /* XXX: this is redundant information since this is provided by + * mcinfo_global2. */ uint32_t mc_socketid; uint16_t mc_coreid; uint16_t mc_core_threadid; }; +struct mcr_cache_shrink_action +{ + /* Params for passing the identity of the cpu cache to DOM0 */ + /* Identity of the affected cpu is provided by mcinfo_global2 */ + uint32_t cs_cacheindex; + uint32_t cs_subcache; +}; + #define MAX_UNION_SIZE 16 struct mcinfo_recovery { @@ -225,6 +252,7 @@ struct mcinfo_recovery union { struct page_offline_action page_retire; struct cpu_offline_action cpu_offline; + struct mcr_cache_shrink_action mcr_cache_shrink; uint8_t pad[MAX_UNION_SIZE]; } action_info; }; Index: sys/arch/xen/x86/cpu.c =================================================================== RCS file: /cvsroot/src/sys/arch/xen/x86/cpu.c,v retrieving revision 1.93 diff -u -p -r1.93 cpu.c --- sys/arch/xen/x86/cpu.c 24 Jun 2012 13:56:10 -0000 1.93 +++ sys/arch/xen/x86/cpu.c 25 Oct 2012 14:05:57 -0000 @@ -120,6 +120,7 @@ __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.93 #include #include +#include static int cpu_match(device_t, cfdata_t, void *); static void cpu_attach(device_t, device_t, void *); @@ -507,6 +508,15 @@ cpu_attach_common(device_t parent, devic panic("unknown processor type??\n"); } + if (x86_amd_errata(ci, X86_AMD_ERRATUM_400)) { + aprint_normal_dev(self, "erratum 400 present\n"); + } + +#if 0 + if (!pmf_device_register(self, cpu_suspend, cpu_resume)) + aprint_error_dev(self, "couldn't establish power handler\n"); +#endif + #ifdef MPVERBOSE if (mp_verbose) { struct lwp *l = ci->ci_data.cpu_idlelwp; Index: sys/arch/xen/x86/mainbus.c =================================================================== RCS file: /cvsroot/src/sys/arch/xen/x86/mainbus.c,v retrieving revision 1.15 diff -u -p -r1.15 mainbus.c --- sys/arch/xen/x86/mainbus.c 20 Sep 2011 00:12:24 -0000 1.15 +++ sys/arch/xen/x86/mainbus.c 25 Oct 2012 14:05:57 -0000 @@ -66,6 +66,8 @@ __KERNEL_RCSID(0, "$NetBSD: mainbus.c,v #include #if NACPICA > 0 #include +#include +#include #include #endif /* NACPICA > 0 */ #ifdef MPBIOS @@ -139,6 +141,9 @@ mainbus_attach(device_t parent, device_t union mainbus_attach_args mba; #if defined(DOM0OPS) int numcpus = 0; +#if NACPICA > 0 + int rc; +#endif #ifdef MPBIOS int mpbios_present = 0; #endif @@ -172,8 +177,32 @@ mainbus_attach(device_t parent, device_t #endif /* PCI_BUS_FIXUP */ #if NACPICA > 0 acpi_present = acpi_probe(); - if (acpi_present) + if (acpi_present) { mpacpi_active = mpacpi_scan_apics(self, &numcpus); + if (!acpisrat_exist()) { + aprint_error_dev(self, + "ACPI SRAT table not present\n"); + } else { + if ((rc = acpisrat_init()) != 0) + aprint_error_dev(self, + "ACPI SRAT initialization failed, rc: %i\n", + rc); + else + acpisrat_dump(); + } + + if (!acpislit_exist()) { + aprint_error_dev(self, + "ACPI SLIT table not present\n"); + } else { + if ((rc = acpislit_init()) != 0) + aprint_error_dev(self, + "ACPI SLIT initialization failed, rc: %i\n", + rc); + else + acpislit_dump(); + } + } if (!mpacpi_active) #endif { Index: sys/arch/xen/x86/x86_trap.S =================================================================== RCS file: sys/arch/xen/x86/x86_trap.S diff -N sys/arch/xen/x86/x86_trap.S --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/xen/x86/x86_trap.S 25 Oct 2012 14:05:57 -0000 @@ -0,0 +1,73 @@ +/* NetBSD: x86_trap.S,v 1.1 2007/07/12 14:49:55 cegger Exp */ + +/* + * Copyright 2007 (c) Advanced Micro Devices, Inc. + * All rights reserved. + * + * Written by Christoph Egger for Advanced Micro Devices, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)isa.c 7.2 (Berkeley) 5/13/91 + */ + +#include + +#include "opt_xen.h" + +#include +#include +#if 0 +#include +#endif +#include +#include + +#include "assym.h" + +.globl _C_LABEL(xenmca_traphandler) +.globl _C_LABEL(xenmc_trap) + +NENTRY(xenmc_trap) +#ifdef amd64 + movq (%rsp),%rcx + movq 8(%rsp),%r11 + addq $0x10,%rsp + pushq $0 + pushq $T_MCA +#endif +#ifdef i386 + pushl $0 # dummy error code + pushl $T_ASTFLT +#endif + INTRENTRY + call xenmca_traphandler + INTRFASTEXIT + +#if 0 + INTRRESTORE +#if defined(XEN_COMPAT_030001) + iret +#else + jmp HYPERVISOR_iret +#endif +#endif Index: sys/arch/xen/x86/x86_xpmap.c =================================================================== RCS file: /cvsroot/src/sys/arch/xen/x86/x86_xpmap.c,v retrieving revision 1.49 diff -u -p -r1.49 x86_xpmap.c --- sys/arch/xen/x86/x86_xpmap.c 16 Sep 2012 22:09:34 -0000 1.49 +++ sys/arch/xen/x86/x86_xpmap.c 25 Oct 2012 14:05:57 -0000 @@ -90,6 +90,7 @@ __KERNEL_RCSID(0, "$NetBSD: x86_xpmap.c, #include #undef XENDEBUG +//#define XENDEBUG /* #define XENDEBUG_SYNC */ /* #define XENDEBUG_LOW */ Index: sys/arch/xen/x86/xen_mca.c =================================================================== RCS file: sys/arch/xen/x86/xen_mca.c diff -N sys/arch/xen/x86/xen_mca.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/xen/x86/xen_mca.c 25 Oct 2012 14:05:57 -0000 @@ -0,0 +1,450 @@ +/* NetBSD: xen_mca.c,v 1.1 2007/07/12 14:49:55 cegger Exp */ + +/* + * Copyright 2007 (c) Advanced Micro Devices, Inc. + * All rights reserved. + * + * Written by Christoph Egger for Advanced Micro Devices, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)isa.c 7.2 (Berkeley) 5/13/91 + */ + +#include +__KERNEL_RCSID(0, "$NetBSD: xen_mca.c,v 1.1 2007/07/12 01:52:46 cegger Exp $"); + +#include "opt_multiprocessor.h" +#include "opt_xen.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include + +static void +xen_mcinfo_dump(struct mcinfo_common *mic) +{ + struct mcinfo_global *mg; + struct mcinfo_bank *mb; + struct mcinfo_extended *ms; + struct mcinfo_recovery *mr; + uint64_t i; + + if (mic == NULL) { + printf_nolog("%s: invalid machine check info\n", __func__); + return; + } + switch (mic->type) { + case MC_TYPE_GLOBAL: + mg = (struct mcinfo_global *)mic; + printf_nolog("type: global machine check information\n"); + printf_nolog("size: 0x%x bytes\n", mic->size); + printf_nolog("mc_domid: impacted domain number %u\n", mg->mc_domid); + printf_nolog("mc_vcpuid: virtual cpu scheduled for mc_domid %u\n", + mg->mc_vcpuid); + printf_nolog("mc_socketid: (cpu socket) %u\n", mg->mc_socketid); + printf_nolog("mc_coreid: (cpu core) %u\n", mg->mc_coreid); + printf_nolog("mc_core_threadid: (cpu core thread) %u\n", + mg->mc_core_threadid); + printf_nolog("mc_apicid: %u\n", mg->mc_apicid); + printf_nolog("mc_gstatus: MCG_STATUS: %"PRIx64"\n", mg->mc_gstatus); + + if (mg->mc_flags & MC_FLAG_CORRECTABLE) + printf_nolog("mc_flags: correctable error type\n"); + if (mg->mc_flags & MC_FLAG_UNCORRECTABLE) + printf_nolog("mc_flags: uncorrectable error type\n"); + if (mg->mc_flags & MC_FLAG_RECOVERABLE) + printf_nolog("mc_flags: recoverable error type\n"); + if (mg->mc_flags & MC_FLAG_POLLED) + printf_nolog("mc_flags: polled error type\n"); + if (mg->mc_flags & MC_FLAG_RESET) + printf_nolog("mc_flags: reset error type\n"); + if (mg->mc_flags & MC_FLAG_CMCI) + printf_nolog("mc_flags: cmci error type\n"); + if (mg->mc_flags & MC_FLAG_MCE) + printf_nolog("mc_flags: exception error type\n"); + break; + + case MC_TYPE_BANK: + mb = (struct mcinfo_bank *)mic; + printf_nolog("type: bank machine check information\n"); + printf_nolog("size: 0x%x bytes\n", mic->size); + switch (mb->mc_bank) { + case 0: + printf_nolog("mc_bank: data cache error reporting bank\n"); + break; + case 1: + printf_nolog("mc_bank: instruction cache error reporting bank\n"); + break; + case 2: + printf_nolog("mc_bank: bus unit error reporting bank\n"); + break; + case 3: + printf_nolog("mc_bank: load-store error reporting bank\n"); + break; + case 4: + printf_nolog("mc_bank: northbridge error reporting bank\n"); + break; + case 5: + printf_nolog("mc_bank: fixed issue re-order buffer error reporting bank\n"); + break; + default: + printf_nolog("mc_bank: unknown bank: %i\n", mb->mc_bank); + break; + } + printf_nolog("mc_status: 0x%"PRIx64"\n", mb->mc_status); + if (mb->mc_status & MCi_STATUS_ADDRV) + printf_nolog("mc_addr: 0x%"PRIx64"\n", mb->mc_addr); + else + printf_nolog("mc_addr: addrv bit in status not set\n"); + if (mb->mc_status & MCi_STATUS_MISCV) + printf_nolog("mc_misc: 0x%"PRIx64"\n", mb->mc_misc); + else + printf_nolog("mc_misc: miscv bit in status not set\n"); + + printf_nolog("mc_ctrl2: 0x%"PRIx64"\n", mb->mc_ctrl2); + printf_nolog("mc_tsc: 0x%"PRIx64"\n", mb->mc_tsc); + break; + + case MC_TYPE_EXTENDED: + ms = (struct mcinfo_extended *)mic; + printf_nolog("type: extended machine check information\n"); + printf_nolog("size: 0x%x bytes\n", mic->size); + printf_nolog("number of model extended registers: %u\n", + ms->mc_msrs); + + for (i = 0; i < ms->mc_msrs; i++) { + printf_nolog("MSR: 0x%8"PRIx64", value: 0x%16"PRIx64"\n", + ms->mc_msr[i].reg, ms->mc_msr[i].value); + } + break; + + case MC_TYPE_RECOVERY: + mr = (struct mcinfo_recovery *)mic; + printf_nolog("type: recovery machine check information\n"); + printf_nolog("size: 0x%x bytes\n", mic->size); + printf_nolog("mc_bank: %u\n", mr->mc_bank); + + if (mr->action_flags & REC_ACTION_RECOVERED) + printf_nolog("Xen took successful recovery action\n"); + if (mr->action_flags & REC_ACTION_NONE) + printf_nolog("Xen took no recovery action\n"); + if (mr->action_flags & REC_ACTION_NEED_RESET) + printf_nolog("Dom0 may take action ownership\n"); + + if (mr->action_types & MC_ACTION_PAGE_OFFLINE) + printf_nolog("taken action: page offline\n"); + if (mr->action_types & MC_ACTION_CPU_OFFLINE) + printf_nolog("taken action: cpu offline\n"); + if (mr->action_types & MC_ACTION_CACHE_SHRINK) + printf_nolog("taken action: cpu cache shrink\n"); + + break; + + default: + printf_nolog("type: unknown machine check information\n"); + printf_nolog("size: 0x%x bytes\n", mic->size); + break; + } +} + + +void xenmca_traphandler(void); + +void +xenmca_traphandler(void) +{ + struct mc_info mi; + struct mcinfo_global *mg; + struct mcinfo_bank *mb[6]; + struct mcinfo_extended *me; + struct mcinfo_common *mic; + struct mcinfo_recovery *mr; + + struct mcheck_cache mc_l3cache; + struct xen_mc mc_op; + int i, j, rc; + int flags; + + printf_nolog("%s: HW reported error(s)\n", __func__); + j = 0; + memset(&mc_op, 0, sizeof(mc_op)); + + flags = XEN_MC_URGENT; + set_xen_guest_handle(mc_op.u.mc_fetch.data, &mi); + + for (;;) { + mc_op.cmd = XEN_MC_fetch; + mc_op.u.mc_fetch.flags = flags; + + printf_nolog("%s: fetch %surgent data\n", + __func__, + (flags == XEN_MC_NONURGENT) ? "non" : ""); + + rc = HYPERVISOR_machine_check(&mc_op); + if (rc) { + printf_nolog("%s: HYPERVISOR fetch failed %i\n", + __func__, rc); + printf_nolog("%s: \"%s\" \"%s\"\n", + __func__, + mc_op.u.mc_fetch.flags & XEN_MC_NODATA ? + "no data" : "", + mc_op.u.mc_fetch.flags & XEN_MC_FETCHFAILED ? + "fetch failed" : ""); + return; + } + + if (mc_op.u.mc_fetch.flags & XEN_MC_NODATA) { + if (flags == XEN_MC_NONURGENT) + break; + flags = XEN_MC_NONURGENT; + continue; + } + + /* After fetching the error telemetry acknowledge it. */ + mc_op.u.mc_fetch.flags = flags | XEN_MC_ACK; + rc = HYPERVISOR_machine_check(&mc_op); + if (rc) { + printf_nolog("%s: ack failed, rc = %i\n", + __func__, -rc); + return; + } + + printf_nolog("%s: %scorrectable errors occured\n", + __func__, + (flags == XEN_MC_URGENT) ? "un" : ""); + + mic = x86_mcinfo_first(&mi); + for (i = 0; i < x86_mcinfo_nentries(&mi); i++) { + if (mic == NULL) { + printf_nolog("%s: index overflow: %i of %i\n", + __func__, i, x86_mcinfo_nentries(&mi)); + break; + } + switch (mic->type) { + case MC_TYPE_GLOBAL: + printf_nolog("xen_mca: found mcinfo_global\n"); + mg = (struct mcinfo_global *)mic; + break; + case MC_TYPE_BANK: + printf_nolog("xen_mca: found mcinfo_bank\n"); + mb[j] = (struct mcinfo_bank *)mic; + j++; + break; + case MC_TYPE_EXTENDED: + printf_nolog("xen_mca: found mcinfo_extended\n"); + me = (struct mcinfo_extended *)mic; + break; + case MC_TYPE_RECOVERY: + printf_nolog("xen_mca: found mcinfo_recovery\n"); + mr = (struct mcinfo_recovery *)mic; + mc_l3cache.mc_status = mb[0]->mc_status; + mc_l3cache.mc_addr = mb[0]->mc_addr; + rc = mcheck_recover_cache( + mcheck_get_northbridge(0), + &mc_l3cache); + printf_nolog("%s: mcheck_recover_cache %i\n", + __func__, rc); + break; + default: + printf_nolog("xen_mca: unknown type %x\n", + mic->type); + break; + } + + xen_mcinfo_dump(mic); + mic = x86_mcinfo_next(mic); + } + } + + return; +} + +#ifdef DOM0OPS +static int +xenmc_event(void *arg) +{ + struct mc_info mi; + struct mcinfo_global *mg; + struct mcinfo_bank *mb[6]; + struct mcinfo_extended *me; + struct mcinfo_recovery *mr; + struct mcinfo_common *mic; + struct xen_mc mc_op; + int i, j, rc; + int flags; + + struct mcheck_cache mc_l3cache; + + printf_nolog("%s: HW reported error(s)\n", __func__); + j = 0; + memset(&mc_op, 0, sizeof(mc_op)); + + flags = XEN_MC_URGENT; + set_xen_guest_handle(mc_op.u.mc_fetch.data, &mi); + + for (;;) { + mc_op.cmd = XEN_MC_fetch; + mc_op.u.mc_fetch.flags = flags; + + printf_nolog("%s: fetch %surgent data\n", + __func__, + (flags == XEN_MC_NONURGENT) ? "non" : ""); + + rc = HYPERVISOR_machine_check(&mc_op); + if (rc) { + printf_nolog("%s: HYPERVISOR fetch failed %i\n", + __func__, rc); + printf_nolog("%s: \"%s\" \"%s\"\n", __func__, + mc_op.u.mc_fetch.flags & XEN_MC_NODATA ? + "no data" : "", + mc_op.u.mc_fetch.flags & XEN_MC_FETCHFAILED ? + "fetch failed" : ""); + return -rc; + } + + if (mc_op.u.mc_fetch.flags & XEN_MC_NODATA) { + if (flags == XEN_MC_NONURGENT) + break; + flags = XEN_MC_NONURGENT; + continue; + } + + /* After fetching the error telemetry acknowledge it. */ + mc_op.u.mc_fetch.flags = flags | XEN_MC_ACK; + rc = HYPERVISOR_machine_check(&mc_op); + if (rc) { + printf_nolog("%s: ack failed, rc = %i\n", + __func__, -rc); + return -rc; + } + + printf_nolog("%s: %scorrectable errors occured\n", + __func__, + (flags == XEN_MC_URGENT) ? "un" : ""); + + mic = x86_mcinfo_first(&mi); + for (i = 0; i < x86_mcinfo_nentries(&mi); i++) { + if (mic == NULL) { + printf_nolog("%s: index overflow: %i of %i\n", + __func__, i, x86_mcinfo_nentries(&mi)); + break; + } + switch (mic->type) { + case MC_TYPE_GLOBAL: + printf_nolog("xen_mca: found mcinfo_global\n"); + mg = (struct mcinfo_global *)mic; + break; + case MC_TYPE_BANK: + printf_nolog("xen_mca: found mcinfo_bank\n"); + mb[j] = (struct mcinfo_bank *)mic; + j++; + break; + case MC_TYPE_EXTENDED: + printf_nolog("xen_mca: found mcinfo_extended\n"); + me = (struct mcinfo_extended *)mic; + break; + case MC_TYPE_RECOVERY: + printf_nolog("xen_mca: found mcinfo_recovery\n"); + mr = (struct mcinfo_recovery *)mic; + mc_l3cache.mc_status = mb[0]->mc_status; + mc_l3cache.mc_addr = mb[0]->mc_addr; + rc = mcheck_recover_cache( + mcheck_get_northbridge(0), + &mc_l3cache); + printf_nolog("%s: mcheck_recover_cache %i\n", + __func__, rc); + break; + default: + printf_nolog("xen_mca: unknown type %x\n", + mic->type); + break; + } + + xen_mcinfo_dump(mic); + mic = x86_mcinfo_next(mic); + } + } + + return 0; +} +#endif /* DOM0OPS */ + + +extern void xenmc_trap(void); + +void xenmca_init(void); + +void +xenmca_init(void) +{ + int rc; + trap_info_t ti_mce; +#ifdef DOM0OPS + int evtch; + + evtch = bind_virq_to_evtch(VIRQ_MCA); + aprint_normal("Xen machine check architecture: using event channel %d\n", + evtch); + + event_set_handler(evtch, (int (*)(void *))xenmc_event, + NULL, IPL_MCA, "mca"); + hypervisor_enable_event(evtch); +#endif + + mcheck_init(); + + ti_mce.vector = 18; /* TRAP_machine_check */ + TI_SET_IF(&(ti_mce), 2); + ti_mce.cs = __KERNEL_CS; + ti_mce.address = (vaddr_t)xenmc_trap; + + /* register MCE handler for uncorrectable errors */ + rc = HYPERVISOR_set_trap_table(&ti_mce); + aprint_normal("Xen machine check architecture: %s\n", + rc < 0 ? "failed to register mce trap handler" + : "registered mce trap handler"); + + return; +} + +int uninit_xenmca(void); + +int +uninit_xenmca(void) +{ + mcheck_exit(); + return 0; +} Index: sys/arch/xen/xen/balloon.c =================================================================== RCS file: /cvsroot/src/sys/arch/xen/xen/balloon.c,v retrieving revision 1.16 diff -u -p -r1.16 balloon.c --- sys/arch/xen/xen/balloon.c 30 Jun 2012 23:36:20 -0000 1.16 +++ sys/arch/xen/xen/balloon.c 25 Oct 2012 14:05:57 -0000 @@ -68,7 +68,7 @@ * */ -#define BALLOONDEBUG 0 +#define BALLOONDEBUG 1 #include __KERNEL_RCSID(0, "$NetBSD: balloon.c,v 1.16 2012/06/30 23:36:20 jym Exp $"); Index: sys/arch/xen/xen/evtchn.c =================================================================== RCS file: /cvsroot/src/sys/arch/xen/xen/evtchn.c,v retrieving revision 1.62 diff -u -p -r1.62 evtchn.c --- sys/arch/xen/xen/evtchn.c 12 Feb 2012 14:24:08 -0000 1.62 +++ sys/arch/xen/xen/evtchn.c 25 Oct 2012 14:05:57 -0000 @@ -504,11 +504,14 @@ bind_pirq_to_evtch(int pirq) evtchn = pirq_to_evtch[pirq]; if (evtchn == -1) { + int ret; op.cmd = EVTCHNOP_bind_pirq; op.u.bind_pirq.pirq = pirq; op.u.bind_pirq.flags = BIND_PIRQ__WILL_SHARE; - if (HYPERVISOR_event_channel_op(&op) != 0) - panic("Failed to bind physical IRQ %d\n", pirq); + ret = HYPERVISOR_event_channel_op(&op); + if (ret) + panic("Failed to bind physical IRQ %d, error=%i\n", + pirq, ret); evtchn = op.u.bind_pirq.port; #ifdef IRQ_DEBUG Index: sys/arch/xen/xen/hypervisor.c =================================================================== RCS file: /cvsroot/src/sys/arch/xen/xen/hypervisor.c,v retrieving revision 1.62 diff -u -p -r1.62 hypervisor.c --- sys/arch/xen/xen/hypervisor.c 6 Apr 2012 03:20:43 -0000 1.62 +++ sys/arch/xen/xen/hypervisor.c 25 Oct 2012 14:05:57 -0000 @@ -188,6 +188,9 @@ hypervisor_match(device_t parent, cfdata return 0; } + +extern void xenmca_init(void); + #ifdef MULTIPROCESSOR static int hypervisor_vcpu_print(void *aux, const char *parent) @@ -253,6 +256,7 @@ hypervisor_attach(device_t parent, devic } #endif /* MULTIPROCESSOR */ + xenmca_init(); #if NXENBUS > 0 memset(&hac, 0, sizeof(hac)); Index: sys/arch/xen/xen/privcmd.c =================================================================== RCS file: /cvsroot/src/sys/arch/xen/xen/privcmd.c,v retrieving revision 1.44 diff -u -p -r1.44 privcmd.c --- sys/arch/xen/xen/privcmd.c 27 Jun 2012 00:37:10 -0000 1.44 +++ sys/arch/xen/xen/privcmd.c 25 Oct 2012 14:05:57 -0000 @@ -69,6 +69,8 @@ static void privpgop_detach(struct uvm_o static int privpgop_fault(struct uvm_faultinfo *, vaddr_t , struct vm_page **, int, int, vm_prot_t, int); static int privcmd_map_obj(struct vm_map *, vaddr_t, paddr_t *, int, int); +static int privcmd_map(pmap_t pmap, vaddr_t va0, u_long *mfn, + vm_prot_t prot, int num, int domid); static int @@ -367,8 +369,56 @@ privcmd_ioctl(void *v) } case IOCTL_PRIVCMD_MMAPBATCH: { - int i; privcmd_mmapbatch_t* pmb = ap->a_data; + vaddr_t va0; + u_long *mfn; + struct vm_map *vmm; + struct vm_map_entry *entry; + vm_prot_t prot; + pmap_t pmap; + + vmm = &curlwp->l_proc->p_vmspace->vm_map; + pmap = vm_map_pmap(vmm); + va0 = pmb->addr & ~PAGE_MASK; + + if (pmb->num == 0) + return EINVAL; + if (va0 > VM_MAXUSER_ADDRESS) + return EINVAL; + if (((VM_MAXUSER_ADDRESS - va0) >> PGSHIFT) < pmb->num) + return EINVAL; + + vm_map_lock_read(vmm); + if (!uvm_map_lookup_entry(vmm, va0, &entry)) { + vm_map_unlock_read(vmm); + return EINVAL; + } + prot = entry->protection; + vm_map_unlock_read(vmm); + + mfn = kmem_alloc(sizeof(u_long) * pmb->num, KM_SLEEP); + error = copyin(pmb->arr, mfn, sizeof(u_long) * pmb->num); + if (error != 0) { + /* XXX: mappings */ + kmem_free(mfn, sizeof(u_long) * pmb->num); + return error; + } + + /* Map the memory region directly */ + error = privcmd_map(pmap, va0, mfn, prot, pmb->num, pmb->dom); + if (error) { + kmem_free(mfn, sizeof(u_long) * pmb->num); + return error; + } + copyout(mfn, pmb->arr, sizeof(u_long) * pmb->num); + kmem_free(mfn, sizeof(u_long) * pmb->num); + + break; + } + case IOCTL_PRIVCMD_MMAPBATCH_V2: + { + int i; + privcmd_mmapbatch_v2_t* pmb = ap->a_data; vaddr_t va0, va; u_long mfn; paddr_t ma; @@ -377,6 +427,7 @@ privcmd_ioctl(void *v) vm_prot_t prot; pmap_t pmap; vaddr_t trymap; + int err, err_out = 0; vmm = &curlwp->l_proc->p_vmspace->vm_map; pmap = vm_map_pmap(vmm); @@ -408,12 +459,10 @@ privcmd_ioctl(void *v) return ENOMEM; } - for(i = 0; i < pmb->num; ++i) { + for (i = 0; i < pmb->num; ++i) { va = va0 + (i * PAGE_SIZE); error = copyin(&pmb->arr[i], &mfn, sizeof(mfn)); if (error != 0) { - /* XXX: mappings */ - pmap_update(pmap_kernel()); kmem_free(maddr, sizeof(paddr_t) * pmb->num); uvm_km_free(kernel_map, trymap, PAGE_SIZE, UVM_KMF_VAONLY); @@ -422,8 +471,9 @@ privcmd_ioctl(void *v) ma = ((paddr_t)mfn) << PGSHIFT; if (pmap_enter_ma(pmap_kernel(), trymap, ma, 0, prot, PMAP_CANFAIL, pmb->dom)) { - mfn |= 0xF0000000; - copyout(&mfn, &pmb->arr[i], sizeof(mfn)); + err = ENOENT; + err_out = ENOENT; + copyout(&err, &pmb->err[i], sizeof(err)); maddr[i] = INVALID_PAGE; } else { pmap_remove(pmap_kernel(), trymap, @@ -431,14 +481,15 @@ privcmd_ioctl(void *v) maddr[i] = ma; } } - pmap_update(pmap_kernel()); - error = privcmd_map_obj(vmm, va0, maddr, pmb->num, pmb->dom); uvm_km_free(kernel_map, trymap, PAGE_SIZE, UVM_KMF_VAONLY); if (error != 0) return error; + if (err_out != 0) + return err_out; + break; } default: @@ -448,6 +499,24 @@ privcmd_ioctl(void *v) return error; } +static int privcmd_map(pmap_t pmap, vaddr_t va0, u_long *mfn, + vm_prot_t prot, int num, int domid) +{ + int i; + vaddr_t va; + paddr_t ma; + + for(i = 0; i < num; ++i) { + va = va0 + (i * PAGE_SIZE); + ma = ((paddr_t)mfn[i]) << PGSHIFT; + if (pmap_enter_ma(pmap, va, ma, 0, prot, PMAP_CANFAIL, domid)) + mfn[i] |= 0xF0000000; + } + pmap_update(pmap); + + return 0; +} + static struct uvm_pagerops privpgops = { .pgo_reference = privpgop_reference, .pgo_detach = privpgop_detach, Index: sys/arch/xen/xen/xen_acpi_machdep.c =================================================================== RCS file: /cvsroot/src/sys/arch/xen/xen/xen_acpi_machdep.c,v retrieving revision 1.5 diff -u -p -r1.5 xen_acpi_machdep.c --- sys/arch/xen/xen/xen_acpi_machdep.c 18 Aug 2009 16:41:03 -0000 1.5 +++ sys/arch/xen/xen/xen_acpi_machdep.c 25 Oct 2012 14:05:57 -0000 @@ -10,9 +10,94 @@ __KERNEL_RCSID(0, "$NetBSD: xen_acpi_mac #define ACPI_MACHDEP_PRIVATE #include +static int +xen_dom0_sleepenter(int sleep_state, int pm1a_control, int pm1b_control) +{ + struct xen_platform_op op = { + .cmd = XENPF_enter_acpi_sleep, + .interface_version = XENPF_INTERFACE_VERSION, + .u = { + .enter_acpi_sleep = { + .pm1a_cnt_val = pm1a_control, + .pm1b_cnt_val = pm1b_control, + .sleep_state = sleep_state, + }, + }, + }; + + return HYPERVISOR_platform_op(&op); +} + +static ACPI_STATUS +acpi_md_get_pm1controls(uint32_t *pm1a_control, uint32_t *pm1b_control) +{ + ACPI_STATUS status = 0; + uint32_t pm1a, pm1b; + struct acpi_bit_register_info *sleep_type_reg_info; + struct acpi_bit_register_info *sleep_enable_reg_info; + + *pm1a_control = *pm1b_control = 0; + + sleep_type_reg_info = + AcpiHwGetBitRegisterInfo(ACPI_BITREG_SLEEP_TYPE); + sleep_enable_reg_info = + AcpiHwGetBitRegisterInfo(ACPI_BITREG_SLEEP_ENABLE); + + status = AcpiHwRegisterRead(ACPI_REGISTER_PM1_CONTROL, &pm1a); + if (ACPI_FAILURE(status)) + return status; + + /* Clear SLP_EN and SLP_TYP fields */ + pm1a &= ~(sleep_type_reg_info->AccessBitMask | + sleep_enable_reg_info->AccessBitMask); + pm1b = pm1a; + + /* Insert SLP_TYP bits */ + pm1a |= (AcpiGbl_SleepTypeA << sleep_type_reg_info->BitPosition); + pm1b |= (AcpiGbl_SleepTypeB << sleep_type_reg_info->BitPosition); + + /* Split the writes of SLP_TYP and SLP_EN to workaround + * poorly implemented hardware + */ + + /* Write #1: fill in SLP_TYP data */ + status = AcpiHwWritePm1Control(pm1a, pm1b); + if (ACPI_FAILURE(status)) + return status; + + /* Insert SLP_ENABLE bit */ + + pm1a |= sleep_enable_reg_info->AccessBitMask; + pm1b |= sleep_enable_reg_info->AccessBitMask; + + ACPI_FLUSH_CPU_CACHE(); + + *pm1a_control = pm1a; + *pm1b_control = pm1b; + + return status; +} + int acpi_md_sleep(int state) { - printf("acpi: sleep not implemented\n"); - return (-1); + int error; + ACPI_STATUS status; + uint32_t pm1a_control, pm1b_control; + + /* XXX Xen version check: + * Xen <= 3.2 : no s3 support available. + * Xen >= 3.3 : s3 support present. + */ + + status = acpi_md_get_pm1controls(&pm1a_control, &pm1b_control); + if (ACPI_FAILURE(status)) { + printf("xenacpi: can't enter sleep mode. acpi error %i\n", + status); + return -1; + } + + error = xen_dom0_sleepenter(state, pm1a_control, pm1b_control); + + return error; } Index: sys/arch/xen/xen/xen_machdep.c =================================================================== RCS file: /cvsroot/src/sys/arch/xen/xen/xen_machdep.c,v retrieving revision 1.13 diff -u -p -r1.13 xen_machdep.c --- sys/arch/xen/xen/xen_machdep.c 28 Jul 2012 02:08:51 -0000 1.13 +++ sys/arch/xen/xen/xen_machdep.c 25 Oct 2012 14:05:57 -0000 @@ -68,6 +68,7 @@ __KERNEL_RCSID(0, "$NetBSD: xen_machdep. #include #include +#include #define DPRINTK(x) printk x #if 0 @@ -85,6 +86,68 @@ static void xen_suspend_domain(void); static void xen_prepare_suspend(void); static void xen_prepare_resume(void); +/* + * Adds the bootinfo entry given in 'item' to the bootinfo tables. + * Sets the item type to 'type' and its length to 'len'. + */ +static void +bootinfo_add(struct btinfo_common *item, int type, int len) +{ + int i; + struct bootinfo *bip = (struct bootinfo *)&bootinfo; + vaddr_t data; + + item->type = type; + item->len = len; + + data = (vaddr_t)&bip->bi_data; + for (i = 0; i < bip->bi_nentries; i++) { + struct btinfo_common *tmp; + + tmp = (struct btinfo_common *)data; + data += tmp->len; + } + if (data + len < (vaddr_t)&bip->bi_data + sizeof(bip->bi_data)) { + memcpy((void *)data, item, len); + bip->bi_nentries++; + } +} + +/* + * Sets up the bootpath bootinfo structure with an appropriate kernel + * name derived from the boot command line. The Multiboot information + * structure does not provide this detail directly, so we try to derive + * it from the command line setting. + */ +static void +setup_bootpath(char *cmdline) +{ + struct btinfo_bootpath bi; + char *cl, *cl2, old; + int len; + + printf("Full bootpath: %s\n", cmdline); + + cl = cmdline; + while (*cl != '\0' && *cl != '/') + cl++; + cl2 = cl; + len = 0; + while (*cl2 != '\0' && *cl2 != ' ') { + len++; + cl2++; + } + + old = *cl2; + *cl2 = '\0'; + memcpy(bi.bootpath, cl, MIN(sizeof(bi.bootpath), len)); + *cl2 = old; + bi.bootpath[MIN(sizeof(bi.bootpath), len)] = '\0'; + + bootinfo_add((struct btinfo_common *)&bi, BTINFO_BOOTPATH, + sizeof(struct btinfo_bootpath)); +} + void xen_parse_cmdline(int what, union xen_cmdline_parseinfo *xcp) { @@ -102,6 +165,7 @@ xen_parse_cmdline(int what, union xen_cm switch (what) { case XEN_PARSE_BOOTDEV: xcp->xcp_bootdev[0] = 0; + setup_bootpath(cmd_line); break; case XEN_PARSE_CONSOLE: xcp->xcp_console[0] = 0; Index: sys/dev/pci/if_bge.c =================================================================== RCS file: /cvsroot/src/sys/dev/pci/if_bge.c,v retrieving revision 1.202 diff -u -p -r1.202 if_bge.c --- sys/dev/pci/if_bge.c 17 Sep 2012 11:54:36 -0000 1.202 +++ sys/dev/pci/if_bge.c 25 Oct 2012 14:05:57 -0000 @@ -516,6 +516,14 @@ static const struct bge_product { "BCM5784M NetLink 1000baseT Ethernet", }, { PCI_VENDOR_BROADCOM, + PCI_PRODUCT_BROADCOM_BCM5785F, + "Broadcom BCM5785F Gigabit Ethernet", + }, + { PCI_VENDOR_BROADCOM, + PCI_PRODUCT_BROADCOM_BCM5785G, + "Broadcom BCM5785G Gigabit Ethernet", + }, + { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5786, "Broadcom BCM5786 Gigabit Ethernet", }, @@ -1336,11 +1344,16 @@ bge_newbuf_std(struct bge_softc *sc, int if (m == NULL) { MGETHDR(m_new, M_DONTWAIT, MT_DATA); - if (m_new == NULL) + if (m_new == NULL) { + aprint_error_dev(sc->bge_dev, + "%s: MGETHDR failed: ENOBUFS\n", __func__); return ENOBUFS; + } MCLGET(m_new, M_DONTWAIT); if (!(m_new->m_flags & M_EXT)) { + aprint_error_dev(sc->bge_dev, + "%s: MCLGET failed: ENOBUFS\n", __func__); m_freem(m_new); return ENOBUFS; } @@ -1354,8 +1367,11 @@ bge_newbuf_std(struct bge_softc *sc, int if (!(sc->bge_flags & BGE_RX_ALIGNBUG)) m_adj(m_new, ETHER_ALIGN); if (bus_dmamap_load_mbuf(sc->bge_dmatag, dmamap, m_new, - BUS_DMA_READ|BUS_DMA_NOWAIT)) + BUS_DMA_READ|BUS_DMA_NOWAIT)) { + aprint_error_dev(sc->bge_dev, + "%s: bus_dmamap_load_mbuf failed: ENOBUFS\n", __func__); return ENOBUFS; + } bus_dmamap_sync(sc->bge_dmatag, dmamap, 0, dmamap->dm_mapsize, BUS_DMASYNC_PREREAD); @@ -1390,8 +1406,11 @@ bge_newbuf_jumbo(struct bge_softc *sc, i /* Allocate the mbuf. */ MGETHDR(m_new, M_DONTWAIT, MT_DATA); - if (m_new == NULL) + if (m_new == NULL) { + aprint_error_dev(sc->bge_dev, + "%s: MGETHDR failed: ENOBUFS\n", __func__); return ENOBUFS; + } /* Allocate the jumbo buffer */ buf = bge_jalloc(sc); @@ -1449,8 +1468,11 @@ bge_init_rx_ring_std(struct bge_softc *s return 0; for (i = 0; i < BGE_SSLOTS; i++) { - if (bge_newbuf_std(sc, i, NULL, 0) == ENOBUFS) + if (bge_newbuf_std(sc, i, NULL, 0) == ENOBUFS) { + aprint_error_dev(sc->bge_dev, + "%s: bge_newbuf_std failed: ENOBUFS\n", __func__); return ENOBUFS; + } } sc->bge_std = i - 1; @@ -1493,8 +1515,11 @@ bge_init_rx_ring_jumbo(struct bge_softc return 0; for (i = 0; i < BGE_JUMBO_RX_RING_CNT; i++) { - if (bge_newbuf_jumbo(sc, i, NULL) == ENOBUFS) + if (bge_newbuf_jumbo(sc, i, NULL) == ENOBUFS) { + aprint_error_dev(sc->bge_dev, + "%s: bge_newbuf_jumbo failed: ENOBUFS\n", __func__); return ENOBUFS; + } }; sc->bge_jumbo = i - 1; @@ -1569,6 +1594,7 @@ bge_init_tx_ring(struct bge_softc *sc) bus_dmamap_t dmamap; struct txdmamap_pool_entry *dma; + if (sc->bge_flags & BGE_TXRING_VALID) return 0; @@ -1593,7 +1619,12 @@ bge_init_tx_ring(struct bge_softc *sc) if (bus_dmamap_create(sc->bge_dmatag, BGE_TXDMA_MAX, BGE_NTXSEG, ETHER_MAX_LEN_JUMBO, 0, BUS_DMA_NOWAIT, &dmamap)) + { + aprint_error_dev(sc->bge_dev, + "%s: bus_dmamap_create failed: ENOBUFS\n", + __func__); return ENOBUFS; + } if (dmamap == NULL) panic("dmamap NULL in bge_init_tx_ring"); dma = malloc(sizeof(*dma), M_DEVBUF, M_NOWAIT); @@ -2647,12 +2678,14 @@ bge_attach(device_t parent, device_t sel bge_set_max_readrq(sc); } else if ((pci_conf_read(sc->sc_pc, sc->sc_pcitag, BGE_PCI_PCISTATE) & BGE_PCISTATE_PCI_BUSMODE) == 0) { - /* PCI-X */ - sc->bge_flags |= BGE_PCIX; if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PCIX, - &sc->bge_pcixcap, NULL) == 0) + &sc->bge_pcixcap, NULL) == 0) { aprint_error_dev(sc->bge_dev, "unable to find PCIX capability\n"); + } else { + /* PCI-X */ + sc->bge_flags |= BGE_PCIX; + } } /* chipid */ @@ -2820,6 +2853,20 @@ bge_attach(device_t parent, device_t sel } } +#if 0 +// if (bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_NICCFG) & BGE_HWCFG_ASF) { + if (1) { + printf("hwcfg: ASF\n"); + sc->bge_asf_mode |= ASF_ENABLE; + sc->bge_asf_mode |= ASF_STACKUP; +#if 1 + if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5785) { + sc->bge_asf_mode |= ASF_NEW_HANDSHAKE; + } +#endif + } +#endif + /* Try to reset the chip again the nice way. */ bge_stop_fw(sc); bge_sig_pre_reset(sc, BGE_RESET_STOP); @@ -3421,7 +3468,7 @@ bge_rxeof(struct bge_softc *sc) if (bge_newbuf_jumbo(sc, sc->bge_jumbo, NULL)== ENOBUFS) { ifp->if_ierrors++; - bge_newbuf_jumbo(sc, sc->bge_jumbo, m); + KASSERT(bge_newbuf_jumbo(sc, sc->bge_jumbo, m) != ENOBUFS); continue; } } else { @@ -3431,6 +3478,11 @@ bge_rxeof(struct bge_softc *sc) sc->bge_cdata.bge_rx_std_chain[rxidx] = NULL; stdcnt++; dmamap = sc->bge_cdata.bge_rx_std_map[rxidx]; + if (dmamap == NULL) { + ifp->if_ierrors++; + bge_newbuf_std(sc, sc->bge_std, m, dmamap); + continue; + } sc->bge_cdata.bge_rx_std_map[rxidx] = 0; if (dmamap == NULL) { ifp->if_ierrors++; @@ -3448,7 +3500,7 @@ bge_rxeof(struct bge_softc *sc) if (bge_newbuf_std(sc, sc->bge_std, NULL, dmamap) == ENOBUFS) { ifp->if_ierrors++; - bge_newbuf_std(sc, sc->bge_std, m, dmamap); + KASSERT(bge_newbuf_std(sc, sc->bge_std, m, dmamap) != ENOBUFS); continue; } } @@ -3467,7 +3519,11 @@ bge_rxeof(struct bge_softc *sc) } #endif - m->m_pkthdr.len = m->m_len = cur_rx->bge_len - ETHER_CRC_LEN; + if (cur_rx->bge_len >= ETHER_CRC_LEN) + m->m_pkthdr.len = m->m_len = cur_rx->bge_len - ETHER_CRC_LEN; + else + m->m_pkthdr.len = m->m_len = 0; + m->m_pkthdr.rcvif = ifp; /* @@ -3524,6 +3580,11 @@ bge_txeof(struct bge_softc *sc) int tosync; struct mbuf *m; + /* Nothing to do */ + if (sc->bge_tx_saved_considx == + sc->bge_rdata->bge_status_block.bge_idx[0].bge_tx_cons_idx) + return; + ifp = &sc->ethercom.ec_if; bus_dmamap_sync(sc->bge_dmatag, sc->bge_ring_map, @@ -3578,11 +3639,13 @@ bge_txeof(struct bge_softc *sc) } sc->bge_txcnt--; BGE_INC(sc->bge_tx_saved_considx, BGE_TX_RING_CNT); - ifp->if_timer = 0; } - if (cur_tx != NULL) + if (sc->bge_txcnt < BGE_TX_RING_CNT - 16) { ifp->if_flags &= ~IFF_OACTIVE; + } + if (sc->bge_txcnt == 0) + ifp->if_timer = 0; } static int @@ -3602,6 +3665,8 @@ bge_intr(void *xsc) */ /* read status word from status block */ + KASSERT(sc != NULL); + KASSERT(sc->bge_rdata != NULL); statusword = sc->bge_rdata->bge_status_block.bge_status; if ((statusword & BGE_STATFLAG_UPDATED) || @@ -3646,9 +3711,7 @@ bge_intr(void *xsc) /* Re-enable interrupts. */ bge_writembx(sc, BGE_MBX_IRQ0_LO, 0); - - if (ifp->if_flags & IFF_RUNNING && !IFQ_IS_EMPTY(&ifp->if_snd)) - bge_start(ifp); + bge_start(ifp); return 1; } else @@ -3802,8 +3865,10 @@ bge_cksum_pad(struct mbuf *pkt) /* Allocate new empty mbuf, pad it. Compact later. */ struct mbuf *n; MGET(n, M_DONTWAIT, MT_DATA); - if (n == NULL) + if (n == NULL) { + printf("%s: MGET failed: ENOBUFS\n", __func__); return ENOBUFS; + } n->m_len = 0; last->m_next = n; last = n; @@ -3900,8 +3965,11 @@ bge_compact_dma_runt(struct mbuf *pkt) int newprevlen = prev->m_len - shortfall; MGET(n, M_NOWAIT, MT_DATA); - if (n == NULL) - return ENOBUFS; + if (n == NULL) { + printf("%s: MGET failed: ENOBUFS\n", + __func__); + return ENOBUFS; + } KASSERT(m->m_len + shortfall < MLEN /*, ("runt %d +prev %d too big\n", m->m_len, shortfall)*/); @@ -3974,8 +4042,11 @@ bge_encap(struct bge_softc *sc, struct m m_head->m_pkthdr.len >= ETHER_MIN_NOPAD) goto check_dma_bug; - if (bge_cksum_pad(m_head) != 0) - return ENOBUFS; + if (bge_cksum_pad(m_head) != 0) { + aprint_error_dev(sc->bge_dev, + "%s: bge_cksum_pad failed: ENOBUFS\n", __func__); + return ENOBUFS; + } check_dma_bug: if (!(BGE_CHIPREV(sc->bge_chipid) == BGE_CHIPREV_5700_BX)) @@ -3986,13 +4057,19 @@ check_dma_bug: * less than eight bytes. If we encounter a teeny mbuf * at the end of a chain, we can pad. Otherwise, copy. */ - if (bge_compact_dma_runt(m_head) != 0) + if (bge_compact_dma_runt(m_head) != 0) { + aprint_error_dev(sc->bge_dev, + "%s: bge_compact_dma_runt failed: ENOBUFS\n", __func__); return ENOBUFS; + } doit: dma = SLIST_FIRST(&sc->txdma_list); - if (dma == NULL) + if (dma == NULL) { + aprint_error_dev(sc->bge_dev, + "%s: txdma_list empty: ENOBUFS\n", __func__); return ENOBUFS; + } dmamap = dma->dmamap; /* @@ -4029,6 +4106,9 @@ doit: /* * Don't support this protocol or encapsulation. */ + aprint_error_dev(sc->bge_dev, + "%s: no support for ethertype %d\n", + __func__, htons(eh->ether_type)); return ENOBUFS; } @@ -4075,6 +4155,7 @@ doit: */ (void) ip; (void)th; (void) ip_tcp_hlen; + aprint_error_dev(sc->bge_dev, "%s: ENOBUFS\n", __func__); return ENOBUFS; #endif } else { @@ -4138,13 +4219,15 @@ doit: */ error = bus_dmamap_load_mbuf(sc->bge_dmatag, dmamap, m_head, BUS_DMA_NOWAIT); - if (error) + if (error) { + aprint_error_dev(sc->bge_dev, + "%s: bus_dmamap_load_mbuf failed %i: ENOBUFS\n", + __func__, error); return ENOBUFS; - /* - * Sanity check: avoid coming within 16 descriptors - * of the end of the ring. - */ - if (dmamap->dm_nsegs > (BGE_TX_RING_CNT - sc->bge_txcnt - 16)) { + } + + /* Check if we have enough free send BDs. */ + if (sc->bge_txcnt + dmamap->dm_nsegs >= BGE_TX_RING_CNT) { BGE_TSO_PRINTF(("%s: " " dmamap_load_mbuf too close to ring wrap\n", device_xname(sc->bge_dev))); @@ -4223,6 +4306,7 @@ doit: fail_unload: bus_dmamap_unload(sc->bge_dmatag, dmamap); + aprint_error_dev(sc->bge_dev, "%s: ENOBUFS\n", __func__); return ENOBUFS; } @@ -4242,10 +4326,17 @@ bge_start(struct ifnet *ifp) if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING) return; + if (!BGE_STS_BIT(sc, BGE_STS_LINK)) + return; prodidx = sc->bge_tx_prodidx; - while (sc->bge_cdata.bge_tx_chain[prodidx] == NULL) { + for (pkts = 0; !IFQ_IS_EMPTY(&ifp->if_snd);) { + if (sc->bge_txcnt > BGE_TX_RING_CNT - 16) { + ifp->if_flags |= IFF_OACTIVE; + break; + } + IFQ_POLL(&ifp->if_snd, m_head); if (m_head == NULL) break; @@ -4279,6 +4370,7 @@ bge_start(struct ifnet *ifp) break; } + /* now we are committed to transmit the packet */ IFQ_DEQUEUE(&ifp->if_snd, m_head); pkts++; Index: sys/dev/pci/pci_map.c =================================================================== RCS file: /cvsroot/src/sys/dev/pci/pci_map.c,v retrieving revision 1.30 diff -u -p -r1.30 pci_map.c --- sys/dev/pci/pci_map.c 20 Oct 2012 06:03:38 -0000 1.30 +++ sys/dev/pci/pci_map.c 25 Oct 2012 14:05:58 -0000 @@ -224,6 +224,9 @@ pci_mem_find(pci_chipset_tag_t pc, pcita *flagsp = (isrom || PCI_MAPREG_MEM_PREFETCHABLE(address)) ? BUS_SPACE_MAP_PREFETCHABLE : 0; + if (basep && *basep > 0xffffffff) + printf("%s: base 0x%"PRIx64"\n", __func__, (uint64_t)*basep); + return 0; } @@ -309,6 +312,10 @@ pci_mapreg_submap(const struct pci_attac tag = pa->pa_memt; } + if (base > 0xffffffff) + printf("%s: base 0x%"PRIx64", size 0x%"PRIx64"\n", + __func__, (uint64_t)base, (uint64_t)size); + if (reg == PCI_MAPREG_ROM) { pcireg_t mask; int s; Index: sys/dev/pci/pucdata.c =================================================================== RCS file: /cvsroot/src/sys/dev/pci/pucdata.c,v retrieving revision 1.82 diff -u -p -r1.82 pucdata.c --- sys/dev/pci/pucdata.c 18 Oct 2012 10:41:44 -0000 1.82 +++ sys/dev/pci/pucdata.c 25 Oct 2012 14:05:58 -0000 @@ -993,6 +993,28 @@ const struct puc_device_description puc_ * I/O Flex PCI I/O Card Model-223 with 4 serial and 1 parallel ports. */ + /* Oxford Semiconductor OX16PCI954 PCI UARTs */ + { "Oxford Semiconductor OX16PCI954 UARTs", + { PCI_VENDOR_OXFORDSEMI, 0x9500, 0, 0 }, + { 0xffff, 0xffff, 0, 0 }, + { + { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ}, + { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ}, + }, + }, + + /* Oxford Semiconductor OX16PCI954 PCI UARTs */ + { "Oxford Semiconductor OX16PCI954 UARTs", + { PCI_VENDOR_OXFORDSEMI, 0x9501, 0, 0 }, + { 0xffff, 0xffff, 0, 0 }, + { + { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ}, + { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ}, + { PUC_PORT_TYPE_COM, 0x10, 0x10, COM_FREQ}, + { PUC_PORT_TYPE_COM, 0x10, 0x18, COM_FREQ}, + }, + }, + /* Oxford Semiconductor OXPCIe952 PCIe UARTs */ { "Oxford Semiconductor OXPCIe952 UARTs", { PCI_VENDOR_OXFORDSEMI, PCI_PRODUCT_OXFORDSEMI_OXPCIE952, Index: sys/net/if_bridge.c =================================================================== RCS file: /cvsroot/src/sys/net/if_bridge.c,v retrieving revision 1.76 diff -u -p -r1.76 if_bridge.c --- sys/net/if_bridge.c 22 Mar 2012 12:59:33 -0000 1.76 +++ sys/net/if_bridge.c 25 Oct 2012 14:06:00 -0000 @@ -1284,6 +1284,8 @@ bridge_output(struct ifnet *ifp, struct } else { mc = m_copym(m, 0, M_COPYALL, M_NOWAIT); if (mc == NULL) { + aprint_error("%s:%s: m_copym(%p) failed\n", + sc->sc_if.if_xname, __func__, m); sc->sc_if.if_oerrors++; continue; } @@ -1631,6 +1633,8 @@ bridge_broadcast(struct bridge_softc *sc } else { mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT); if (mc == NULL) { + aprint_error("%s:%s: m_copym(%p) failed\n", + sc->sc_if.if_xname, __func__, m); sc->sc_if.if_oerrors++; continue; } Index: sys/net/radix.c =================================================================== RCS file: /cvsroot/src/sys/net/radix.c,v retrieving revision 1.44 diff -u -p -r1.44 radix.c --- sys/net/radix.c 17 Jul 2011 20:54:52 -0000 1.44 +++ sys/net/radix.c 25 Oct 2012 14:06:00 -0000 @@ -558,12 +558,15 @@ rn_lexobetter( const u_char *lim; if (*mp > *np) - return 1; /* not really, but need to check longer one first */ - if (*mp == *np) - for (lim = mp + *mp; mp < lim;) - if (*mp++ > *np++) - return 1; - return 0; + return 1; + if (*mp < *np) + return 0; + /* + * Must return the first difference between the masks + * to ensure deterministic sorting. + */ + lim = mp + *mp; + return (memcmp(mp, np, *lim) > 0); } static struct radix_mask * Index: sys/netinet/tcp_input.c =================================================================== RCS file: /cvsroot/src/sys/netinet/tcp_input.c,v retrieving revision 1.325 diff -u -p -r1.325 tcp_input.c --- sys/netinet/tcp_input.c 22 Jun 2012 15:09:36 -0000 1.325 +++ sys/netinet/tcp_input.c 25 Oct 2012 14:06:00 -0000 @@ -2536,8 +2536,8 @@ after_listen: */ if (tiflags & TH_SYN) { if (tp->rcv_nxt == th->th_seq) { - tcp_respond(tp, m, m, th, (tcp_seq)0, th->th_ack - 1, - TH_ACK); + tcp_respond(tp, mtod(m, void *), m, th, + (tcp_seq)0, th->th_ack - 1, TH_ACK); if (tcp_saveti) m_freem(tcp_saveti); return; @@ -3086,12 +3086,13 @@ dropwithreset: } if (tiflags & TH_ACK) - (void)tcp_respond(tp, m, m, th, (tcp_seq)0, th->th_ack, TH_RST); + (void)tcp_respond(tp, mtod(m, void *), m, th, + (tcp_seq)0, th->th_ack, TH_RST); else { if (tiflags & TH_SYN) tlen++; - (void)tcp_respond(tp, m, m, th, th->th_seq + tlen, (tcp_seq)0, - TH_RST|TH_ACK); + (void)tcp_respond(tp, mtod(m, void *), m, th, + th->th_seq + tlen, (tcp_seq)0, TH_RST|TH_ACK); } if (tcp_saveti) m_freem(tcp_saveti); @@ -4229,7 +4230,8 @@ syn_cache_get(struct sockaddr *src, stru return (so); resetandabort: - (void)tcp_respond(NULL, m, m, th, (tcp_seq)0, th->th_ack, TH_RST); + (void)tcp_respond(NULL, mtod(m, void *), m, th, + (tcp_seq)0, th->th_ack, TH_RST); abort: if (so != NULL) { (void) soqremque(so, 1); Index: sys/netinet/tcp_subr.c =================================================================== RCS file: /cvsroot/src/sys/netinet/tcp_subr.c,v retrieving revision 1.248 diff -u -p -r1.248 tcp_subr.c --- sys/netinet/tcp_subr.c 8 Sep 2012 02:58:13 -0000 1.248 +++ sys/netinet/tcp_subr.c 25 Oct 2012 14:06:00 -0000 @@ -606,7 +606,7 @@ tcp_template(struct tcpcb *tp) * segment are as specified by the parameters. */ int -tcp_respond(struct tcpcb *tp, struct mbuf *template, struct mbuf *m, +tcp_respond(struct tcpcb *tp, void *template, struct mbuf *m, struct tcphdr *th0, tcp_seq ack, tcp_seq seq, int flags) { #ifdef INET6 @@ -648,7 +648,7 @@ tcp_respond(struct tcpcb *tp, struct mbu return EINVAL; /* get family information from template */ - switch (mtod(template, struct ip *)->ip_v) { + switch (((struct ip *)(template))->ip_v) { case 4: family = AF_INET; hlen = sizeof(struct ip); @@ -681,17 +681,17 @@ tcp_respond(struct tcpcb *tp, struct mbu tlen = 0; m->m_data += max_linkhdr; - bcopy(mtod(template, void *), mtod(m, void *), - template->m_len); switch (family) { case AF_INET: ip = mtod(m, struct ip *); th = (struct tcphdr *)(ip + 1); + memcpy(ip, template, sizeof(*ip)); break; #ifdef INET6 case AF_INET6: ip6 = mtod(m, struct ip6_hdr *); th = (struct tcphdr *)(ip6 + 1); + memcpy(ip6, template, sizeof(*ip6)); break; #endif #if 0 Index: sys/netinet/tcp_timer.c =================================================================== RCS file: /cvsroot/src/sys/netinet/tcp_timer.c,v retrieving revision 1.86 diff -u -p -r1.86 tcp_timer.c --- sys/netinet/tcp_timer.c 31 Aug 2011 18:31:03 -0000 1.86 +++ sys/netinet/tcp_timer.c 25 Oct 2012 14:06:00 -0000 @@ -567,11 +567,11 @@ tcp_timer_keep(void *arg) * The keepalive packet must have nonzero * length to get a 4.2 host to respond. */ - (void)tcp_respond(tp, tp->t_template, + (void)tcp_respond(tp, mtod(tp->t_template, void *), NULL, NULL, tp->rcv_nxt - 1, tp->snd_una - 1, 0); } else { - (void)tcp_respond(tp, tp->t_template, + (void)tcp_respond(tp, mtod(tp->t_template, void *), NULL, NULL, tp->rcv_nxt, tp->snd_una - 1, 0); } Index: sys/netinet/tcp_var.h =================================================================== RCS file: /cvsroot/src/sys/netinet/tcp_var.h,v retrieving revision 1.169 diff -u -p -r1.169 tcp_var.h --- sys/netinet/tcp_var.h 2 Feb 2012 19:43:08 -0000 1.169 +++ sys/netinet/tcp_var.h 25 Oct 2012 14:06:00 -0000 @@ -935,7 +935,7 @@ void tcpipqent_init(void); struct ipqent *tcpipqent_alloc(void); void tcpipqent_free(struct ipqent *); -int tcp_respond(struct tcpcb *, struct mbuf *, struct mbuf *, +int tcp_respond(struct tcpcb *, void *, struct mbuf *, struct tcphdr *, tcp_seq, tcp_seq, int); void tcp_rmx_rtt(struct tcpcb *); void tcp_setpersist(struct tcpcb *); Index: sys/nfs/nfs_serv.c =================================================================== RCS file: /cvsroot/src/sys/nfs/nfs_serv.c,v retrieving revision 1.165 diff -u -p -r1.165 nfs_serv.c --- sys/nfs/nfs_serv.c 29 Aug 2012 14:00:22 -0000 1.165 +++ sys/nfs/nfs_serv.c 25 Oct 2012 14:06:00 -0000 @@ -473,6 +473,12 @@ nfsrv_lookup(struct nfsrv_descript *nfsd nfsm_srvpostop_attr(dirattr_ret, &dirattr); return (0); } + if (nd.ni_pathbuf != NULL) { + pathbuf_destroy(nd.ni_pathbuf); + } + if (ipb != NULL) { + pathbuf_destroy(ipb); + } nqsrv_getl(ndp->ni_startdir, ND_READ); pathbuf_destroy(nd.ni_pathbuf); Index: sys/nfs/nfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/nfs/nfs_vnops.c,v retrieving revision 1.295 diff -u -p -r1.295 nfs_vnops.c --- sys/nfs/nfs_vnops.c 22 Jul 2012 00:53:21 -0000 1.295 +++ sys/nfs/nfs_vnops.c 25 Oct 2012 14:06:01 -0000 @@ -1266,7 +1266,7 @@ nfs_writerpc(struct vnode *vp, struct ui char *cp; int32_t t1, t2; char *bpos, *dpos; - struct mbuf *mreq, *mrep, *md, *mb; + struct mbuf *mreq = NULL, *mrep, *md, *mb; struct nfsmount *nmp = VFSTONFS(vp->v_mount); int error = 0, len, tsiz, wccflag = NFSV3_WCCRATTR; const int v3 = NFS_ISV3(vp); @@ -1279,6 +1279,7 @@ nfs_writerpc(struct vnode *vp, struct ui char *cp2; int rlen, commit; #endif + struct mbuf *mbnext = NULL; if (vp->v_mount->mnt_flag & MNT_RDONLY) { panic("writerpc readonly vp %p", vp); @@ -1350,6 +1351,7 @@ retry: m->m_flags |= M_EXT_ROMAP; m->m_len = len; mb->m_next = m; + mbnext = m; /* * no need to maintain mb and bpos here * because no one care them later. @@ -1462,7 +1464,16 @@ nfsmout: mutex_enter(&ctx.nwc_lock); ctx.nwc_mbufcount--; while (ctx.nwc_mbufcount > 0) { - cv_wait(&ctx.nwc_cv, &ctx.nwc_lock); + error = cv_timedwait(&ctx.nwc_cv, &ctx.nwc_lock, + mstohz(1000)); + if (error) { + printf("nfsmblk timeout, mbufcount %i, mb %p, mreq %p, mrep %p, md %p, mb->m_next %p\n", + ctx.nwc_mbufcount, mb, mreq, mrep, md, mbnext); + mutex_exit(&ctx.nwc_lock); + Debugger(); + mutex_enter(&ctx.nwc_lock); + continue; + } } mutex_exit(&ctx.nwc_lock); } Index: sys/sys/kmemset.h =================================================================== RCS file: sys/sys/kmemset.h diff -N sys/sys/kmemset.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/sys/kmemset.h 25 Oct 2012 14:06:01 -0000 @@ -0,0 +1,70 @@ +/* $NetBSD: $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christoph Egger + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SYS_KMEMSET_H_ +#define _SYS_KMEMSET_H_ + +struct kmemset; +typedef struct kmemset kmemset_t; + +#ifdef _KERNEL + +void kmemset_sysinit(void); + +void kmemset_create(kmemset_t **, bool); +void kmemset_destroy(kmemset_t *); +void kmemset_copy(kmemset_t *, kmemset_t *); + +void kmemset_use(kmemset_t *); +void kmemset_unuse(kmemset_t *, kmemset_t **); + +#if 0 +int kmemset_copyin(const memset_t *, kmemset_t *, size_t); +int kmemset_copyout(kmemset_t *, memset_t *, size_t); +#endif + +void kmemset_zero(kmemset_t *); +void kmemset_fill(kmemset_t *); +void kmemset_set(kmemset_t *, paddr_t, paddr_t); +void kmemset_clear(kmemset_t *, paddr_t, paddr_t); + +bool kmemset_iszero(kmemset_t *); +bool kmemset_match(const kmemset_t *, const kmemset_t *); +void kmemset_merge(kmemset_t *, kmemset_t *); +void kmemset_intersect(kmemset_t *, kmemset_t *); +size_t kmemset_countset(kmemset_t *); + +void kmemset_atomic_set(kmemset_t *, paddr_t, paddr_t); +void kmemset_atomic_clear(kmemset_t *, paddr_t, paddr_t); + +#endif + +#endif /* _SYS_KMEMSET_H_ */ Index: sys/sys/knumaset.h =================================================================== RCS file: sys/sys/knumaset.h diff -N sys/sys/knumaset.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/sys/knumaset.h 25 Oct 2012 14:06:01 -0000 @@ -0,0 +1,76 @@ +/* $NetBSD: $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christoph Egger + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SYS_KNUMASET_H_ +#define _SYS_KNUMASET_H_ + +struct knumaset; +typedef struct knumaset knumaset_t; + +#ifdef _KERNEL + +void knumaset_sysinit(void); + +void knumaset_create(knumaset_t **, bool); +void knumaset_destroy(knumaset_t *); +void knumaset_copy(knumaset_t *, knumaset_t *); + +void knumaset_use(knumaset_t *); +void knumaset_unuse(knumaset_t *, knumaset_t **); + +#if 0 +int knumaset_copyin(const numaset_t *, knumaset_t *, size_t); +int knumaset_copyout(knumaset_t *, numaset_t *, size_t); +#endif + +void knumaset_mem_zero(knumaset_t *); +void knumaset_mem_fill(knumaset_t *); +void knumaset_mem_set(knumaset_t *, paddr_t, paddr_t); +void knumaset_mem_clear(knumaset_t *, paddr_t, paddr_t); + +void knumaset_cpu_zero(knumaset_t *); +void knumaset_cpu_fill(knumaset_t *); +void knumaset_cpu_set(knumaset_t *, kcpuset_t *); +void knumaset_cpu_clear(knumaset_t *, kcpuset_t *); + +bool knumaset_cpu_isset(knumaset_t *, kcpuset_t *); +bool knumaset_iszero(knumaset_t *); +bool knumaset_match(const knumaset_t *, const knumaset_t *); +void knumaset_merge(knumaset_t *, knumaset_t *); +void knumaset_intersect(knumaset_t *, knumaset_t *); +int knumaset_countset(knumaset_t *); + +void knumaset_atomic_set(knumaset_t *, kcpuset_t *); +void knumaset_atomic_clear(knumaset_t *, kcpuset_t *); + +#endif + +#endif /* _SYS_KNUMASET_H_ */