From owner-p4-projects@FreeBSD.ORG Tue Jan 14 19:00:21 2014 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 4B1DEB65; Tue, 14 Jan 2014 19:00:21 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id CADB2B5C for ; Tue, 14 Jan 2014 19:00:20 +0000 (UTC) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:1900:2254:2068::682:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id AE94C1449 for ; Tue, 14 Jan 2014 19:00:20 +0000 (UTC) Received: from skunkworks.freebsd.org ([127.0.1.74]) by skunkworks.freebsd.org (8.14.7/8.14.7) with ESMTP id s0EJ0K2i020416 for ; Tue, 14 Jan 2014 19:00:20 GMT (envelope-from jhb@freebsd.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.7/8.14.7/Submit) id s0EJ0K11020412 for perforce@freebsd.org; Tue, 14 Jan 2014 19:00:20 GMT (envelope-from jhb@freebsd.org) Date: Tue, 14 Jan 2014 19:00:20 GMT Message-Id: <201401141900.s0EJ0K11020412@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to jhb@freebsd.org using -f From: John Baldwin Subject: PERFORCE change 1190026 for review To: Perforce Change Reviews Precedence: bulk X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.17 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 14 Jan 2014 19:00:21 -0000 http://p4web.freebsd.org/@@1190026?ac=10 Change 1190026 by jhb@jhb_jhbbsd on 2014/01/14 19:00:04 Catch up. Affected files ... .. //depot/projects/pci/sys/dev/alc/if_alc.c#7 edit Differences ... ==== //depot/projects/pci/sys/dev/alc/if_alc.c#7 (text+ko) ==== @@ -841,9 +841,9 @@ device_printf(dev, "RCB %u bytes\n", sc->alc_rcb == DMA_CFG_RCB_64 ? 64 : 128); state = ctl & PCIEM_LINK_CTL_ASPMC; - if (state & PCIEM_LINK_CTL_ASPMC_L0S) + if (state & PCIEM_LINK_ASPMC_L0S) sc->alc_flags |= ALC_FLAG_L0S; - if (state & PCIEM_LINK_CTL_ASPMC_L1) + if (state & PCIEM_LINK_ASPMC_L1) sc->alc_flags |= ALC_FLAG_L1S; if (bootverbose) device_printf(sc->alc_dev, "ASPM %s %s\n", From owner-p4-projects@FreeBSD.ORG Tue Jan 14 19:06:28 2014 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 6A9F9FFA; Tue, 14 Jan 2014 19:06:28 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 28AA8F24 for ; Tue, 14 Jan 2014 19:06:28 +0000 (UTC) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:1900:2254:2068::682:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id ECAA81502 for ; Tue, 14 Jan 2014 19:06:27 +0000 (UTC) Received: from skunkworks.freebsd.org ([127.0.1.74]) by skunkworks.freebsd.org (8.14.7/8.14.7) with ESMTP id s0EJ6RxQ021790 for ; Tue, 14 Jan 2014 19:06:27 GMT (envelope-from jhb@freebsd.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.7/8.14.7/Submit) id s0EJ6RPE021787 for perforce@freebsd.org; Tue, 14 Jan 2014 19:06:27 GMT (envelope-from jhb@freebsd.org) Date: Tue, 14 Jan 2014 19:06:27 GMT Message-Id: <201401141906.s0EJ6RPE021787@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to jhb@freebsd.org using -f From: John Baldwin Subject: PERFORCE change 1190028 for review To: Perforce Change Reviews Precedence: bulk X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.17 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 14 Jan 2014 19:06:28 -0000 http://p4web.freebsd.org/@@1190028?ac=10 Change 1190028 by jhb@jhb_jhbbsd on 2014/01/14 19:06:26 Building hack for this branch. Affected files ... .. //depot/projects/pci/usr.sbin/pciconf/Makefile#2 edit Differences ... ==== //depot/projects/pci/usr.sbin/pciconf/Makefile#2 (text+ko) ==== @@ -5,6 +5,8 @@ SRCS= pciconf.c cap.c err.c MAN= pciconf.8 +CFLAGS+= -I${.CURDIR}/../../sys + WARNS?= 3 .include From owner-p4-projects@FreeBSD.ORG Tue Jan 14 19:06:28 2014 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 29C22F26; Tue, 14 Jan 2014 19:06:28 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id DFB84F23 for ; Tue, 14 Jan 2014 19:06:27 +0000 (UTC) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:1900:2254:2068::682:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id C7FD31501 for ; Tue, 14 Jan 2014 19:06:27 +0000 (UTC) Received: from skunkworks.freebsd.org ([127.0.1.74]) by skunkworks.freebsd.org (8.14.7/8.14.7) with ESMTP id s0EJ6RxN021784 for ; Tue, 14 Jan 2014 19:06:27 GMT (envelope-from jhb@freebsd.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.7/8.14.7/Submit) id s0EJ6Rt6021781 for perforce@freebsd.org; Tue, 14 Jan 2014 19:06:27 GMT (envelope-from jhb@freebsd.org) Date: Tue, 14 Jan 2014 19:06:27 GMT Message-Id: <201401141906.s0EJ6Rt6021781@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to jhb@freebsd.org using -f From: John Baldwin Subject: PERFORCE change 1190027 for review To: Perforce Change Reviews Precedence: bulk X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.17 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 14 Jan 2014 19:06:28 -0000 http://p4web.freebsd.org/@@1190027?ac=10 Change 1190027 by jhb@jhb_jhbbsd on 2014/01/14 19:06:15 Add support for listing VPD fields in userland. - Explicitly track the length of read-only VPD keyword values as they are not always ASCII. - Add an ioctl to fetch the list of VPD keywords for a given PCI device. - Add -V flag to dump VPD fields for each device. - Allow the -l option to accept an optional selector so that details are listed for a single device instead of all. Affected files ... .. //depot/projects/pci/sys/dev/pci/pci.c#49 edit .. //depot/projects/pci/sys/dev/pci/pci_user.c#7 edit .. //depot/projects/pci/sys/dev/pci/pcivar.h#15 edit .. //depot/projects/pci/sys/sys/pciio.h#3 edit .. //depot/projects/pci/usr.sbin/pciconf/pciconf.c#2 edit Differences ... ==== //depot/projects/pci/sys/dev/pci/pci.c#49 (text+ko) ==== @@ -1011,7 +1011,7 @@ state = -2; break; } - dflen = byte2; + cfg->vpd.vpd_ros[off].len = dflen = byte2; if (dflen == 0 && strncmp(cfg->vpd.vpd_ros[off].keyword, "RV", 2) == 0) { @@ -1205,6 +1205,17 @@ return (ENXIO); } +struct pcicfg_vpd * +pci_fetch_vpd_list(device_t dev) +{ + struct pci_devinfo *dinfo = device_get_ivars(dev); + pcicfgregs *cfg = &dinfo->cfg; + + if (!cfg->vpd.vpd_cached && cfg->vpd.vpd_reg != 0) + pci_read_vpd(device_get_parent(device_get_parent(dev)), cfg); + return (&cfg->vpd); +} + /* * Find the requested HyperTransport capability and return the offset * in configuration space via the pointer provided. The function ==== //depot/projects/pci/sys/dev/pci/pci_user.c#7 (text+ko) ==== @@ -407,6 +407,89 @@ #endif /* PRE7_COMPAT */ static int +pci_list_vpd(device_t dev, struct pci_list_vpd_io *lvio) +{ + struct pci_vpd_element vpd_element, *vpd_user; + struct pcicfg_vpd *vpd; + size_t len; + int error, i; + + vpd = pci_fetch_vpd_list(dev); + if (vpd->vpd_reg == 0 || vpd->vpd_ident == NULL) + return (ENXIO); + + /* + * Calculate the amount of space needed in the data buffer. An + * identifier element is always present followed by the read-only + * and read-write keywords. + */ + len = sizeof(struct pci_vpd_element) + strlen(vpd->vpd_ident); + for (i = 0; i < vpd->vpd_rocnt; i++) + len += sizeof(struct pci_vpd_element) + vpd->vpd_ros[i].len; + for (i = 0; i < vpd->vpd_wcnt; i++) + len += sizeof(struct pci_vpd_element) + vpd->vpd_w[i].len; + + if (lvio->plvi_len == 0) { + lvio->plvi_len = len; + return (0); + } + if (lvio->plvi_len < len) { + lvio->plvi_len = len; + return (ENOMEM); + } + + /* + * Copyout the identifier string followed by each keyword and + * value. + */ + vpd_user = lvio->plvi_data; + vpd_element.pve_keyword[0] = '\0'; + vpd_element.pve_keyword[1] = '\0'; + vpd_element.pve_flags = PVE_FLAG_IDENT; + vpd_element.pve_datalen = strlen(vpd->vpd_ident); + error = copyout(&vpd_element, vpd_user, sizeof(vpd_element)); + if (error) + return (error); + error = copyout(vpd->vpd_ident, vpd_user->pve_data, + strlen(vpd->vpd_ident)); + if (error) + return (error); + vpd_user = PVE_NEXT(vpd_user); + vpd_element.pve_flags = 0; + for (i = 0; i < vpd->vpd_rocnt; i++) { + vpd_element.pve_keyword[0] = vpd->vpd_ros[i].keyword[0]; + vpd_element.pve_keyword[1] = vpd->vpd_ros[i].keyword[1]; + vpd_element.pve_datalen = vpd->vpd_ros[i].len; + error = copyout(&vpd_element, vpd_user, sizeof(vpd_element)); + if (error) + return (error); + error = copyout(vpd->vpd_ros[i].value, vpd_user->pve_data, + vpd->vpd_ros[i].len); + if (error) + return (error); + vpd_user = PVE_NEXT(vpd_user); + } + vpd_element.pve_flags = PVE_FLAG_RW; + for (i = 0; i < vpd->vpd_wcnt; i++) { + vpd_element.pve_keyword[0] = vpd->vpd_w[i].keyword[0]; + vpd_element.pve_keyword[1] = vpd->vpd_w[i].keyword[1]; + vpd_element.pve_datalen = vpd->vpd_w[i].len; + error = copyout(&vpd_element, vpd_user, sizeof(vpd_element)); + if (error) + return (error); + error = copyout(vpd->vpd_w[i].value, vpd_user->pve_data, + vpd->vpd_w[i].len); + if (error) + return (error); + vpd_user = PVE_NEXT(vpd_user); + } + KASSERT((char *)vpd_user - (char *)lvio->plvi_data == len, + ("length mismatch")); + lvio->plvi_len = len; + return (0); +} + +static int pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td) { device_t pcidev, brdev; @@ -417,6 +500,7 @@ struct pci_devinfo *dinfo; struct pci_io *io; struct pci_bar_io *bio; + struct pci_list_vpd_io *lvio; struct pci_match_conf *pattern_buf; struct pci_map *pm; size_t confsz, iolen, pbufsz; @@ -433,19 +517,29 @@ struct pci_match_conf_old *pattern_buf_old = NULL; io_old = NULL; +#endif - if (!(flag & FWRITE) && cmd != PCIOCGETBAR && - cmd != PCIOCGETCONF && cmd != PCIOCGETCONF_OLD) - return EPERM; -#else - if (!(flag & FWRITE) && cmd != PCIOCGETBAR && cmd != PCIOCGETCONF) - return EPERM; + if (!(flag & FWRITE)) { + switch (cmd) { +#ifdef PRE7_COMPAT +#ifdef COMPAT_FREEBSD32 + case PCIOCGETCONF_OLD32: +#endif + case PCIOCGETCONF_OLD: #endif + case PCIOCGETCONF: + case PCIOCGETBAR: + case PCIOCLISTVPD: + break; + default: + return (EPERM); + } + } - switch(cmd) { + switch (cmd) { #ifdef PRE7_COMPAT #ifdef COMPAT_FREEBSD32 - case PCIOCGETCONF_OLD32: + case PCIOCGETCONF_OLD32: cio32 = (struct pci_conf_io32 *)data; cio = malloc(sizeof(struct pci_conf_io), M_TEMP, M_WAITOK); cio->pat_buf_len = cio32->pat_buf_len; @@ -466,7 +560,7 @@ cio = (struct pci_conf_io *)data; } - switch(cmd) { + switch (cmd) { #ifdef PRE7_COMPAT #ifdef COMPAT_FREEBSD32 case PCIOCGETCONF_OLD32: @@ -912,6 +1006,22 @@ else error = ENODEV; break; + case PCIOCLISTVPD: + lvio = (struct pci_list_vpd_io *)data; + + /* + * Assume that the user-level bus number is + * in fact the physical PCI bus number. + */ + pcidev = pci_find_dbsf(lvio->plvi_sel.pc_domain, + lvio->plvi_sel.pc_bus, lvio->plvi_sel.pc_dev, + lvio->plvi_sel.pc_func); + if (pcidev == NULL) { + error = ENODEV; + break; + } + error = pci_list_vpd(pcidev, lvio); + break; default: error = ENOTTY; break; ==== //depot/projects/pci/sys/dev/pci/pcivar.h#15 (text+ko) ==== @@ -57,6 +57,7 @@ struct vpd_readonly { char keyword[2]; char *value; + int len; }; struct vpd_write { @@ -525,6 +526,7 @@ struct pci_map *pci_find_bar(device_t dev, int reg); int pci_bar_enabled(device_t dev, struct pci_map *pm); +struct pcicfg_vpd *pci_fetch_vpd_list(device_t dev); #define VGA_PCI_BIOS_SHADOW_ADDR 0xC0000 #define VGA_PCI_BIOS_SHADOW_SIZE 131072 ==== //depot/projects/pci/sys/sys/pciio.h#3 (text+ko) ==== @@ -116,10 +116,31 @@ uint64_t pbi_length; /* length of BAR */ }; +struct pci_vpd_element { + char pve_keyword[2]; + uint8_t pve_flags; + uint8_t pve_datalen; + uint8_t pve_data[0]; +}; + +#define PVE_FLAG_IDENT 0x01 /* Element is the string identifier */ +#define PVE_FLAG_RW 0x02 /* Element is read/write */ + +#define PVE_NEXT(pve) \ + ((struct pci_vpd_element *)((char *)(pve) + \ + sizeof(struct pci_vpd_element) + (pve)->pve_datalen)) + +struct pci_list_vpd_io { + struct pcisel plvi_sel; /* device to operate on */ + size_t plvi_len; /* size of the data area */ + struct pci_vpd_element *plvi_data; +}; + #define PCIOCGETCONF _IOWR('p', 5, struct pci_conf_io) #define PCIOCREAD _IOWR('p', 2, struct pci_io) #define PCIOCWRITE _IOWR('p', 3, struct pci_io) #define PCIOCATTACHED _IOWR('p', 4, struct pci_io) #define PCIOCGETBAR _IOWR('p', 6, struct pci_bar_io) +#define PCIOCLISTVPD _IOWR('p', 7, struct pci_list_vpd_io) #endif /* !_SYS_PCIIO_H_ */ ==== //depot/projects/pci/usr.sbin/pciconf/pciconf.c#2 (text+ko) ==== @@ -67,9 +67,12 @@ TAILQ_HEAD(,pci_vendor_info) pci_vendors; +static struct pcisel getsel(const char *str); static void list_bars(int fd, struct pci_conf *p); -static void list_devs(int verbose, int bars, int caps, int errors); +static void list_devs(const char *name, int verbose, int bars, int caps, + int errors, int vpd); static void list_verbose(struct pci_conf *p); +static void list_vpd(int fd, struct pci_conf *p); static const char *guess_class(struct pci_conf *p); static const char *guess_subclass(struct pci_conf *p); static int load_vendors(void); @@ -83,7 +86,7 @@ usage(void) { fprintf(stderr, "%s\n%s\n%s\n%s\n", - "usage: pciconf -l [-bcev]", + "usage: pciconf -l [-bcevV] [selector]", " pciconf -a selector", " pciconf -r [-b | -h] selector addr[:addr2]", " pciconf -w [-b | -h] selector addr value"); @@ -95,13 +98,13 @@ { int c; int listmode, readmode, writemode, attachedmode; - int bars, caps, errors, verbose; + int bars, caps, errors, verbose, vpd; int byte, isshort; listmode = readmode = writemode = attachedmode = 0; - bars = caps = errors = verbose = byte = isshort = 0; + bars = caps = errors = verbose = vpd = byte = isshort = 0; - while ((c = getopt(argc, argv, "abcehlrwv")) != -1) { + while ((c = getopt(argc, argv, "abcehlrwvV")) != -1) { switch(c) { case 'a': attachedmode = 1; @@ -140,19 +143,24 @@ verbose = 1; break; + case 'V': + vpd = 1; + break; + default: usage(); } } - if ((listmode && optind != argc) + if ((listmode && optind >= argc + 1) || (writemode && optind + 3 != argc) || (readmode && optind + 2 != argc) || (attachedmode && optind + 1 != argc)) usage(); if (listmode) { - list_devs(verbose, bars, caps, errors); + list_devs(optind + 1 == argc ? argv[optind] : NULL, verbose, + bars, caps, errors, vpd); } else if (attachedmode) { chkattached(argv[optind]); } else if (readmode) { @@ -169,11 +177,13 @@ } static void -list_devs(int verbose, int bars, int caps, int errors) +list_devs(const char *name, int verbose, int bars, int caps, int errors, + int vpd) { int fd; struct pci_conf_io pc; struct pci_conf conf[255], *p; + struct pci_match_conf patterns[1]; int none_count = 0; if (verbose) @@ -186,6 +196,16 @@ bzero(&pc, sizeof(struct pci_conf_io)); pc.match_buf_len = sizeof(conf); pc.matches = conf; + if (name != NULL) { + bzero(&patterns, sizeof(patterns)); + patterns[0].pc_sel = getsel(name); + patterns[0].flags = PCI_GETCONF_MATCH_DOMAIN | + PCI_GETCONF_MATCH_BUS | PCI_GETCONF_MATCH_DEV | + PCI_GETCONF_MATCH_FUNC; + pc.num_patterns = 1; + pc.pat_buf_len = sizeof(patterns); + pc.patterns = patterns; + } do { if (ioctl(fd, PCIOCGETCONF, &pc) == -1) @@ -231,6 +251,8 @@ list_caps(fd, p); if (errors) list_errors(fd, p); + if (vpd) + list_vpd(fd, p); } } while (pc.status == PCI_GETCONF_MORE_DEVS); @@ -324,6 +346,63 @@ printf(" subclass = %s\n", dp); } +static void +list_vpd(int fd, struct pci_conf *p) +{ + struct pci_list_vpd_io list; + struct pci_vpd_element *vpd, *end; + + list.plvi_sel = p->pc_sel; + list.plvi_len = 0; + list.plvi_data = NULL; + if (ioctl(fd, PCIOCLISTVPD, &list) < 0 || list.plvi_len == 0) + return; + + list.plvi_data = malloc(list.plvi_len); + if (ioctl(fd, PCIOCLISTVPD, &list) < 0) { + free(list.plvi_data); + return; + } + + vpd = list.plvi_data; + end = (struct pci_vpd_element *)((char *)vpd + list.plvi_len); + for (; vpd < end; vpd = PVE_NEXT(vpd)) { + if (vpd->pve_flags == PVE_FLAG_IDENT) { + printf(" VPD ident = '%.*s'\n", + (int)vpd->pve_datalen, vpd->pve_data); + continue; + } + + /* Ignore the checksum keyword. */ + if (!(vpd->pve_flags & PVE_FLAG_RW) && + memcmp(vpd->pve_keyword, "RV", 2) == 0) + continue; + + /* Ignore remaining read-write space. */ + if (vpd->pve_flags & PVE_FLAG_RW && + memcmp(vpd->pve_keyword, "RW", 2) == 0) + continue; + + /* Handle extended capability keyword. */ + if (!(vpd->pve_flags & PVE_FLAG_RW) && + memcmp(vpd->pve_keyword, "CP", 2) == 0) { + printf(" VPD ro CP = ID %02x in map 0x%x[0x%x]\n", + (unsigned int)vpd->pve_data[0], + PCIR_BAR((unsigned int)vpd->pve_data[1]), + (unsigned int)vpd->pve_data[3] << 8 | + (unsigned int)vpd->pve_data[2]); + continue; + } + + /* Remaining keywords should all have ASCII values. */ + printf(" VPD %s %c%c = '%.*s'\n", + vpd->pve_flags & PVE_FLAG_RW ? "rw" : "ro", + vpd->pve_keyword[0], vpd->pve_keyword[1], + (int)vpd->pve_datalen, vpd->pve_data); + } + free(list.plvi_data); +} + /* * This is a direct cut-and-paste from the table in sys/dev/pci/pci.c. */ From owner-p4-projects@FreeBSD.ORG Tue Jan 14 23:02:54 2014 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 79DB3F5; Tue, 14 Jan 2014 23:02:54 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 3D00EF3 for ; Tue, 14 Jan 2014 23:02:54 +0000 (UTC) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:1900:2254:2068::682:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 270741362 for ; Tue, 14 Jan 2014 23:02:54 +0000 (UTC) Received: from skunkworks.freebsd.org ([127.0.1.74]) by skunkworks.freebsd.org (8.14.7/8.14.7) with ESMTP id s0EN2sSD066237 for ; Tue, 14 Jan 2014 23:02:54 GMT (envelope-from csjp@freebsd.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.7/8.14.7/Submit) id s0EN2r5h066234 for perforce@freebsd.org; Tue, 14 Jan 2014 23:02:53 GMT (envelope-from csjp@freebsd.org) Date: Tue, 14 Jan 2014 23:02:53 GMT Message-Id: <201401142302.s0EN2r5h066234@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to csjp@freebsd.org using -f From: "Christian S.J. Peron" Subject: PERFORCE change 1190039 for review To: Perforce Change Reviews Precedence: bulk X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.17 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 14 Jan 2014 23:02:54 -0000 http://p4web.freebsd.org/@@1190039?ac=10 Change 1190039 by csjp@csjp_movsx on 2014/01/14 23:02:44 correct makefile so that compiler isn't hard-coded to gcc Affected files ... .. //depot/projects/trustedbsd/bsmtrace/Makefile#5 edit Differences ... ==== //depot/projects/trustedbsd/bsmtrace/Makefile#5 (text+ko) ==== @@ -1,6 +1,6 @@ # $Id: Makefile,v 1.8 2007/07/13 00:03:50 csjp Exp $ -CC = gcc +CC ?= cc CFLAGS = -Wall -g TARGETS = bsmtrace OBJ = y.tab.o bsm.o bsmtrace.o conf.o lex.yy.o log.o pipe.o trigger.o fcache.o From owner-p4-projects@FreeBSD.ORG Sat Jan 18 21:23:12 2014 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 6AE26795; Sat, 18 Jan 2014 21:23:12 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 09EF578F for ; Sat, 18 Jan 2014 21:23:12 +0000 (UTC) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:1900:2254:2068::682:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id E6D09125A for ; Sat, 18 Jan 2014 21:23:11 +0000 (UTC) Received: from skunkworks.freebsd.org ([127.0.1.74]) by skunkworks.freebsd.org (8.14.7/8.14.7) with ESMTP id s0ILNBa1016956 for ; Sat, 18 Jan 2014 21:23:11 GMT (envelope-from jhb@freebsd.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.7/8.14.7/Submit) id s0ILNBX2016953 for perforce@freebsd.org; Sat, 18 Jan 2014 21:23:11 GMT (envelope-from jhb@freebsd.org) Date: Sat, 18 Jan 2014 21:23:11 GMT Message-Id: <201401182123.s0ILNBX2016953@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to jhb@freebsd.org using -f From: John Baldwin Subject: PERFORCE change 1190142 for review To: Perforce Change Reviews Precedence: bulk X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.17 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 18 Jan 2014 21:23:12 -0000 http://p4web.freebsd.org/@@1190142?ac=10 Change 1190142 by jhb@jhb_pippin on 2014/01/18 21:22:36 IFC @1190140 Affected files ... .. //depot/projects/pci/sys/amd64/amd64/identcpu.c#9 integrate .. //depot/projects/pci/sys/amd64/conf/NOTES#12 integrate .. //depot/projects/pci/sys/amd64/include/vmm.h#8 integrate .. //depot/projects/pci/sys/amd64/vmm/amd/amdv.c#5 integrate .. //depot/projects/pci/sys/amd64/vmm/intel/vmcs.c#7 integrate .. //depot/projects/pci/sys/amd64/vmm/intel/vmcs.h#7 integrate .. //depot/projects/pci/sys/amd64/vmm/intel/vmx.c#9 integrate .. //depot/projects/pci/sys/amd64/vmm/intel/vmx.h#6 integrate .. //depot/projects/pci/sys/amd64/vmm/intel/vmx_genassym.c#6 integrate .. //depot/projects/pci/sys/amd64/vmm/intel/vmx_support.S#4 integrate .. //depot/projects/pci/sys/amd64/vmm/io/vioapic.c#3 integrate .. //depot/projects/pci/sys/amd64/vmm/io/vlapic.c#6 integrate .. //depot/projects/pci/sys/amd64/vmm/io/vlapic.h#5 integrate .. //depot/projects/pci/sys/amd64/vmm/vmm.c#8 integrate .. //depot/projects/pci/sys/amd64/vmm/vmm_stat.c#3 integrate .. //depot/projects/pci/sys/amd64/vmm/vmm_stat.h#3 integrate .. //depot/projects/pci/sys/arm/at91/at91_gpio.h#1 branch .. //depot/projects/pci/sys/arm/at91/at91rm9200.c#4 integrate .. //depot/projects/pci/sys/arm/at91/at91sam9260.c#3 integrate .. //depot/projects/pci/sys/arm/at91/at91sam9g20.c#3 integrate .. //depot/projects/pci/sys/arm/at91/at91sam9g45.c#2 integrate .. //depot/projects/pci/sys/arm/at91/at91sam9x5.c#2 integrate .. //depot/projects/pci/sys/arm/at91/at91var.h#3 integrate .. //depot/projects/pci/sys/arm/freescale/imx/imx51_ipuv3_fbd.c#2 integrate .. //depot/projects/pci/sys/cam/cam_periph.c#13 integrate .. //depot/projects/pci/sys/cam/cam_periph.h#8 integrate .. //depot/projects/pci/sys/cam/cam_xpt.c#15 integrate .. //depot/projects/pci/sys/cam/scsi/scsi_xpt.c#10 integrate .. //depot/projects/pci/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c#9 integrate .. //depot/projects/pci/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c#6 integrate .. //depot/projects/pci/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c#6 integrate .. //depot/projects/pci/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c#7 integrate .. //depot/projects/pci/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c#12 integrate .. //depot/projects/pci/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c#9 integrate .. //depot/projects/pci/sys/compat/freebsd32/freebsd32_misc.c#14 integrate .. //depot/projects/pci/sys/conf/files.amd64#13 integrate .. //depot/projects/pci/sys/conf/files.i386#15 integrate .. //depot/projects/pci/sys/contrib/dev/iwn/iwlwifi-105-6-18.168.6.1.fw.uu#1 branch .. //depot/projects/pci/sys/contrib/ipfilter/netinet/ip_compat.h#6 integrate .. //depot/projects/pci/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c#4 integrate .. //depot/projects/pci/sys/dev/ahci/ahci.c#16 integrate .. //depot/projects/pci/sys/dev/altera/atse/if_atse.c#2 integrate .. //depot/projects/pci/sys/dev/bxe/bxe.c#6 integrate .. //depot/projects/pci/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c#4 integrate .. //depot/projects/pci/sys/dev/netmap/netmap.c#7 integrate .. //depot/projects/pci/sys/dev/netmap/netmap_generic.c#3 integrate .. //depot/projects/pci/sys/dev/netmap/netmap_vale.c#3 integrate .. //depot/projects/pci/sys/dev/qlxge/qls_os.c#2 integrate .. //depot/projects/pci/sys/dev/usb/controller/ehci.c#9 integrate .. //depot/projects/pci/sys/dev/usb/controller/uhci.c#6 integrate .. //depot/projects/pci/sys/dev/usb/controller/xhci.c#11 integrate .. //depot/projects/pci/sys/dev/usb/input/ukbd.c#11 integrate .. //depot/projects/pci/sys/dev/usb/net/uhso.c#9 integrate .. //depot/projects/pci/sys/dev/usb/serial/u3g.c#9 integrate .. //depot/projects/pci/sys/dev/usb/serial/umcs.c#5 integrate .. //depot/projects/pci/sys/dev/usb/usb_dev.c#6 integrate .. //depot/projects/pci/sys/dev/usb/usb_device.c#8 integrate .. //depot/projects/pci/sys/dev/usb/usb_device.h#8 integrate .. //depot/projects/pci/sys/dev/usb/usb_hub.c#11 integrate .. //depot/projects/pci/sys/dev/usb/usb_hub.h#4 integrate .. //depot/projects/pci/sys/dev/usb/usb_request.c#8 integrate .. //depot/projects/pci/sys/dev/usb/usb_transfer.c#8 integrate .. //depot/projects/pci/sys/dev/usb/wlan/if_run.c#12 integrate .. //depot/projects/pci/sys/dev/virtio/block/virtio_blk.c#5 integrate .. //depot/projects/pci/sys/dev/virtio/random/virtio_random.c#1 branch .. //depot/projects/pci/sys/dev/virtio/scsi/virtio_scsi.c#4 integrate .. //depot/projects/pci/sys/dev/vt/hw/xboxfb/xboxfb.c#3 integrate .. //depot/projects/pci/sys/fs/ext2fs/ext2_inode_cnv.c#7 integrate .. //depot/projects/pci/sys/fs/nfs/nfs_var.h#12 integrate .. //depot/projects/pci/sys/fs/nfsserver/nfs_nfsdcache.c#9 integrate .. //depot/projects/pci/sys/fs/nfsserver/nfs_nfsdkrpc.c#8 integrate .. //depot/projects/pci/sys/geom/uncompress/g_uncompress.c#3 integrate .. //depot/projects/pci/sys/i386/conf/NOTES#11 integrate .. //depot/projects/pci/sys/i386/i386/identcpu.c#8 integrate .. //depot/projects/pci/sys/ia64/ia64/exception.S#7 integrate .. //depot/projects/pci/sys/kern/kern_event.c#11 integrate .. //depot/projects/pci/sys/kern/subr_sglist.c#3 integrate .. //depot/projects/pci/sys/kern/uipc_mbuf.c#9 integrate .. //depot/projects/pci/sys/kern/uipc_sockbuf.c#7 integrate .. //depot/projects/pci/sys/kern/uipc_socket.c#9 integrate .. //depot/projects/pci/sys/kern/uipc_syscalls.c#14 integrate .. //depot/projects/pci/sys/mips/cavium/ciu.c#4 integrate .. //depot/projects/pci/sys/modules/geom/Makefile#4 integrate .. //depot/projects/pci/sys/modules/geom/geom_uncompress/Makefile#3 integrate .. //depot/projects/pci/sys/modules/iwnfw/Makefile#7 integrate .. //depot/projects/pci/sys/modules/iwnfw/iwn105/Makefile#1 branch .. //depot/projects/pci/sys/modules/sound/driver/ai2s/Makefile#3 integrate .. //depot/projects/pci/sys/modules/virtio/Makefile#3 integrate .. //depot/projects/pci/sys/modules/virtio/random/Makefile#1 branch .. //depot/projects/pci/sys/net/netmap_user.h#6 integrate .. //depot/projects/pci/sys/net80211/ieee80211_mesh.c#11 integrate .. //depot/projects/pci/sys/netinet/in.c#12 integrate .. //depot/projects/pci/sys/netinet/in_mcast.c#8 integrate .. //depot/projects/pci/sys/netinet/ip_output.c#13 integrate .. //depot/projects/pci/sys/netinet6/in6.c#14 integrate .. //depot/projects/pci/sys/netinet6/in6_ifattach.c#10 integrate .. //depot/projects/pci/sys/netinet6/in6_var.h#8 integrate .. //depot/projects/pci/sys/netinet6/nd6_rtr.c#9 integrate .. //depot/projects/pci/sys/netpfil/ipfw/ip_fw_nat.c#4 integrate .. //depot/projects/pci/sys/powerpc/include/atomic.h#4 integrate .. //depot/projects/pci/sys/powerpc/powermac/macgpio.c#3 integrate .. //depot/projects/pci/sys/powerpc/powermac/macgpiovar.h#3 integrate .. //depot/projects/pci/sys/sys/mbuf.h#10 integrate .. //depot/projects/pci/sys/sys/random.h#6 integrate .. //depot/projects/pci/sys/sys/sf_base.h#2 integrate .. //depot/projects/pci/sys/sys/sf_sync.h#2 integrate .. //depot/projects/pci/sys/sys/sglist.h#3 integrate .. //depot/projects/pci/sys/sys/socket.h#8 integrate .. //depot/projects/pci/sys/vm/vm_pageout.c#11 integrate Differences ... ==== //depot/projects/pci/sys/amd64/amd64/identcpu.c#9 (text+ko) ==== @@ -39,7 +39,7 @@ */ #include -__FBSDID("$FreeBSD: head/sys/amd64/amd64/identcpu.c 257856 2013-11-08 16:32:30Z kib $"); +__FBSDID("$FreeBSD: head/sys/amd64/amd64/identcpu.c 260557 2014-01-11 22:41:10Z gavin $"); #include "opt_cpu.h" @@ -206,16 +206,16 @@ } printf("-class CPU)\n"); if (*cpu_vendor) - printf(" Origin = \"%s\"", cpu_vendor); + printf(" Origin=\"%s\"", cpu_vendor); if (cpu_id) - printf(" Id = 0x%x", cpu_id); + printf(" Id=0x%x", cpu_id); if (cpu_vendor_id == CPU_VENDOR_INTEL || cpu_vendor_id == CPU_VENDOR_AMD || cpu_vendor_id == CPU_VENDOR_CENTAUR) { - printf(" Family = 0x%x", CPUID_TO_FAMILY(cpu_id)); - printf(" Model = 0x%x", CPUID_TO_MODEL(cpu_id)); - printf(" Stepping = %u", cpu_id & CPUID_STEPPING); + printf(" Family=0x%x", CPUID_TO_FAMILY(cpu_id)); + printf(" Model=0x%x", CPUID_TO_MODEL(cpu_id)); + printf(" Stepping=%u", cpu_id & CPUID_STEPPING); /* * AMD CPUID Specification ==== //depot/projects/pci/sys/amd64/conf/NOTES#12 (text+ko) ==== @@ -4,7 +4,7 @@ # This file contains machine dependent kernel configuration notes. For # machine independent notes, look in /sys/conf/NOTES. # -# $FreeBSD: head/sys/amd64/conf/NOTES 260376 2014-01-06 17:23:22Z schweikh $ +# $FreeBSD: head/sys/amd64/conf/NOTES 260847 2014-01-18 06:14:38Z bryanv $ # # @@ -472,6 +472,7 @@ device virtio_blk # VirtIO Block device device virtio_scsi # VirtIO SCSI device device virtio_balloon # VirtIO Memory Balloon device +device virtio_random # VirtIO Entropy device device hyperv # HyperV drivers ==== //depot/projects/pci/sys/amd64/include/vmm.h#8 (text+ko) ==== @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: head/sys/amd64/include/vmm.h 260466 2014-01-09 03:25:54Z neel $ + * $FreeBSD: head/sys/amd64/include/vmm.h 260619 2014-01-14 01:55:58Z neel $ */ #ifndef _VMM_H_ @@ -52,7 +52,7 @@ typedef void (*vmm_resume_func_t)(void); typedef void * (*vmi_init_func_t)(struct vm *vm, struct pmap *pmap); typedef int (*vmi_run_func_t)(void *vmi, int vcpu, register_t rip, - struct pmap *pmap); + struct pmap *pmap, void *rendezvous_cookie); typedef void (*vmi_cleanup_func_t)(void *vmi); typedef int (*vmi_get_register_t)(void *vmi, int vcpu, int num, uint64_t *retval); @@ -136,6 +136,31 @@ struct vm_exit *vm_exitinfo(struct vm *vm, int vcpuid); /* + * Rendezvous all vcpus specified in 'dest' and execute 'func(arg)'. + * The rendezvous 'func(arg)' is not allowed to do anything that will + * cause the thread to be put to sleep. + * + * If the rendezvous is being initiated from a vcpu context then the + * 'vcpuid' must refer to that vcpu, otherwise it should be set to -1. + * + * The caller cannot hold any locks when initiating the rendezvous. + * + * The implementation of this API may cause vcpus other than those specified + * by 'dest' to be stalled. The caller should not rely on any vcpus making + * forward progress when the rendezvous is in progress. + */ +typedef void (*vm_rendezvous_func_t)(struct vm *vm, int vcpuid, void *arg); +void vm_smp_rendezvous(struct vm *vm, int vcpuid, cpuset_t dest, + vm_rendezvous_func_t func, void *arg); + +static __inline int +vcpu_rendezvous_pending(void *rendezvous_cookie) +{ + + return (*(uintptr_t *)rendezvous_cookie != 0); +} + +/* * Return 1 if device indicated by bus/slot/func is supposed to be a * pci passthrough device. * @@ -272,6 +297,7 @@ VM_EXITCODE_INST_EMUL, VM_EXITCODE_SPINUP_AP, VM_EXITCODE_SPINDOWN_CPU, + VM_EXITCODE_RENDEZVOUS, VM_EXITCODE_MAX }; ==== //depot/projects/pci/sys/amd64/vmm/amd/amdv.c#5 (text+ko) ==== @@ -23,11 +23,11 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: head/sys/amd64/vmm/amd/amdv.c 260466 2014-01-09 03:25:54Z neel $ + * $FreeBSD: head/sys/amd64/vmm/amd/amdv.c 260619 2014-01-14 01:55:58Z neel $ */ #include -__FBSDID("$FreeBSD: head/sys/amd64/vmm/amd/amdv.c 260466 2014-01-09 03:25:54Z neel $"); +__FBSDID("$FreeBSD: head/sys/amd64/vmm/amd/amdv.c 260619 2014-01-14 01:55:58Z neel $"); #include #include @@ -67,7 +67,7 @@ } static int -amdv_vmrun(void *arg, int vcpu, register_t rip, struct pmap *pmap) +amdv_vmrun(void *arg, int vcpu, register_t rip, struct pmap *pmap, void *cookie) { printf("amdv_vmrun: not implemented\n"); ==== //depot/projects/pci/sys/amd64/vmm/intel/vmcs.c#7 (text+ko) ==== @@ -23,13 +23,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: head/sys/amd64/vmm/intel/vmcs.c 260380 2014-01-06 23:16:39Z neel $ + * $FreeBSD: head/sys/amd64/vmm/intel/vmcs.c 260531 2014-01-11 03:14:05Z neel $ */ #include "opt_ddb.h" #include -__FBSDID("$FreeBSD: head/sys/amd64/vmm/intel/vmcs.c 260380 2014-01-06 23:16:39Z neel $"); +__FBSDID("$FreeBSD: head/sys/amd64/vmm/intel/vmcs.c 260531 2014-01-11 03:14:05Z neel $"); #include #include @@ -473,7 +473,7 @@ switch (exit & 0x8000ffff) { case EXIT_REASON_EXCEPTION: case EXIT_REASON_EXT_INTR: - val = vmcs_read(VMCS_EXIT_INTERRUPTION_INFO); + val = vmcs_read(VMCS_EXIT_INTR_INFO); db_printf("Interrupt Type: "); switch (val >> 8 & 0x7) { case 0: @@ -495,7 +495,7 @@ db_printf(" Vector: %lu", val & 0xff); if (val & 0x800) db_printf(" Error Code: %lx", - vmcs_read(VMCS_EXIT_INTERRUPTION_ERROR)); + vmcs_read(VMCS_EXIT_INTR_ERRCODE)); db_printf("\n"); break; case EXIT_REASON_EPT_FAULT: ==== //depot/projects/pci/sys/amd64/vmm/intel/vmcs.h#7 (text+ko) ==== @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: head/sys/amd64/vmm/intel/vmcs.h 260410 2014-01-07 21:04:49Z neel $ + * $FreeBSD: head/sys/amd64/vmm/intel/vmcs.h 260836 2014-01-18 02:20:10Z neel $ */ #ifndef _VMCS_H_ @@ -97,6 +97,7 @@ /* 16-bit control fields */ #define VMCS_VPID 0x00000000 +#define VMCS_PIR_VECTOR 0x00000002 /* 16-bit guest-state fields */ #define VMCS_GUEST_ES_SELECTOR 0x00000800 @@ -129,6 +130,7 @@ #define VMCS_TSC_OFFSET 0x00002010 #define VMCS_VIRTUAL_APIC 0x00002012 #define VMCS_APIC_ACCESS 0x00002014 +#define VMCS_PIR_DESC 0x00002016 #define VMCS_EPTP 0x0000201A #define VMCS_EOI_EXIT0 0x0000201C #define VMCS_EOI_EXIT1 0x0000201E @@ -177,8 +179,8 @@ /* 32-bit read-only data fields */ #define VMCS_INSTRUCTION_ERROR 0x00004400 #define VMCS_EXIT_REASON 0x00004402 -#define VMCS_EXIT_INTERRUPTION_INFO 0x00004404 -#define VMCS_EXIT_INTERRUPTION_ERROR 0x00004406 +#define VMCS_EXIT_INTR_INFO 0x00004404 +#define VMCS_EXIT_INTR_ERRCODE 0x00004406 #define VMCS_IDT_VECTORING_INFO 0x00004408 #define VMCS_IDT_VECTORING_ERROR 0x0000440A #define VMCS_EXIT_INSTRUCTION_LENGTH 0x0000440C @@ -329,11 +331,18 @@ #define EXIT_REASON_APIC_WRITE 56 /* + * NMI unblocking due to IRET. + * + * Applies to VM-exits due to hardware exception or EPT fault. + */ +#define EXIT_QUAL_NMIUDTI (1 << 12) +/* * VMCS interrupt information fields */ -#define VMCS_INTERRUPTION_INFO_VALID (1U << 31) -#define VMCS_INTERRUPTION_INFO_HW_INTR (0 << 8) -#define VMCS_INTERRUPTION_INFO_NMI (2 << 8) +#define VMCS_INTR_VALID (1U << 31) +#define VMCS_INTR_T_MASK 0x700 /* Interruption-info type */ +#define VMCS_INTR_T_HWINTR (0 << 8) +#define VMCS_INTR_T_NMI (2 << 8) /* * VMCS IDT-Vectoring information fields ==== //depot/projects/pci/sys/amd64/vmm/intel/vmx.c#9 (text+ko) ==== @@ -23,11 +23,11 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: head/sys/amd64/vmm/intel/vmx.c 260466 2014-01-09 03:25:54Z neel $ + * $FreeBSD: head/sys/amd64/vmm/intel/vmx.c 260836 2014-01-18 02:20:10Z neel $ */ #include -__FBSDID("$FreeBSD: head/sys/amd64/vmm/intel/vmx.c 260466 2014-01-09 03:25:54Z neel $"); +__FBSDID("$FreeBSD: head/sys/amd64/vmm/intel/vmx.c 260836 2014-01-18 02:20:10Z neel $"); #include #include @@ -45,11 +45,13 @@ #include #include #include +#include #include #include #include #include "vmm_host.h" +#include "vmm_ipi.h" #include "vmm_msr.h" #include "vmm_ktr.h" #include "vmm_stat.h" @@ -93,6 +95,7 @@ #define VM_EXIT_CTLS_ONE_SETTING \ (VM_EXIT_CTLS_ONE_SETTING_NO_PAT | \ + VM_EXIT_ACKNOWLEDGE_INTERRUPT | \ VM_EXIT_SAVE_PAT | \ VM_EXIT_LOAD_PAT) #define VM_EXIT_CTLS_ZERO_SETTING VM_EXIT_SAVE_DEBUG_CONTROLS @@ -171,6 +174,14 @@ SYSCTL_INT(_hw_vmm_vmx, OID_AUTO, virtual_interrupt_delivery, CTLFLAG_RD, &virtual_interrupt_delivery, 0, "APICv virtual interrupt delivery support"); +static int posted_interrupts; +SYSCTL_INT(_hw_vmm_vmx, OID_AUTO, posted_interrupts, CTLFLAG_RD, + &posted_interrupts, 0, "APICv posted interrupt support"); + +static int pirvec; +SYSCTL_INT(_hw_vmm_vmx, OID_AUTO, posted_interrupt_vector, CTLFLAG_RD, + &pirvec, 0, "APICv posted interrupt vector"); + static struct unrhdr *vpid_unr; static u_int vpid_alloc_failed; SYSCTL_UINT(_hw_vmm_vmx, OID_AUTO, vpid_alloc_failed, CTLFLAG_RD, @@ -441,6 +452,9 @@ static int vmx_cleanup(void) { + + if (pirvec != 0) + vmm_ipi_free(pirvec); if (vpid_unr != NULL) { delete_unrhdr(vpid_unr); @@ -636,8 +650,32 @@ procbased_ctls |= PROCBASED_USE_TPR_SHADOW; procbased_ctls2 |= procbased2_vid_bits; procbased_ctls2 &= ~PROCBASED2_VIRTUALIZE_X2APIC_MODE; + + /* + * Check for Posted Interrupts only if Virtual Interrupt + * Delivery is enabled. + */ + error = vmx_set_ctlreg(MSR_VMX_PINBASED_CTLS, + MSR_VMX_TRUE_PINBASED_CTLS, PINBASED_POSTED_INTERRUPT, 0, + &tmp); + if (error == 0) { + pirvec = vmm_ipi_alloc(); + if (pirvec == 0) { + if (bootverbose) { + printf("vmx_init: unable to allocate " + "posted interrupt vector\n"); + } + } else { + posted_interrupts = 1; + TUNABLE_INT_FETCH("hw.vmm.vmx.use_apic_pir", + &posted_interrupts); + } + } } + if (posted_interrupts) + pinbased_ctls |= PINBASED_POSTED_INTERRUPT; + /* Initialize EPT */ error = ept_init(ipinum); if (error) { @@ -680,6 +718,31 @@ return (0); } +static void +vmx_trigger_hostintr(int vector) +{ + uintptr_t func; + struct gate_descriptor *gd; + + gd = &idt[vector]; + + KASSERT(vector >= 32 && vector <= 255, ("vmx_trigger_hostintr: " + "invalid vector %d", vector)); + KASSERT(gd->gd_p == 1, ("gate descriptor for vector %d not present", + vector)); + KASSERT(gd->gd_type == SDT_SYSIGT, ("gate descriptor for vector %d " + "has invalid type %d", vector, gd->gd_type)); + KASSERT(gd->gd_dpl == SEL_KPL, ("gate descriptor for vector %d " + "has invalid dpl %d", vector, gd->gd_dpl)); + KASSERT(gd->gd_selector == GSEL(GCODE_SEL, SEL_KPL), ("gate descriptor " + "for vector %d has invalid selector %d", vector, gd->gd_selector)); + KASSERT(gd->gd_ist == 0, ("gate descriptor for vector %d has invalid " + "IST %d", vector, gd->gd_ist)); + + func = ((long)gd->gd_hioffset << 16 | gd->gd_looffset); + vmx_call_isr(func); +} + static int vmx_setup_cr_shadow(int which, struct vmcs *vmcs, uint32_t initial) { @@ -822,6 +885,11 @@ error += vmwrite(VMCS_EOI_EXIT2, 0); error += vmwrite(VMCS_EOI_EXIT3, 0); } + if (posted_interrupts) { + error += vmwrite(VMCS_PIR_VECTOR, pirvec); + error += vmwrite(VMCS_PIR_DESC, + vtophys(&vmx->pir_desc[i])); + } VMCLEAR(vmcs); KASSERT(error == 0, ("vmx_vminit: error customizing the vmcs")); @@ -997,7 +1065,7 @@ * Inject the virtual NMI. The vector must be the NMI IDT entry * or the VMCS entry check will fail. */ - info = VMCS_INTERRUPTION_INFO_NMI | VMCS_INTERRUPTION_INFO_VALID; + info = VMCS_INTR_T_NMI | VMCS_INTR_VALID; info |= IDT_NMI; vmcs_write(VMCS_ENTRY_INTR_INFO, info); @@ -1035,7 +1103,7 @@ * because of a pending AST. */ info = vmcs_read(VMCS_ENTRY_INTR_INFO); - if (info & VMCS_INTERRUPTION_INFO_VALID) + if (info & VMCS_INTR_VALID) return; /* @@ -1066,7 +1134,7 @@ goto cantinject; /* Inject the interrupt */ - info = VMCS_INTERRUPTION_INFO_HW_INTR | VMCS_INTERRUPTION_INFO_VALID; + info = VMCS_INTR_T_HWINTR | VMCS_INTR_VALID; info |= vector; vmcs_write(VMCS_ENTRY_INTR_INFO, info); @@ -1087,6 +1155,37 @@ VCPU_CTR0(vmx->vm, vcpu, "Enabling interrupt window exiting"); } +/* + * If the Virtual NMIs execution control is '1' then the logical processor + * tracks virtual-NMI blocking in the Guest Interruptibility-state field of + * the VMCS. An IRET instruction in VMX non-root operation will remove any + * virtual-NMI blocking. + * + * This unblocking occurs even if the IRET causes a fault. In this case the + * hypervisor needs to restore virtual-NMI blocking before resuming the guest. + */ +static void +vmx_restore_nmi_blocking(struct vmx *vmx, int vcpuid) +{ + uint32_t gi; + + VCPU_CTR0(vmx->vm, vcpuid, "Restore Virtual-NMI blocking"); + gi = vmcs_read(VMCS_GUEST_INTERRUPTIBILITY); + gi |= VMCS_INTERRUPTIBILITY_NMI_BLOCKING; + vmcs_write(VMCS_GUEST_INTERRUPTIBILITY, gi); +} + +static void +vmx_clear_nmi_blocking(struct vmx *vmx, int vcpuid) +{ + uint32_t gi; + + VCPU_CTR0(vmx->vm, vcpuid, "Clear Virtual-NMI blocking"); + gi = vmcs_read(VMCS_GUEST_INTERRUPTIBILITY); + gi &= ~VMCS_INTERRUPTIBILITY_NMI_BLOCKING; + vmcs_write(VMCS_GUEST_INTERRUPTIBILITY, gi); +} + static int vmx_emulate_cr_access(struct vmx *vmx, int vcpu, uint64_t exitqual) { @@ -1376,10 +1475,12 @@ int error, handled; struct vmxctx *vmxctx; struct vlapic *vlapic; - uint32_t eax, ecx, edx, idtvec_info, idtvec_err, reason; + uint32_t eax, ecx, edx, idtvec_info, idtvec_err, intr_info, reason; uint64_t qual, gpa; bool retu; + CTASSERT((PINBASED_CTLS_ONE_SETTING & PINBASED_VIRTUAL_NMI) != 0); + handled = 0; vmxctx = &vmx->ctx[vcpu]; @@ -1412,9 +1513,20 @@ vmcs_write(VMCS_ENTRY_EXCEPTION_ERROR, idtvec_err); } + /* + * If 'virtual NMIs' are being used and the VM-exit + * happened while injecting an NMI during the previous + * VM-entry, then clear "blocking by NMI" in the Guest + * Interruptibility-state. + */ + if ((idtvec_info & VMCS_INTR_T_MASK) == + VMCS_INTR_T_NMI) { + vmx_clear_nmi_blocking(vmx, vcpu); + } vmcs_write(VMCS_ENTRY_INST_LENGTH, vmexit->inst_length); } default: + idtvec_info = 0; break; } @@ -1487,6 +1599,11 @@ * host interrupt handler in the VM's softc. We will inject * this virtual interrupt during the subsequent VM enter. */ + intr_info = vmcs_read(VMCS_EXIT_INTR_INFO); + KASSERT((intr_info & VMCS_INTR_VALID) != 0 && + (intr_info & VMCS_INTR_T_MASK) == VMCS_INTR_T_HWINTR, + ("VM exit interruption info invalid: %#x", intr_info)); + vmx_trigger_hostintr(intr_info & 0xff); /* * This is special. We want to treat this as an 'handled' @@ -1514,6 +1631,23 @@ vmm_stat_incr(vmx->vm, vcpu, VMEXIT_CPUID, 1); handled = vmx_handle_cpuid(vmx->vm, vcpu, vmxctx); break; + case EXIT_REASON_EXCEPTION: + intr_info = vmcs_read(VMCS_EXIT_INTR_INFO); + KASSERT((intr_info & VMCS_INTR_VALID) != 0, + ("VM exit interruption info invalid: %#x", intr_info)); + /* + * If Virtual NMIs control is 1 and the VM-exit is due to a + * fault encountered during the execution of IRET then we must + * restore the state of "virtual-NMI blocking" before resuming + * the guest. + * + * See "Resuming Guest Software after Handling an Exception". + */ + if ((idtvec_info & VMCS_IDT_VEC_VALID) == 0 && + (intr_info & 0xff) != IDT_DF && + (intr_info & EXIT_QUAL_NMIUDTI) != 0) + vmx_restore_nmi_blocking(vmx, vcpu); + break; case EXIT_REASON_EPT_FAULT: vmm_stat_incr(vmx->vm, vcpu, VMEXIT_EPT_FAULT, 1); /* @@ -1532,6 +1666,17 @@ vmexit->u.inst_emul.gla = vmcs_gla(); vmexit->u.inst_emul.cr3 = vmcs_guest_cr3(); } + /* + * If Virtual NMIs control is 1 and the VM-exit is due to an + * EPT fault during the execution of IRET then we must restore + * the state of "virtual-NMI blocking" before resuming. + * + * See description of "NMI unblocking due to IRET" in + * "Exit Qualification for EPT Violations". + */ + if ((idtvec_info & VMCS_IDT_VEC_VALID) == 0 && + (qual & EXIT_QUAL_NMIUDTI) != 0) + vmx_restore_nmi_blocking(vmx, vcpu); break; case EXIT_REASON_APIC_ACCESS: handled = vmx_handle_apic_access(vmx, vcpu, vmexit); @@ -1596,6 +1741,18 @@ } static __inline int +vmx_exit_rendezvous(struct vmx *vmx, int vcpu, struct vm_exit *vmexit) +{ + + vmexit->rip = vmcs_guest_rip(); + vmexit->inst_length = 0; + vmexit->exitcode = VM_EXITCODE_RENDEZVOUS; + vmm_stat_incr(vmx->vm, vcpu, VMEXIT_RENDEZVOUS, 1); + + return (UNHANDLED); +} + +static __inline int vmx_exit_inst_error(struct vmxctx *vmxctx, int rc, struct vm_exit *vmexit) { @@ -1624,10 +1781,12 @@ } static int -vmx_run(void *arg, int vcpu, register_t startrip, pmap_t pmap) +vmx_run(void *arg, int vcpu, register_t startrip, pmap_t pmap, + void *rendezvous_cookie) { int rc, handled, launched; struct vmx *vmx; + struct vm *vm; struct vmxctx *vmxctx; struct vmcs *vmcs; struct vm_exit *vmexit; @@ -1636,10 +1795,11 @@ uint32_t exit_reason; vmx = arg; + vm = vmx->vm; vmcs = &vmx->vmcs[vcpu]; vmxctx = &vmx->ctx[vcpu]; - vlapic = vm_lapic(vmx->vm, vcpu); - vmexit = vm_exitinfo(vmx->vm, vcpu); + vlapic = vm_lapic(vm, vcpu); + vmexit = vm_exitinfo(vm, vcpu); launched = 0; KASSERT(vmxctx->pmap == pmap, @@ -1687,6 +1847,12 @@ break; } + if (vcpu_rendezvous_pending(rendezvous_cookie)) { + enable_intr(); + handled = vmx_exit_rendezvous(vmx, vcpu, vmexit); + break; + } + vmx_inject_interrupts(vmx, vcpu, vlapic); vmx_run_trace(vmx, vcpu); rc = vmx_enter_guest(vmxctx, launched); @@ -1720,9 +1886,9 @@ } if (!handled) - vmm_stat_incr(vmx->vm, vcpu, VMEXIT_USERSPACE, 1); + vmm_stat_incr(vm, vcpu, VMEXIT_USERSPACE, 1); - VCPU_CTR1(vmx->vm, vcpu, "returning from vmx_run: exitcode %d", + VCPU_CTR1(vm, vcpu, "returning from vmx_run: exitcode %d", vmexit->exitcode); VMCLEAR(vmcs); @@ -1945,11 +2111,11 @@ if (error) return (error); - if (info & VMCS_INTERRUPTION_INFO_VALID) + if (info & VMCS_INTR_VALID) return (EAGAIN); info = vector | (type_map[type] << 8) | (code_valid ? 1 << 11 : 0); - info |= VMCS_INTERRUPTION_INFO_VALID; + info |= VMCS_INTR_VALID; error = vmcs_setreg(vmcs, 0, VMCS_IDENT(VMCS_ENTRY_INTR_INFO), info); if (error != 0) return (error); @@ -2101,19 +2267,9 @@ return (retval); } -/* - * Posted Interrupt Descriptor (described in section 29.6 of the Intel SDM). - */ -struct pir_desc { - uint64_t pir[4]; - uint64_t pending; - uint64_t unused[3]; -} __aligned(64); -CTASSERT(sizeof(struct pir_desc) == 64); - struct vlapic_vtx { struct vlapic vlapic; - struct pir_desc pir_desc; + struct pir_desc *pir_desc; }; #define VMX_CTR_PIR(vm, vcpuid, pir_desc, notify, vector, level, msg) \ @@ -2143,7 +2299,7 @@ * XXX need to deal with level triggered interrupts */ vlapic_vtx = (struct vlapic_vtx *)vlapic; - pir_desc = &vlapic_vtx->pir_desc; + pir_desc = vlapic_vtx->pir_desc; /* * Keep track of interrupt requests in the PIR descriptor. This is @@ -2177,7 +2333,7 @@ KASSERT(vecptr == NULL, ("vmx_pending_intr: vecptr must be NULL")); vlapic_vtx = (struct vlapic_vtx *)vlapic; - pir_desc = &vlapic_vtx->pir_desc; + pir_desc = vlapic_vtx->pir_desc; pending = atomic_load_acq_long(&pir_desc->pending); if (!pending) @@ -2215,6 +2371,13 @@ panic("vmx_intr_accepted: not expected to be called"); } +static void +vmx_post_intr(struct vlapic *vlapic, int hostcpu) +{ + + ipi_cpu(hostcpu, pirvec); +} + /* * Transfer the pending interrupts in the PIR descriptor to the IRR * in the virtual APIC page. @@ -2230,7 +2393,7 @@ uint16_t intr_status_old, intr_status_new; vlapic_vtx = (struct vlapic_vtx *)vlapic; - pir_desc = &vlapic_vtx->pir_desc; + pir_desc = vlapic_vtx->pir_desc; if (atomic_cmpset_long(&pir_desc->pending, 1, 0) == 0) { VCPU_CTR0(vlapic->vm, vlapic->vcpuid, "vmx_inject_pir: " "no posted interrupt pending"); @@ -2295,6 +2458,7 @@ { struct vmx *vmx; struct vlapic *vlapic; + struct vlapic_vtx *vlapic_vtx; vmx = arg; @@ -2303,12 +2467,18 @@ vlapic->vcpuid = vcpuid; vlapic->apic_page = (struct LAPIC *)&vmx->apic_page[vcpuid]; + vlapic_vtx = (struct vlapic_vtx *)vlapic; + vlapic_vtx->pir_desc = &vmx->pir_desc[vcpuid]; + if (virtual_interrupt_delivery) { vlapic->ops.set_intr_ready = vmx_set_intr_ready; vlapic->ops.pending_intr = vmx_pending_intr; vlapic->ops.intr_accepted = vmx_intr_accepted; } + if (posted_interrupts) + vlapic->ops.post_intr = vmx_post_intr; + vlapic_init(vlapic); return (vlapic); ==== //depot/projects/pci/sys/amd64/vmm/intel/vmx.h#6 (text+ko) ==== @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: head/sys/amd64/vmm/intel/vmx.h 260167 2014-01-01 21:17:08Z neel $ + * $FreeBSD: head/sys/amd64/vmm/intel/vmx.h 260532 2014-01-11 04:22:00Z neel $ */ #ifndef _VMX_H_ @@ -93,11 +93,20 @@ }; CTASSERT(sizeof(struct apic_page) == PAGE_SIZE); +/* Posted Interrupt Descriptor (described in section 29.6 of the Intel SDM) */ +struct pir_desc { + uint64_t pir[4]; + uint64_t pending; + uint64_t unused[3]; +} __aligned(64); +CTASSERT(sizeof(struct pir_desc) == 64); + /* virtual machine softc */ struct vmx { struct vmcs vmcs[VM_MAXCPU]; /* one vmcs per virtual cpu */ struct apic_page apic_page[VM_MAXCPU]; /* one apic page per vcpu */ char msr_bitmap[PAGE_SIZE]; + struct pir_desc pir_desc[VM_MAXCPU]; struct msr_entry guest_msrs[VM_MAXCPU][GUEST_MSR_MAX_ENTRIES]; struct vmxctx ctx[VM_MAXCPU]; struct vmxcap cap[VM_MAXCPU]; @@ -108,6 +117,7 @@ CTASSERT((offsetof(struct vmx, vmcs) & PAGE_MASK) == 0); CTASSERT((offsetof(struct vmx, msr_bitmap) & PAGE_MASK) == 0); CTASSERT((offsetof(struct vmx, guest_msrs) & 15) == 0); +CTASSERT((offsetof(struct vmx, pir_desc[0]) & 63) == 0); #define VMX_GUEST_VMEXIT 0 #define VMX_VMRESUME_ERROR 1 @@ -115,6 +125,7 @@ #define VMX_INVEPT_ERROR 3 int vmx_enter_guest(struct vmxctx *ctx, int launched); void vmx_exit_guest(void); +void vmx_call_isr(uintptr_t entry); u_long vmx_fix_cr0(u_long cr0); u_long vmx_fix_cr4(u_long cr4); ==== //depot/projects/pci/sys/amd64/vmm/intel/vmx_genassym.c#6 (text+ko) ==== @@ -23,11 +23,11 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: head/sys/amd64/vmm/intel/vmx_genassym.c 260167 2014-01-01 21:17:08Z neel $ + * $FreeBSD: head/sys/amd64/vmm/intel/vmx_genassym.c 260531 2014-01-11 03:14:05Z neel $ */ #include -__FBSDID("$FreeBSD: head/sys/amd64/vmm/intel/vmx_genassym.c 260167 2014-01-01 21:17:08Z neel $"); +__FBSDID("$FreeBSD: head/sys/amd64/vmm/intel/vmx_genassym.c 260531 2014-01-11 03:14:05Z neel $"); #include #include @@ -84,3 +84,6 @@ ASSYM(PM_ACTIVE, offsetof(struct pmap, pm_active)); ASSYM(PM_EPTGEN, offsetof(struct pmap, pm_eptgen)); + +ASSYM(KERNEL_SS, GSEL(GDATA_SEL, SEL_KPL)); +ASSYM(KERNEL_CS, GSEL(GCODE_SEL, SEL_KPL)); ==== //depot/projects/pci/sys/amd64/vmm/intel/vmx_support.S#4 (text+ko) ==== @@ -24,7 +24,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: head/sys/amd64/vmm/intel/vmx_support.S 260238 2014-01-03 19:29:33Z neel $ + * $FreeBSD: head/sys/amd64/vmm/intel/vmx_support.S 260531 2014-01-11 03:14:05Z neel $ */ #include @@ -234,3 +234,21 @@ movl $VMX_GUEST_VMEXIT, %eax ret END(vmx_exit_guest) + +/* + * %rdi = interrupt handler entry point + * + * Calling sequence described in the "Instruction Set Reference" for the "INT" + * instruction in Intel SDM, Vol 2. + */ +ENTRY(vmx_call_isr) + mov %rsp, %r11 /* save %rsp */ + and $~0xf, %rsp /* align on 16-byte boundary */ + pushq $KERNEL_SS /* %ss */ + pushq %r11 /* %rsp */ + pushfq /* %rflags */ + pushq $KERNEL_CS /* %cs */ + cli /* disable interrupts */ + callq *%rdi /* push %rip and call isr */ + ret +END(vmx_call_isr) ==== //depot/projects/pci/sys/amd64/vmm/io/vioapic.c#3 (text+ko) ==== @@ -24,11 +24,11 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: head/sys/amd64/vmm/io/vioapic.c 259482 2013-12-16 19:59:31Z neel $ + * $FreeBSD: head/sys/amd64/vmm/io/vioapic.c 260619 2014-01-14 01:55:58Z neel $ */ #include -__FBSDID("$FreeBSD: head/sys/amd64/vmm/io/vioapic.c 259482 2013-12-16 19:59:31Z neel $"); +__FBSDID("$FreeBSD: head/sys/amd64/vmm/io/vioapic.c 260619 2014-01-14 01:55:58Z neel $"); #include #include @@ -222,8 +222,52 @@ return (vioapic_set_irqstate(vm, irq, IRQSTATE_PULSE)); } +/* + * Reset the vlapic's trigger-mode register to reflect the ioapic pin + * configuration. + */ +static void +vioapic_update_tmr(struct vm *vm, int vcpuid, void *arg) +{ + struct vioapic *vioapic; + struct vlapic *vlapic; + uint32_t low, high, dest; + int delmode, pin, vector; + bool level, phys; + + vlapic = vm_lapic(vm, vcpuid); + vioapic = vm_ioapic(vm); + + VIOAPIC_LOCK(vioapic); + /* + * Reset all vectors to be edge-triggered. + */ + vlapic_reset_tmr(vlapic); + for (pin = 0; pin < REDIR_ENTRIES; pin++) { + low = vioapic->rtbl[pin].reg; + high = vioapic->rtbl[pin].reg >> 32; + + level = low & IOART_TRGRLVL ? true : false; + if (!level) + continue; + + /* + * For a level-triggered 'pin' let the vlapic figure out if + * an assertion on this 'pin' would result in an interrupt + * being delivered to it. If yes, then it will modify the + * TMR bit associated with this vector to level-triggered. + */ + phys = ((low & IOART_DESTMOD) == IOART_DESTPHY); + delmode = low & IOART_DELMOD; + vector = low & IOART_INTVEC; + dest = high >> APIC_ID_SHIFT; + vlapic_set_tmr_level(vlapic, dest, phys, delmode, vector); + } + VIOAPIC_UNLOCK(vioapic); +} + static uint32_t -vioapic_read(struct vioapic *vioapic, uint32_t addr) >>> TRUNCATED FOR MAIL (1000 lines) <<< From owner-p4-projects@FreeBSD.ORG Sat Jan 18 22:35:33 2014 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 1DA51D88; Sat, 18 Jan 2014 22:35:33 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id D372CD86 for ; Sat, 18 Jan 2014 22:35:32 +0000 (UTC) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:1900:2254:2068::682:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id BC79416E4 for ; Sat, 18 Jan 2014 22:35:32 +0000 (UTC) Received: from skunkworks.freebsd.org ([127.0.1.74]) by skunkworks.freebsd.org (8.14.7/8.14.7) with ESMTP id s0IMZWIq029857 for ; Sat, 18 Jan 2014 22:35:32 GMT (envelope-from jhb@freebsd.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.7/8.14.7/Submit) id s0IMZWRU029854 for perforce@freebsd.org; Sat, 18 Jan 2014 22:35:32 GMT (envelope-from jhb@freebsd.org) Date: Sat, 18 Jan 2014 22:35:32 GMT Message-Id: <201401182235.s0IMZWRU029854@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to jhb@freebsd.org using -f From: John Baldwin Subject: PERFORCE change 1190145 for review To: Perforce Change Reviews Precedence: bulk X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.17 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 18 Jan 2014 22:35:33 -0000 http://p4web.freebsd.org/@@1190145?ac=10 Change 1190145 by jhb@jhb_jhbbsd on 2014/01/18 22:35:13 Update for changes to add -V and selector support to -l. Affected files ... .. //depot/projects/pci/usr.sbin/pciconf/pciconf.8#2 edit Differences ... ==== //depot/projects/pci/usr.sbin/pciconf/pciconf.8#2 (text+ko) ==== @@ -33,7 +33,7 @@ .Nd diagnostic utility for the PCI bus .Sh SYNOPSIS .Nm -.Fl l Op Fl bcev +.Fl l Oo Fl bcevV Oc Op Ar selector .Nm .Fl a Ar selector .Nm @@ -54,7 +54,9 @@ .Pp With the .Fl l -option, it lists all devices found by the boot probe in the following format: +option, +.Nm +lists PCI devices in the following format: .Bd -literal foo0@pci0:0:4:0: class=0x010000 card=0x00000000 chip=0x000f1000 rev=0x01 \ hdr=0x00 @@ -182,6 +184,36 @@ will attempt to load the vendor/device information database, and print vendor, device, class and subclass identification strings for each device. .Pp +If the +.Fl V +option is supplied, +.Nm +will list any vital product data +.Pq VPD +provided by each device. +Each VPD keyword is enumerated via a line in the following format: +.Bd -literal + VPD ro PN = '110114640C0 ' +.Ed +.Pp +The first string after the +.Dq Li VPD +prefix indicates if the keyword is read-only +.Dq ro +or read-write +.Dq rw . +The second string provides the keyword name. +The text after the the equals sign lists the value of the keyword which is +usually an ASCII string. +.Pp +If the optional +.Ar selector +argument is given with the +.Fl l +flag, +.Nm +will only list details about a single device instead of all devices. +.Pp All invocations of .Nm except for From owner-p4-projects@FreeBSD.ORG Sat Jan 18 23:13:14 2014 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 73A54A25; Sat, 18 Jan 2014 23:13:14 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 358C0A23 for ; Sat, 18 Jan 2014 23:13:14 +0000 (UTC) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:1900:2254:2068::682:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 15E4D191F for ; Sat, 18 Jan 2014 23:13:14 +0000 (UTC) Received: from skunkworks.freebsd.org ([127.0.1.74]) by skunkworks.freebsd.org (8.14.7/8.14.7) with ESMTP id s0INDD7o036844 for ; Sat, 18 Jan 2014 23:13:13 GMT (envelope-from jhb@freebsd.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.7/8.14.7/Submit) id s0INDDAT036841 for perforce@freebsd.org; Sat, 18 Jan 2014 23:13:13 GMT (envelope-from jhb@freebsd.org) Date: Sat, 18 Jan 2014 23:13:13 GMT Message-Id: <201401182313.s0INDDAT036841@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to jhb@freebsd.org using -f From: John Baldwin Subject: PERFORCE change 1190148 for review To: Perforce Change Reviews Precedence: bulk X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.17 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 18 Jan 2014 23:13:14 -0000 http://p4web.freebsd.org/@@1190148?ac=10 Change 1190148 by jhb@jhb_pippin on 2014/01/18 23:12:19 Allow PCI devices that are attached to a driver to be identified by their device name in addition to the selector. Affected files ... .. //depot/projects/pci/usr.sbin/pciconf/pciconf.8#3 edit .. //depot/projects/pci/usr.sbin/pciconf/pciconf.c#3 edit Differences ... ==== //depot/projects/pci/usr.sbin/pciconf/pciconf.8#3 (text+ko) ==== @@ -33,13 +33,13 @@ .Nd diagnostic utility for the PCI bus .Sh SYNOPSIS .Nm -.Fl l Oo Fl bcevV Oc Op Ar selector +.Fl l Oo Fl bcevV Oc Op Ar device .Nm -.Fl a Ar selector +.Fl a Ar device .Nm -.Fl r Oo Fl b | h Oc Ar selector addr Ns Op : Ns Ar addr2 +.Fl r Oo Fl b | h Oc Ar device addr Ns Op : Ns Ar addr2 .Nm -.Fl w Oo Fl b | h Oc Ar selector addr value +.Fl w Oo Fl b | h Oc Ar device addr value .Sh DESCRIPTION The .Nm @@ -67,16 +67,14 @@ .Ed .Pp The first column gives the -device name, unit number, and -.Ar selector . +device name, unit number, and selector . If there is no device configured in the kernel for the .Tn PCI device in question, the device name will be .Dq none . Unit numbers for unconfigured devices start at zero and are incremented for each unconfigured device that is encountered. -The -.Ar selector +The selector is in a form which may directly be used for the other forms of the command. The second column is the class code, with the class byte printed as two hex digits, followed by the sub-class and the interface bytes. @@ -207,7 +205,7 @@ usually an ASCII string. .Pp If the optional -.Ar selector +.Ar device argument is given with the .Fl l flag, @@ -219,13 +217,23 @@ except for .Fl l require a -.Ar selector -of the form +.Ar device . +The device can be identified either by a device name if the device is +attached to a driver or by a selector. +Selectors identify a PCI device by its address in PCI config space and +can take one of the following forms: +.Pp +.Bl -bullet -offset indent -compact +.It .Li pci Ns Va domain Ns \&: Ns Va bus Ns \&: Ns Va device Ns \&: \ -Ns Va function Ns , -.Li pci Ns Va bus Ns \&: Ns Va device Ns \&: Ns Va function Ns , or -.Li pci Ns Va bus Ns \&: Ns Va device Ns . -In case of an abridged form, omitted selector components are assumed to be 0. +Ns Va function Ns +.It +.Li pci Ns Va bus Ns \&: Ns Va device Ns \&: Ns Va function Ns +.It +.Li pci Ns Va bus Ns \&: Ns Va device Ns +.El +.Pp +In the case of an abridged form, omitted selector components are assumed to be 0. An optional leading device name followed by @ and an optional final colon will be ignored; this is so that the first column in the output of .Nm ==== //depot/projects/pci/usr.sbin/pciconf/pciconf.c#3 (text+ko) ==== @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -636,7 +637,61 @@ } static struct pcisel -getsel(const char *str) +getdevice(const char *name) +{ + struct pci_conf_io pc; + struct pci_conf conf[1]; + struct pci_match_conf patterns[1]; + char *cp; + int fd; + + fd = open(_PATH_DEVPCI, O_RDONLY, 0); + if (fd < 0) + err(1, "%s", _PATH_DEVPCI); + + bzero(&pc, sizeof(struct pci_conf_io)); + pc.match_buf_len = sizeof(conf); + pc.matches = conf; + + bzero(&patterns, sizeof(patterns)); + + /* + * The pattern structure requires the unit to be split out from + * the driver name. Walk backwards from the end of the name to + * find the start of the unit. + */ + if (name[0] == '\0') + err(1, "Empty device name"); + cp = strchr(name, '\0'); + assert(cp != NULL && cp != name); + cp--; + while (cp != name && isdigit(cp[-1])) + cp--; + if (cp == name) + errx(1, "Invalid device name"); + if ((size_t)(cp - name) + 1 > sizeof(patterns[0].pd_name)) + errx(1, "Device name i2s too long"); + memcpy(patterns[0].pd_name, name, cp - name); + patterns[0].pd_unit = strtol(cp, &cp, 10); + assert(*cp == '\0'); + patterns[0].flags = PCI_GETCONF_MATCH_NAME | PCI_GETCONF_MATCH_UNIT; + pc.num_patterns = 1; + pc.pat_buf_len = sizeof(patterns); + pc.patterns = patterns; + + if (ioctl(fd, PCIOCGETCONF, &pc) == -1) + err(1, "ioctl(PCIOCGETCONF)"); + if (pc.status != PCI_GETCONF_LAST_DEVICE && + pc.status != PCI_GETCONF_MORE_DEVS) + errx(1, "error returned from PCIOCGETCONF ioctl"); + close(fd); + if (pc.num_matches == 0) + errx(1, "Device not found"); + return (conf[0].pc_sel); +} + +static struct pcisel +parsesel(const char *str) { char *ep = strchr(str, '@'); char *epbase; @@ -674,6 +729,20 @@ return sel; } +static struct pcisel +getsel(const char *str) +{ + + /* + * No device names contain colons and raw selectors always + * contain at least one colon. + */ + if (strchr(str, ':') == NULL) + return (getdevice(str)); + else + return (parsesel(str)); +} + static void readone(int fd, struct pcisel *sel, long reg, int width) {