From 3ff6178ab58078083649354dc56cc75205f4779a Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Mon, 2 May 2011 22:54:24 +0000 Subject: [PATCH 01/25] Add LINT-NOINET6 which we have inofficially supported for years and our users complained when broken. Similarly add LINT-NOINET, and for at least documentation purposes add LINT-NOIP (which compiles out INET and INET6 and couple of NIC drivers). Tested by: make universe (if you broke it since you fix it) Reviewed by: gnn Sponsored by: The FreeBSD Foundation Sponsored by: iXsystems MFC after: 2 weeks --- sys/conf/makeLINT.mk | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/sys/conf/makeLINT.mk b/sys/conf/makeLINT.mk index e5ac2217e53a..50a74a34dcc9 100644 --- a/sys/conf/makeLINT.mk +++ b/sys/conf/makeLINT.mk @@ -16,6 +16,34 @@ LINT: ${NOTES} ../../conf/makeLINT.sed echo "include ${.TARGET}" > ${.TARGET}-VIMAGE echo "ident ${.TARGET}-VIMAGE" >> ${.TARGET}-VIMAGE echo "options VIMAGE" >> ${.TARGET}-VIMAGE + echo "include ${.TARGET}" > ${.TARGET}-NOINET + echo "ident ${.TARGET}-NOINET" >> ${.TARGET}-NOINET + echo 'makeoptions MKMODULESENV+="WITHOUT_INET_SUPPORT="' >> ${.TARGET}-NOINET + echo "nooptions INET" >> ${.TARGET}-NOINET + echo "nodevice gre" >> ${.TARGET}-NOINET + echo "include ${.TARGET}" > ${.TARGET}-NOINET6 + echo "ident ${.TARGET}-NOINET6" >> ${.TARGET}-NOINET6 + echo "nooptions INET6" >> ${.TARGET}-NOINET6 + echo "include ${.TARGET}" > ${.TARGET}-NOIP + echo "ident ${.TARGET}-NOIP" >> ${.TARGET}-NOIP + echo 'makeoptions MKMODULESENV+="WITHOUT_INET_SUPPORT="' >> ${.TARGET}-NOIP + echo 'makeoptions MKMODULESENV+="WITHOUT_INET6_SUPPORT="' >> ${.TARGET}-NOIP + echo "nooptions INET" >> ${.TARGET}-NOIP + echo "nooptions INET6" >> ${.TARGET}-NOIP + echo "nodevice age" >> ${.TARGET}-NOIP + echo "nodevice alc" >> ${.TARGET}-NOIP + echo "nodevice ale" >> ${.TARGET}-NOIP + echo "nodevice bxe" >> ${.TARGET}-NOIP + echo "nodevice em" >> ${.TARGET}-NOIP + echo "nodevice fxp" >> ${.TARGET}-NOIP + echo "nodevice igb" >> ${.TARGET}-NOIP + echo "nodevice jme" >> ${.TARGET}-NOIP + echo "nodevice msk" >> ${.TARGET}-NOIP + echo "nodevice mxge" >> ${.TARGET}-NOIP + echo "nodevice sge" >> ${.TARGET}-NOIP + echo "nodevice sk" >> ${.TARGET}-NOIP + echo "nodevice txp" >> ${.TARGET}-NOIP + echo "nodevice vxge" >> ${.TARGET}-NOIP .endif .if ${TARGET} == "powerpc" || ${TARGET} == "mips" echo "machine ${TARGET} ${TARGET_ARCH}" >> ${.TARGET} From f83b279588ca2dd217308cb426f7f4cc29be87db Mon Sep 17 00:00:00 2001 From: David Christensen Date: Mon, 2 May 2011 23:34:33 +0000 Subject: [PATCH 02/25] - Fixed a typo in an if() statement when setting flow control for MTU greater than 5000 bytes. Submitted by: yongari --- sys/dev/bxe/if_bxe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/bxe/if_bxe.c b/sys/dev/bxe/if_bxe.c index a877ba02488e..05ed74719f4c 100644 --- a/sys/dev/bxe/if_bxe.c +++ b/sys/dev/bxe/if_bxe.c @@ -3600,7 +3600,7 @@ bxe_initial_phy_init(struct bxe_softc *sc) * It is recommended to turn off RX flow control for 5771x * when using jumbo frames for better performance. */ - if (!IS_E1HMF(sc) & (sc->mbuf_alloc_size > 5000)) + if (!IS_E1HMF(sc) && (sc->mbuf_alloc_size > 5000)) sc->link_params.req_fc_auto_adv = FLOW_CTRL_TX; else sc->link_params.req_fc_auto_adv = FLOW_CTRL_BOTH; From e94b542e024f15e3348878a12606641dcd3bfc33 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Tue, 3 May 2011 01:43:04 +0000 Subject: [PATCH 03/25] Fix corner case where the size is a power of two. --- sys/boot/ia64/common/exec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/boot/ia64/common/exec.c b/sys/boot/ia64/common/exec.c index 6c7f0279f0ba..dd9c9ba05e63 100644 --- a/sys/boot/ia64/common/exec.c +++ b/sys/boot/ia64/common/exec.c @@ -76,7 +76,7 @@ sz2shft(vm_offset_t ofs, vm_size_t sz) shft = 12; /* Start with 4K */ s = 1 << shft; - while (s < sz) { + while (s <= sz) { shft++; s <<= 1; } From 74ff69fe440970de0ca87411a48ea7aa78182a8a Mon Sep 17 00:00:00 2001 From: Craig Rodrigues Date: Tue, 3 May 2011 04:44:50 +0000 Subject: [PATCH 04/25] Switch to ANSI function prototypes in a few places. Get rid of some unused parameter warnings. --- lib/libstand/__main.c | 2 +- lib/libstand/bswap.c | 9 ++++---- lib/libstand/cd9660.c | 2 +- lib/libstand/environment.c | 5 +++-- lib/libstand/getopt.c | 5 +---- lib/libstand/tftp.c | 42 ++++++++++---------------------------- 6 files changed, 22 insertions(+), 43 deletions(-) diff --git a/lib/libstand/__main.c b/lib/libstand/__main.c index 1c7e67703e0d..e38f33865c05 100644 --- a/lib/libstand/__main.c +++ b/lib/libstand/__main.c @@ -38,6 +38,6 @@ __FBSDID("$FreeBSD$"); void __main(void); void -__main() +__main(void) { } diff --git a/lib/libstand/bswap.c b/lib/libstand/bswap.c index a9bd323b7f62..212e2afe4b81 100644 --- a/lib/libstand/bswap.c +++ b/lib/libstand/bswap.c @@ -16,9 +16,11 @@ static char *rcsid = "$NetBSD: bswap64.c,v 1.1 1997/10/09 15:42:33 bouyer Exp $" #undef bswap32 #undef bswap64 +u_int32_t bswap32(u_int32_t x); +u_int64_t bswap64(u_int64_t x); + u_int32_t -bswap32(x) - u_int32_t x; +bswap32(u_int32_t x) { return ((x << 24) & 0xff000000 ) | ((x << 8) & 0x00ff0000 ) | @@ -27,8 +29,7 @@ bswap32(x) } u_int64_t -bswap64(x) - u_int64_t x; +bswap64(u_int64_t x) { u_int32_t *p = (u_int32_t*)&x; u_int32_t t; diff --git a/lib/libstand/cd9660.c b/lib/libstand/cd9660.c index 449480b5531e..c6bcef2ec9c2 100644 --- a/lib/libstand/cd9660.c +++ b/lib/libstand/cd9660.c @@ -545,7 +545,7 @@ cd9660_readdir(struct open_file *f, struct dirent *d) } static int -cd9660_write(struct open_file *f, void *start, size_t size, size_t *resid) +cd9660_write(struct open_file *f __unused, void *start __unused, size_t size __unused, size_t *resid __unused) { return EROFS; } diff --git a/lib/libstand/environment.c b/lib/libstand/environment.c index 3505ccd98d4d..fde4cf9c3874 100644 --- a/lib/libstand/environment.c +++ b/lib/libstand/environment.c @@ -207,13 +207,14 @@ env_discard(struct env_var *ev) } int -env_noset(struct env_var *ev, int flags, const void *value) +env_noset(struct env_var *ev __unused, int flags __unused, + const void *value __unused) { return(EPERM); } int -env_nounset(struct env_var *ev) +env_nounset(struct env_var *ev __unused) { return(EPERM); } diff --git a/lib/libstand/getopt.c b/lib/libstand/getopt.c index bb57fcd49e75..cfe405a85d63 100644 --- a/lib/libstand/getopt.c +++ b/lib/libstand/getopt.c @@ -52,10 +52,7 @@ char *optarg; /* argument associated with option */ * Parse argc/argv argument vector. */ int -getopt(nargc, nargv, ostr) - int nargc; - char * const *nargv; - const char *ostr; +getopt(int nargc, char * const *nargv, const char *ostr) { static char *place = EMSG; /* option letter processing */ char *oli; /* option letter list index */ diff --git a/lib/libstand/tftp.c b/lib/libstand/tftp.c index 23594bbd67b1..4a2ca69dda7a 100644 --- a/lib/libstand/tftp.c +++ b/lib/libstand/tftp.c @@ -110,11 +110,7 @@ static const int tftperrors[8] = { }; static ssize_t -recvtftp(d, pkt, len, tleft) - struct iodesc *d; - void *pkt; - ssize_t len; - time_t tleft; +recvtftp(struct iodesc *d, void *pkt, ssize_t len, time_t tleft) { struct tftphdr *t; @@ -168,8 +164,7 @@ recvtftp(d, pkt, len, tleft) /* send request, expect first block (or error) */ static int -tftp_makereq(h) - struct tftp_handle *h; +tftp_makereq(struct tftp_handle *h) { struct { u_char header[HEADER_SIZE]; @@ -212,8 +207,7 @@ tftp_makereq(h) /* ack block, expect next */ static int -tftp_getnextblock(h) - struct tftp_handle *h; +tftp_getnextblock(struct tftp_handle *h) { struct { u_char header[HEADER_SIZE]; @@ -246,9 +240,7 @@ tftp_getnextblock(h) } static int -tftp_open(path, f) - const char *path; - struct open_file *f; +tftp_open(const char *path, struct open_file *f) { struct tftp_handle *tftpfile; struct iodesc *io; @@ -287,11 +279,8 @@ tftp_open(path, f) } static int -tftp_read(f, addr, size, resid) - struct open_file *f; - void *addr; - size_t size; - size_t *resid; /* out */ +tftp_read(struct open_file *f, void *addr, size_t size, + size_t *resid /* out */) { struct tftp_handle *tftpfile; static int tc = 0; @@ -361,8 +350,7 @@ tftp_read(f, addr, size, resid) } static int -tftp_close(f) - struct open_file *f; +tftp_close(struct open_file *f) { struct tftp_handle *tftpfile; tftpfile = (struct tftp_handle *) f->f_fsdata; @@ -377,19 +365,14 @@ tftp_close(f) } static int -tftp_write(f, start, size, resid) - struct open_file *f; - void *start; - size_t size; - size_t *resid; /* out */ +tftp_write(struct open_file *f __unused, void *start __unused, size_t size __unused, + size_t *resid /* out */ __unused) { return (EROFS); } static int -tftp_stat(f, sb) - struct open_file *f; - struct stat *sb; +tftp_stat(struct open_file *f, struct stat *sb) { struct tftp_handle *tftpfile; tftpfile = (struct tftp_handle *) f->f_fsdata; @@ -403,10 +386,7 @@ tftp_stat(f, sb) } static off_t -tftp_seek(f, offset, where) - struct open_file *f; - off_t offset; - int where; +tftp_seek(struct open_file *f, off_t offset, int where) { struct tftp_handle *tftpfile; tftpfile = (struct tftp_handle *) f->f_fsdata; From a7ad07bff3f0501e3ea483955122f5da37519674 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Tue, 3 May 2011 07:32:58 +0000 Subject: [PATCH 05/25] Change the way rctl interfaces with jails by introducing prison_racct structure, which acts as a proxy between them. This makes jail rules persistent, i.e. they can be added before jail gets created, and they don't disappear when the jail gets destroyed. --- sys/kern/kern_jail.c | 116 ++++++++++++++++++++++++++++++++++++++---- sys/kern/kern_racct.c | 14 +++-- sys/kern/kern_rctl.c | 95 ++++++++++++++-------------------- sys/sys/jail.h | 13 ++++- sys/sys/rctl.h | 4 +- usr.bin/rctl/rctl.8 | 8 +-- 6 files changed, 171 insertions(+), 79 deletions(-) diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index 22b97e854ad1..5850ad1b512b 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -50,7 +50,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include #include #include #include @@ -78,6 +78,7 @@ __FBSDID("$FreeBSD$"); #define DEFAULT_HOSTUUID "00000000-0000-0000-0000-000000000000" MALLOC_DEFINE(M_PRISON, "prison", "Prison structures"); +MALLOC_DEFINE(M_PRISON_RACCT, "prison_racct", "Prison racct structures"); /* Keep struct prison prison0 and some code in kern_jail_set() readable. */ #ifdef INET @@ -114,10 +115,11 @@ struct prison prison0 = { }; MTX_SYSINIT(prison0, &prison0.pr_mtx, "jail mutex", MTX_DEF); -/* allprison and lastprid are protected by allprison_lock. */ +/* allprison, allprison_racct and lastprid are protected by allprison_lock. */ struct sx allprison_lock; SX_SYSINIT(allprison_lock, &allprison_lock, "allprison"); struct prisonlist allprison = TAILQ_HEAD_INITIALIZER(allprison); +LIST_HEAD(, prison_racct) allprison_racct; int lastprid = 0; static int do_jail_attach(struct thread *td, struct prison *pr); @@ -125,6 +127,10 @@ static void prison_complete(void *context, int pending); static void prison_deref(struct prison *pr, int flags); static char *prison_path(struct prison *pr1, struct prison *pr2); static void prison_remove_one(struct prison *pr); +#ifdef RACCT +static void prison_racct_attach(struct prison *pr); +static void prison_racct_detach(struct prison *pr); +#endif #ifdef INET static int _prison_check_ip4(struct prison *pr, struct in_addr *ia); static int prison_restrict_ip4(struct prison *pr, struct in_addr *newip4); @@ -1197,7 +1203,6 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags) root = mypr->pr_root; vref(root); } - racct_create(&pr->pr_racct); strlcpy(pr->pr_hostuuid, DEFAULT_HOSTUUID, HOSTUUIDLEN); pr->pr_flags |= PR_HOST; #if defined(INET) || defined(INET6) @@ -1657,6 +1662,11 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags) pr->pr_flags = (pr->pr_flags & ~ch_flags) | pr_flags; mtx_unlock(&pr->pr_mtx); +#ifdef RACCT + if (created) + prison_racct_attach(pr); +#endif + /* Locks may have prevented a complete restriction of child IP * addresses. If so, allocate some more memory and try again. */ @@ -2533,10 +2543,9 @@ prison_deref(struct prison *pr, int flags) if (pr->pr_cpuset != NULL) cpuset_rel(pr->pr_cpuset); osd_jail_exit(pr); -#ifdef RCTL - rctl_racct_release(pr->pr_racct); +#ifdef RACCT + prison_racct_detach(pr); #endif - racct_destroy(&pr->pr_racct); free(pr, M_PRISON); /* Removing a prison frees a reference on its parent. */ @@ -4277,14 +4286,103 @@ void prison_racct_foreach(void (*callback)(struct racct *racct, void *arg2, void *arg3), void *arg2, void *arg3) { - struct prison *pr; + struct prison_racct *prr; sx_slock(&allprison_lock); - TAILQ_FOREACH(pr, &allprison, pr_list) - (callback)(pr->pr_racct, arg2, arg3); + LIST_FOREACH(prr, &allprison_racct, prr_next) + (callback)(prr->prr_racct, arg2, arg3); sx_sunlock(&allprison_lock); } +static struct prison_racct * +prison_racct_find_locked(const char *name) +{ + struct prison_racct *prr; + + sx_assert(&allprison_lock, SA_XLOCKED); + + if (name[0] == '\0' || strlen(name) >= MAXHOSTNAMELEN) + return (NULL); + + LIST_FOREACH(prr, &allprison_racct, prr_next) { + if (strcmp(name, prr->prr_name) != 0) + continue; + + /* Found prison_racct with a matching name? */ + prison_racct_hold(prr); + return (prr); + } + + /* Add new prison_racct. */ + prr = malloc(sizeof(*prr), M_PRISON_RACCT, M_ZERO | M_WAITOK); + racct_create(&prr->prr_racct); + + strcpy(prr->prr_name, name); + refcount_init(&prr->prr_refcount, 1); + LIST_INSERT_HEAD(&allprison_racct, prr, prr_next); + + return (prr); +} + +struct prison_racct * +prison_racct_find(const char *name) +{ + struct prison_racct *prr; + + sx_xlock(&allprison_lock); + prr = prison_racct_find_locked(name); + sx_xunlock(&allprison_lock); + return (prr); +} + +void +prison_racct_hold(struct prison_racct *prr) +{ + + refcount_acquire(&prr->prr_refcount); +} + +void +prison_racct_free(struct prison_racct *prr) +{ + int old; + + old = prr->prr_refcount; + if (old > 1 && atomic_cmpset_int(&prr->prr_refcount, old, old - 1)) + return; + + sx_xlock(&allprison_lock); + if (refcount_release(&prr->prr_refcount)) { + racct_destroy(&prr->prr_racct); + LIST_REMOVE(prr, prr_next); + sx_xunlock(&allprison_lock); + free(prr, M_PRISON_RACCT); + + return; + } + sx_xunlock(&allprison_lock); +} + +#ifdef RACCT +static void +prison_racct_attach(struct prison *pr) +{ + struct prison_racct *prr; + + prr = prison_racct_find_locked(pr->pr_name); + KASSERT(prr != NULL, ("cannot find prison_racct")); + + pr->pr_prison_racct = prr; +} + +static void +prison_racct_detach(struct prison *pr) +{ + prison_racct_free(pr->pr_prison_racct); + pr->pr_prison_racct = NULL; +} +#endif /* RACCT */ + #ifdef DDB static void diff --git a/sys/kern/kern_racct.c b/sys/kern/kern_racct.c index 5778bfe54d77..98bd9c56a0ed 100644 --- a/sys/kern/kern_racct.c +++ b/sys/kern/kern_racct.c @@ -313,7 +313,8 @@ racct_add_cred_locked(struct ucred *cred, int resource, uint64_t amount) racct_alloc_resource(cred->cr_ruidinfo->ui_racct, resource, amount); for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent) - racct_alloc_resource(pr->pr_racct, resource, amount); + racct_alloc_resource(pr->pr_prison_racct->prr_racct, resource, + amount); racct_alloc_resource(cred->cr_loginclass->lc_racct, resource, amount); } @@ -522,7 +523,8 @@ racct_sub_cred_locked(struct ucred *cred, int resource, uint64_t amount) racct_alloc_resource(cred->cr_ruidinfo->ui_racct, resource, -amount); for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent) - racct_alloc_resource(pr->pr_racct, resource, -amount); + racct_alloc_resource(pr->pr_prison_racct->prr_racct, resource, + -amount); racct_alloc_resource(cred->cr_loginclass->lc_racct, resource, -amount); } @@ -669,9 +671,11 @@ racct_proc_ucred_changed(struct proc *p, struct ucred *oldcred, } if (newpr != oldpr) { for (pr = oldpr; pr != NULL; pr = pr->pr_parent) - racct_sub_racct(pr->pr_racct, p->p_racct); + racct_sub_racct(pr->pr_prison_racct->prr_racct, + p->p_racct); for (pr = newpr; pr != NULL; pr = pr->pr_parent) - racct_add_racct(pr->pr_racct, p->p_racct); + racct_add_racct(pr->pr_prison_racct->prr_racct, + p->p_racct); } mtx_unlock(&racct_lock); @@ -744,7 +748,7 @@ racct_init(void) /* * XXX: Move this somewhere. */ - racct_create(&prison0.pr_racct); + prison0.pr_prison_racct = prison_racct_find("0"); } SYSINIT(racct, SI_SUB_RACCT, SI_ORDER_FIRST, racct_init, NULL); diff --git a/sys/kern/kern_rctl.c b/sys/kern/kern_rctl.c index 88a971c932e8..2d43bdce521c 100644 --- a/sys/kern/kern_rctl.c +++ b/sys/kern/kern_rctl.c @@ -241,7 +241,8 @@ rctl_available_resource(const struct proc *p, const struct rctl_rule *rule) break; case RCTL_SUBJECT_TYPE_JAIL: available = rule->rr_amount - - cred->cr_prison->pr_racct->r_resources[resource]; + cred->cr_prison->pr_prison_racct->prr_racct-> + r_resources[resource]; break; default: panic("rctl_compute_available: unknown per %d", @@ -327,7 +328,7 @@ rctl_enforce(struct proc *p, int resource, uint64_t amount) printf("rctl: rule \"%s\" matched by pid %d " "(%s), uid %d, jail %s\n", sbuf_data(&sb), p->p_pid, p->p_comm, p->p_ucred->cr_uid, - p->p_ucred->cr_prison->pr_name); + p->p_ucred->cr_prison->pr_prison_racct->prr_name); sbuf_delete(&sb); free(buf, M_RCTL); link->rrl_exceeded = 1; @@ -346,7 +347,7 @@ rctl_enforce(struct proc *p, int resource, uint64_t amount) rctl_rule_to_sbuf(&sb, rule); sbuf_printf(&sb, " pid=%d ruid=%d jail=%s", p->p_pid, p->p_ucred->cr_ruid, - p->p_ucred->cr_prison->pr_name); + p->p_ucred->cr_prison->pr_prison_racct->prr_name); sbuf_finish(&sb); devctl_notify_f("RCTL", "rule", "matched", sbuf_data(&sb), M_NOWAIT); @@ -481,9 +482,9 @@ rctl_rule_matches(const struct rctl_rule *rule, const struct rctl_rule *filter) return (0); break; case RCTL_SUBJECT_TYPE_JAIL: - if (filter->rr_subject.rs_prison != NULL && - rule->rr_subject.rs_prison != - filter->rr_subject.rs_prison) + if (filter->rr_subject.rs_prison_racct != NULL && + rule->rr_subject.rs_prison_racct != + filter->rr_subject.rs_prison_racct) return (0); break; default: @@ -635,7 +636,10 @@ rctl_rule_acquire_subject(struct rctl_rule *rule) switch (rule->rr_subject_type) { case RCTL_SUBJECT_TYPE_UNDEFINED: case RCTL_SUBJECT_TYPE_PROCESS: + break; case RCTL_SUBJECT_TYPE_JAIL: + if (rule->rr_subject.rs_prison_racct != NULL) + prison_racct_hold(rule->rr_subject.rs_prison_racct); break; case RCTL_SUBJECT_TYPE_USER: if (rule->rr_subject.rs_uip != NULL) @@ -658,7 +662,10 @@ rctl_rule_release_subject(struct rctl_rule *rule) switch (rule->rr_subject_type) { case RCTL_SUBJECT_TYPE_UNDEFINED: case RCTL_SUBJECT_TYPE_PROCESS: + break; case RCTL_SUBJECT_TYPE_JAIL: + if (rule->rr_subject.rs_prison_racct != NULL) + prison_racct_free(rule->rr_subject.rs_prison_racct); break; case RCTL_SUBJECT_TYPE_USER: if (rule->rr_subject.rs_uip != NULL) @@ -686,7 +693,7 @@ rctl_rule_alloc(int flags) rule->rr_subject.rs_proc = NULL; rule->rr_subject.rs_uip = NULL; rule->rr_subject.rs_loginclass = NULL; - rule->rr_subject.rs_prison = NULL; + rule->rr_subject.rs_prison_racct = NULL; rule->rr_per = RCTL_SUBJECT_TYPE_UNDEFINED; rule->rr_resource = RACCT_UNDEFINED; rule->rr_action = RCTL_ACTION_UNDEFINED; @@ -708,7 +715,7 @@ rctl_rule_duplicate(const struct rctl_rule *rule, int flags) copy->rr_subject.rs_proc = rule->rr_subject.rs_proc; copy->rr_subject.rs_uip = rule->rr_subject.rs_uip; copy->rr_subject.rs_loginclass = rule->rr_subject.rs_loginclass; - copy->rr_subject.rs_prison = rule->rr_subject.rs_prison; + copy->rr_subject.rs_prison_racct = rule->rr_subject.rs_prison_racct; copy->rr_per = rule->rr_per; copy->rr_resource = rule->rr_resource; copy->rr_action = rule->rr_action; @@ -784,7 +791,7 @@ rctl_rule_fully_specified(const struct rctl_rule *rule) return (0); break; case RCTL_SUBJECT_TYPE_JAIL: - if (rule->rr_subject.rs_prison == NULL) + if (rule->rr_subject.rs_prison_racct == NULL) return (0); break; default: @@ -833,7 +840,7 @@ rctl_string_to_rule(char *rulestr, struct rctl_rule **rulep) rule->rr_subject.rs_proc = NULL; rule->rr_subject.rs_uip = NULL; rule->rr_subject.rs_loginclass = NULL; - rule->rr_subject.rs_prison = NULL; + rule->rr_subject.rs_prison_racct = NULL; } else { switch (rule->rr_subject_type) { case RCTL_SUBJECT_TYPE_UNDEFINED: @@ -866,23 +873,12 @@ rctl_string_to_rule(char *rulestr, struct rctl_rule **rulep) } break; case RCTL_SUBJECT_TYPE_JAIL: - rule->rr_subject.rs_prison = - prison_find_name(&prison0, subject_idstr); - if (rule->rr_subject.rs_prison == NULL) { - /* - * No jail with that name; try with the JID. - */ - error = str2id(subject_idstr, &id); - if (error != 0) - goto out; - rule->rr_subject.rs_prison = prison_find(id); - if (rule->rr_subject.rs_prison == NULL) { - error = ESRCH; - goto out; - } + rule->rr_subject.rs_prison_racct = + prison_racct_find(subject_idstr); + if (rule->rr_subject.rs_prison_racct == NULL) { + error = ENAMETOOLONG; + goto out; } - /* prison_find() returns with mutex held. */ - mtx_unlock(&rule->rr_subject.rs_prison->pr_mtx); break; default: panic("rctl_string_to_rule: unknown subject type %d", @@ -944,6 +940,7 @@ rctl_rule_add(struct rctl_rule *rule) struct ucred *cred; struct uidinfo *uip; struct prison *pr; + struct prison_racct *prr; struct loginclass *lc; struct rctl_rule *rule2; int match; @@ -1008,9 +1005,9 @@ rctl_rule_add(struct rctl_rule *rule) break; case RCTL_SUBJECT_TYPE_JAIL: - pr = rule->rr_subject.rs_prison; - KASSERT(pr != NULL, ("rctl_rule_add: NULL pr")); - rctl_racct_add_rule(pr->pr_racct, rule); + prr = rule->rr_subject.rs_prison_racct; + KASSERT(prr != NULL, ("rctl_rule_add: NULL pr")); + rctl_racct_add_rule(prr->prr_racct, rule); break; default: @@ -1040,7 +1037,7 @@ rctl_rule_add(struct rctl_rule *rule) case RCTL_SUBJECT_TYPE_JAIL: match = 0; for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent) { - if (pr == rule->rr_subject.rs_prison) { + if (pr->pr_prison_racct == rule->rr_subject.rs_prison_racct) { match = 1; break; } @@ -1144,11 +1141,11 @@ rctl_rule_to_sbuf(struct sbuf *sb, const struct rctl_rule *rule) rule->rr_subject.rs_loginclass->lc_name); break; case RCTL_SUBJECT_TYPE_JAIL: - if (rule->rr_subject.rs_prison == NULL) + if (rule->rr_subject.rs_prison_racct == NULL) sbuf_printf(sb, ":"); else sbuf_printf(sb, "%s:", - rule->rr_subject.rs_prison->pr_name); + rule->rr_subject.rs_prison_racct->prr_name); break; default: panic("rctl_rule_to_sbuf: unknown subject type %d", @@ -1245,7 +1242,7 @@ rctl_get_racct(struct thread *td, struct rctl_get_racct_args *uap) struct proc *p; struct uidinfo *uip; struct loginclass *lc; - struct prison *pr; + struct prison_racct *prr; error = priv_check(td, PRIV_RCTL_GET_RACCT); if (error != 0) @@ -1256,11 +1253,9 @@ rctl_get_racct(struct thread *td, struct rctl_get_racct_args *uap) return (error); sx_slock(&allproc_lock); - sx_slock(&allprison_lock); error = rctl_string_to_rule(inputstr, &filter); free(inputstr, M_RCTL); if (error != 0) { - sx_sunlock(&allprison_lock); sx_sunlock(&allproc_lock); return (error); } @@ -1295,19 +1290,18 @@ rctl_get_racct(struct thread *td, struct rctl_get_racct_args *uap) outputsbuf = rctl_racct_to_sbuf(lc->lc_racct, 1); break; case RCTL_SUBJECT_TYPE_JAIL: - pr = filter->rr_subject.rs_prison; - if (pr == NULL) { + prr = filter->rr_subject.rs_prison_racct; + if (prr == NULL) { error = EINVAL; goto out; } - outputsbuf = rctl_racct_to_sbuf(pr->pr_racct, 1); + outputsbuf = rctl_racct_to_sbuf(prr->prr_racct, 1); break; default: error = EINVAL; } out: rctl_rule_release(filter); - sx_sunlock(&allprison_lock); sx_sunlock(&allproc_lock); if (error != 0) return (error); @@ -1354,11 +1348,9 @@ rctl_get_rules(struct thread *td, struct rctl_get_rules_args *uap) return (error); sx_slock(&allproc_lock); - sx_slock(&allprison_lock); error = rctl_string_to_rule(inputstr, &filter); free(inputstr, M_RCTL); if (error != 0) { - sx_sunlock(&allprison_lock); sx_sunlock(&allproc_lock); return (error); } @@ -1406,7 +1398,6 @@ rctl_get_rules(struct thread *td, struct rctl_get_rules_args *uap) error = rctl_write_outbuf(sb, uap->outbufp, uap->outbuflen); rctl_rule_release(filter); - sx_sunlock(&allprison_lock); sx_sunlock(&allproc_lock); free(buf, M_RCTL); return (error); @@ -1431,30 +1422,25 @@ rctl_get_limits(struct thread *td, struct rctl_get_limits_args *uap) return (error); sx_slock(&allproc_lock); - sx_slock(&allprison_lock); error = rctl_string_to_rule(inputstr, &filter); free(inputstr, M_RCTL); if (error != 0) { - sx_sunlock(&allprison_lock); sx_sunlock(&allproc_lock); return (error); } if (filter->rr_subject_type == RCTL_SUBJECT_TYPE_UNDEFINED) { rctl_rule_release(filter); - sx_sunlock(&allprison_lock); sx_sunlock(&allproc_lock); return (EINVAL); } if (filter->rr_subject_type != RCTL_SUBJECT_TYPE_PROCESS) { rctl_rule_release(filter); - sx_sunlock(&allprison_lock); sx_sunlock(&allproc_lock); return (EOPNOTSUPP); } if (filter->rr_subject.rs_proc == NULL) { rctl_rule_release(filter); - sx_sunlock(&allprison_lock); sx_sunlock(&allproc_lock); return (EINVAL); } @@ -1486,7 +1472,6 @@ rctl_get_limits(struct thread *td, struct rctl_get_limits_args *uap) error = rctl_write_outbuf(sb, uap->outbufp, uap->outbuflen); rctl_rule_release(filter); - sx_sunlock(&allprison_lock); sx_sunlock(&allproc_lock); free(buf, M_RCTL); return (error); @@ -1508,11 +1493,9 @@ rctl_add_rule(struct thread *td, struct rctl_add_rule_args *uap) return (error); sx_slock(&allproc_lock); - sx_slock(&allprison_lock); error = rctl_string_to_rule(inputstr, &rule); free(inputstr, M_RCTL); if (error != 0) { - sx_sunlock(&allprison_lock); sx_sunlock(&allproc_lock); return (error); } @@ -1532,7 +1515,6 @@ rctl_add_rule(struct thread *td, struct rctl_add_rule_args *uap) out: rctl_rule_release(rule); - sx_sunlock(&allprison_lock); sx_sunlock(&allproc_lock); return (error); } @@ -1553,18 +1535,15 @@ rctl_remove_rule(struct thread *td, struct rctl_remove_rule_args *uap) return (error); sx_slock(&allproc_lock); - sx_slock(&allprison_lock); error = rctl_string_to_rule(inputstr, &filter); free(inputstr, M_RCTL); if (error != 0) { - sx_sunlock(&allprison_lock); sx_sunlock(&allproc_lock); return (error); } error = rctl_rule_remove(filter); rctl_rule_release(filter); - sx_sunlock(&allprison_lock); sx_sunlock(&allproc_lock); return (error); @@ -1580,12 +1559,12 @@ rctl_proc_ucred_changed(struct proc *p, struct ucred *newcred) struct rctl_rule_link *link, *newlink; struct uidinfo *newuip; struct loginclass *newlc; - struct prison *newpr; + struct prison_racct *newprr; LIST_HEAD(, rctl_rule_link) newrules; newuip = newcred->cr_ruidinfo; newlc = newcred->cr_loginclass; - newpr = newcred->cr_prison; + newprr = newcred->cr_prison->pr_prison_racct; LIST_INIT(&newrules); @@ -1605,7 +1584,7 @@ rctl_proc_ucred_changed(struct proc *p, struct ucred *newcred) rulecnt++; LIST_FOREACH(link, &newlc->lc_racct->r_rule_links, rrl_next) rulecnt++; - LIST_FOREACH(link, &newpr->pr_racct->r_rule_links, rrl_next) + LIST_FOREACH(link, &newprr->prr_racct->r_rule_links, rrl_next) rulecnt++; rw_runlock(&rctl_lock); @@ -1655,7 +1634,7 @@ rctl_proc_ucred_changed(struct proc *p, struct ucred *newcred) rulecnt--; } - LIST_FOREACH(link, &newpr->pr_racct->r_rule_links, rrl_next) { + LIST_FOREACH(link, &newprr->prr_racct->r_rule_links, rrl_next) { if (newlink == NULL) goto goaround; rctl_rule_acquire(link->rrl_rule); diff --git a/sys/sys/jail.h b/sys/sys/jail.h index b83ac1b8a3c9..bbaf38162e7c 100644 --- a/sys/sys/jail.h +++ b/sys/sys/jail.h @@ -136,6 +136,7 @@ MALLOC_DECLARE(M_PRISON); #define HOSTUUIDLEN 64 struct racct; +struct prison_racct; /* * This structure describes a prison. It is pointed to by all struct @@ -168,7 +169,7 @@ struct prison { int pr_ip6s; /* (p) number of v6 IPs */ struct in_addr *pr_ip4; /* (p) v4 IPs of jail */ struct in6_addr *pr_ip6; /* (p) v6 IPs of jail */ - struct racct *pr_racct; /* (c) resource accounting */ + struct prison_racct *pr_prison_racct; /* (c) racct jail proxy */ void *pr_sparep[3]; int pr_childcount; /* (a) number of child jails */ int pr_childmax; /* (p) maximum child jails */ @@ -183,6 +184,13 @@ struct prison { char pr_domainname[MAXHOSTNAMELEN]; /* (p) jail domainname */ char pr_hostuuid[HOSTUUIDLEN]; /* (p) jail hostuuid */ }; + +struct prison_racct { + LIST_ENTRY(prison_racct) prr_next; + char prr_name[MAXHOSTNAMELEN]; + u_int prr_refcount; + struct racct *prr_racct; +}; #endif /* _KERNEL || _WANT_PRISON */ #ifdef _KERNEL @@ -385,6 +393,9 @@ int prison_priv_check(struct ucred *cred, int priv); int sysctl_jail_param(SYSCTL_HANDLER_ARGS); void prison_racct_foreach(void (*callback)(struct racct *racct, void *arg2, void *arg3), void *arg2, void *arg3); +struct prison_racct *prison_racct_find(const char *name); +void prison_racct_hold(struct prison_racct *prr); +void prison_racct_free(struct prison_racct *prr); #endif /* _KERNEL */ #endif /* !_SYS_JAIL_H_ */ diff --git a/sys/sys/rctl.h b/sys/sys/rctl.h index d61defd8e427..1e0342732b80 100644 --- a/sys/sys/rctl.h +++ b/sys/sys/rctl.h @@ -44,7 +44,7 @@ struct proc; struct uidinfo; struct loginclass; -struct prison; +struct prison_racct; struct ucred; struct rctl_rule_link; @@ -70,7 +70,7 @@ struct rctl_rule { struct proc *rs_proc; struct uidinfo *rs_uip; struct loginclass *rs_loginclass; - struct prison *rs_prison; + struct prison_racct *rs_prison_racct; } rr_subject; int rr_per; int rr_resource; diff --git a/usr.bin/rctl/rctl.8 b/usr.bin/rctl/rctl.8 index f30f4c3f024f..bddd3130ff25 100644 --- a/usr.bin/rctl/rctl.8 +++ b/usr.bin/rctl/rctl.8 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 14, 2011 +.Dd May 3, 2011 .Dt RCTL 8 .Os .Sh NAME @@ -90,7 +90,7 @@ Subject defines the kind of entity the rule applies to. It can be either process, user, login class, or jail. .Pp Subject ID identifies the subject. It can be user name, -numerical user ID, login class name, jail name, or numerical jail ID. +numerical user ID, login class name, or jail name. .Pp Resource identifies the resource the rule controls. .Pp @@ -177,9 +177,9 @@ Prevent user "joe" from allocating more than 1GB of virtual memory. .Pp Remove all RCTL rules. .Pp -.Dl rctl -hu jail:5 +.Dl rctl -hu jail:www .Pp -Display resource usage information for jail with JID 5. +Display resource usage information for jail named "www". .Pp .Dl rctl -l process:512 .Pp From d9711c28efc4ec89ba5ea11f8fd63e9d0a7fc81b Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" Date: Tue, 3 May 2011 07:33:39 +0000 Subject: [PATCH 06/25] Add "-a alignment" option to gpart(8). When it specified gpart(8) tries to align partition start offset and size to be multiple of alignment value. MFC after: 2 weeks --- sbin/geom/class/part/geom_part.c | 93 +++++++++++++++++++++++--------- sbin/geom/class/part/gpart.8 | 33 ++++++++++-- 2 files changed, 99 insertions(+), 27 deletions(-) diff --git a/sbin/geom/class/part/geom_part.c b/sbin/geom/class/part/geom_part.c index 8593d20891c0..ed7b8f830cc7 100644 --- a/sbin/geom/class/part/geom_part.c +++ b/sbin/geom/class/part/geom_part.c @@ -93,6 +93,7 @@ static void gpart_restore(struct gctl_req *, unsigned int); struct g_command PUBSYM(class_commands)[] = { { "add", 0, gpart_issue, { + { 'a', "alignment", GPART_AUTOFILL, G_TYPE_STRING }, { 'b', "start", GPART_AUTOFILL, G_TYPE_STRING }, { 's', "size", GPART_AUTOFILL, G_TYPE_STRING }, { 't', "type", NULL, G_TYPE_STRING }, @@ -100,7 +101,8 @@ struct g_command PUBSYM(class_commands)[] = { { 'l', "label", G_VAL_OPTIONAL, G_TYPE_STRING }, { 'f', "flags", GPART_FLAGS, G_TYPE_STRING }, G_OPT_SENTINEL }, - "[-b start] [-s size] -t type [-i index] [-l label] [-f flags] geom" + "[-a alignment] [-b start] [-s size] -t type [-i index] " + "[-l label] [-f flags] geom" }, { "backup", 0, gpart_backup, G_NULL_OPTS, "geom" @@ -168,11 +170,12 @@ struct g_command PUBSYM(class_commands)[] = { "-a attrib -i index [-f flags] geom" }, { "resize", 0, gpart_issue, { + { 'a', "alignment", GPART_AUTOFILL, G_TYPE_STRING }, { 's', "size", GPART_AUTOFILL, G_TYPE_STRING }, { 'i', GPART_PARAM_INDEX, NULL, G_TYPE_NUMBER }, { 'f', "flags", GPART_FLAGS, G_TYPE_STRING }, G_OPT_SENTINEL }, - "[-s size] -i index [-f flags] geom" + "[-a alignment] [-s size] -i index [-f flags] geom" }, { "restore", 0, gpart_restore, { { 'F', "force", NULL, G_TYPE_BOOL }, @@ -298,6 +301,9 @@ fmtattrib(struct gprovider *pp) return (buf); } +#define ALIGNDOWN(d, a) (-(a) & (d)) +#define ALIGNUP(d, a) (-(-(a) & -(d))) + static int gpart_autofill_resize(struct gctl_req *req) { @@ -306,7 +312,7 @@ gpart_autofill_resize(struct gctl_req *req) struct ggeom *gp; struct gprovider *pp; off_t last, size, start, new_size; - off_t lba, new_lba; + off_t lba, new_lba, alignment; const char *s; int error, idx; @@ -333,6 +339,19 @@ gpart_autofill_resize(struct gctl_req *req) if (pp == NULL) errx(EXIT_FAILURE, "Provider for geom %s not found.", s); + s = gctl_get_ascii(req, "alignment"); + alignment = 1; + if (*s != '*') { + error = g_parse_lba(s, pp->lg_sectorsize, &alignment); + if (error) + errc(EXIT_FAILURE, error, "Invalid alignment param"); + if (alignment == 0) + errx(EXIT_FAILURE, "Invalid alignment param"); + } + error = gctl_delete_param(req, "alignment"); + if (error) + errc(EXIT_FAILURE, error, "internal error"); + s = gctl_get_ascii(req, "size"); if (*s == '*') new_size = 0; @@ -341,10 +360,14 @@ gpart_autofill_resize(struct gctl_req *req) if (error) errc(EXIT_FAILURE, error, "Invalid size param"); /* no autofill necessary. */ - goto done; + if (alignment == 1) + goto done; + if (new_size > alignment) + new_size = ALIGNDOWN(new_size, alignment); } last = (off_t)strtoimax(find_geomcfg(gp, "last"), NULL, 0); + last = ALIGNDOWN(last, alignment); LIST_FOREACH(pp, &gp->lg_provider, lg_provider) { s = find_provcfg(pp, "index"); if (s == NULL) @@ -376,7 +399,7 @@ gpart_autofill_resize(struct gctl_req *req) size = lba - start; pp = find_provider(gp, lba); if (pp == NULL) - new_size = last - start + 1; + new_size = ALIGNDOWN(last - start + 1, alignment); else { s = find_provcfg(pp, "start"); if (s == NULL) { @@ -389,6 +412,7 @@ gpart_autofill_resize(struct gctl_req *req) * Is there any free space between current and * next providers? */ + new_lba = ALIGNUP(new_lba, alignment); if (new_lba > lba) new_size = new_lba - start; else { @@ -410,12 +434,12 @@ gpart_autofill(struct gctl_req *req) struct gclass *cp; struct ggeom *gp; struct gprovider *pp; - off_t first, last; - off_t size, start; - off_t lba, len; + off_t first, last, a_first; + off_t size, start, a_lba; + off_t lba, len, alignment; uintmax_t grade; const char *s; - int error, has_size, has_start; + int error, has_size, has_start, has_alignment; s = gctl_get_ascii(req, "verb"); if (strcmp(s, "resize") == 0) @@ -442,6 +466,20 @@ gpart_autofill(struct gctl_req *req) if (pp == NULL) errx(EXIT_FAILURE, "Provider for geom %s not found.", s); + s = gctl_get_ascii(req, "alignment"); + has_alignment = (*s == '*') ? 0 : 1; + alignment = 1; + if (has_alignment) { + error = g_parse_lba(s, pp->lg_sectorsize, &alignment); + if (error) + errc(EXIT_FAILURE, error, "Invalid alignment param"); + if (alignment == 0) + errx(EXIT_FAILURE, "Invalid alignment param"); + } + error = gctl_delete_param(req, "alignment"); + if (error) + errc(EXIT_FAILURE, error, "internal error"); + s = gctl_get_ascii(req, "size"); has_size = (*s == '*') ? 0 : 1; size = 0; @@ -449,6 +487,8 @@ gpart_autofill(struct gctl_req *req) error = g_parse_lba(s, pp->lg_sectorsize, &size); if (error) errc(EXIT_FAILURE, error, "Invalid size param"); + if (size > alignment) + size = ALIGNDOWN(size, alignment); } s = gctl_get_ascii(req, "start"); @@ -458,15 +498,18 @@ gpart_autofill(struct gctl_req *req) error = g_parse_lba(s, pp->lg_sectorsize, &start); if (error) errc(EXIT_FAILURE, error, "Invalid start param"); + start = ALIGNUP(start, alignment); } /* No autofill necessary. */ - if (has_size && has_start) + if (has_size && has_start && !has_alignment) goto done; first = (off_t)strtoimax(find_geomcfg(gp, "first"), NULL, 0); last = (off_t)strtoimax(find_geomcfg(gp, "last"), NULL, 0); grade = ~0ULL; + a_first = ALIGNUP(first, alignment); + last = ALIGNDOWN(last, alignment); while ((pp = find_provider(gp, first)) != NULL) { s = find_provcfg(pp, "start"); if (s == NULL) { @@ -475,23 +518,24 @@ gpart_autofill(struct gctl_req *req) } else lba = (off_t)strtoimax(s, NULL, 0); - if (first < lba) { + a_lba = ALIGNDOWN(lba, alignment); + if (first < a_lba && a_first < a_lba) { /* Free space [first, lba> */ - len = lba - first; + len = a_lba - a_first; if (has_size) { if (len >= size && (uintmax_t)(len - size) < grade) { - start = first; + start = a_first; grade = len - size; } } else if (has_start) { - if (start >= first && start < lba) { - size = lba - start; - grade = start - first; + if (start >= a_first && start < a_lba) { + size = a_lba - start; + grade = start - a_first; } } else { if (grade == ~0ULL || len > size) { - start = first; + start = a_first; size = len; grade = 0; } @@ -505,24 +549,25 @@ gpart_autofill(struct gctl_req *req) (off_t)strtoimax(s, NULL, 0) / pp->lg_sectorsize; } else first = (off_t)strtoimax(s, NULL, 0) + 1; + a_first = ALIGNUP(first, alignment); } - if (first <= last) { + if (a_first <= last) { /* Free space [first-last] */ - len = last - first + 1; + len = ALIGNDOWN(last - a_first + 1, alignment); if (has_size) { if (len >= size && (uintmax_t)(len - size) < grade) { - start = first; + start = a_first; grade = len - size; } } else if (has_start) { - if (start >= first && start <= last) { - size = last - start + 1; - grade = start - first; + if (start >= a_first && start <= last) { + size = ALIGNDOWN(last - start + 1, alignment); + grade = start - a_first; } } else { if (grade == ~0ULL || len > size) { - start = first; + start = a_first; size = len; grade = 0; } diff --git a/sbin/geom/class/part/gpart.8 b/sbin/geom/class/part/gpart.8 index 51b1af5cba51..436a1a041712 100644 --- a/sbin/geom/class/part/gpart.8 +++ b/sbin/geom/class/part/gpart.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 12, 2011 +.Dd May 03, 2011 .Dt GPART 8 .Os .Sh NAME @@ -91,6 +91,7 @@ utility: .Nm .Cm add .Fl t Ar type +.Op Fl a Ar alignment .Op Fl b Ar start .Op Fl s Ar size .Op Fl i Ar index @@ -148,6 +149,7 @@ utility: .Nm .Cm resize .Fl i Ar index +.Op Fl a Ar alignment .Op Fl s Ar size .Op Fl f Ar flags .Ar geom @@ -209,7 +211,17 @@ Partition types are discussed below in the section entitled .Sx "PARTITION TYPES" . .Pp Additional options include: -.Bl -tag -width 10n +.Bl -tag -width 12n +.It Fl a Ar alignment +If specified, then +.Nm +utility tries to align +.Ar start +offset and partition +.Ar size +to be multiple of +.Ar alignment +value. .It Fl i Ar index The index in the partition table at which the new partition is to be placed. @@ -416,7 +428,15 @@ to maximum available from given geom .Ar geom . .Pp Additional options include: -.Bl -tag -width 10n +.Bl -tag -width 12n +.It Fl a Ar alignment +If specified, then +.Nm +utility tries to align partition +.Ar size +to be multiple of +.Ar alignment +value. .It Fl f Ar flags Additional operational flags. See the section entitled @@ -834,6 +854,13 @@ partition that would contain UFS where the system boots from. /sbin/gpart add -s 512M -t freebsd-ufs da0 .Ed .Pp +Create a 15GB-sized +.Cm freebsd-ufs +partition that would contain UFS and aligned on 4KB boundaries: +.Bd -literal -offset indent +/sbin/gpart add -s 15G -t freebsd-ufs -a 4k da0 +.Ed +.Pp After having created all required partitions, embed bootstrap code into them. .Bd -literal -offset indent /sbin/gpart bootcode -p /boot/boot1 da0 From a259aceffff4ecc5c5175bd495772280a52410bc Mon Sep 17 00:00:00 2001 From: Craig Rodrigues Date: Tue, 3 May 2011 07:39:54 +0000 Subject: [PATCH 07/25] Add #include for missing forward declation of struct inpcb. --- lib/libstand/net.c | 1 + lib/libstand/udp.c | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/libstand/net.c b/lib/libstand/net.c index d417bfb08486..81b4521c4c02 100644 --- a/lib/libstand/net.c +++ b/lib/libstand/net.c @@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include diff --git a/lib/libstand/udp.c b/lib/libstand/udp.c index 194f564531a8..d41be902a3f7 100644 --- a/lib/libstand/udp.c +++ b/lib/libstand/udp.c @@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include From 3eb882f0318a76977b1d77d5e25cac646dca7c71 Mon Sep 17 00:00:00 2001 From: Craig Rodrigues Date: Tue, 3 May 2011 07:43:47 +0000 Subject: [PATCH 08/25] - Comment out unused variable. - Add parentheses around expression to eliminate compiler warning. --- lib/libstand/dosfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/libstand/dosfs.c b/lib/libstand/dosfs.c index 5ba10c11adf2..e15ecdcf6fb3 100644 --- a/lib/libstand/dosfs.c +++ b/lib/libstand/dosfs.c @@ -358,7 +358,7 @@ dos_stat(struct open_file *fd, struct stat *sb) static int dos_readdir(struct open_file *fd, struct dirent *d) { - DOS_FILE *f = (DOS_FILE *)fd->f_fsdata; + /* DOS_FILE *f = (DOS_FILE *)fd->f_fsdata; */ u_char fn[261]; DOS_DIR dd; size_t res; @@ -414,7 +414,7 @@ dos_readdir(struct open_file *fd, struct dirent *d) } } - d->d_fileno = dd.de.clus[1] << 8 + dd.de.clus[0]; + d->d_fileno = (dd.de.clus[1] << 8) + dd.de.clus[0]; d->d_reclen = sizeof(*d); d->d_type = (dd.de.attr & FA_DIR) ? DT_DIR : DT_REG; memcpy(d->d_name, fn, sizeof(d->d_name)); From 51f95b0a42a137aa19453d6778424672402b08a2 Mon Sep 17 00:00:00 2001 From: Craig Rodrigues Date: Tue, 3 May 2011 07:46:02 +0000 Subject: [PATCH 09/25] Rename DEBUG macro to TFTP_DEBUG, to be more consistent with debug macros in other files. --- lib/libstand/tftp.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/libstand/tftp.c b/lib/libstand/tftp.c index 4a2ca69dda7a..29590fcd7461 100644 --- a/lib/libstand/tftp.c +++ b/lib/libstand/tftp.c @@ -148,14 +148,14 @@ recvtftp(struct iodesc *d, void *pkt, ssize_t len, time_t tleft) printf("illegal tftp error %d\n", ntohs(t->th_code)); errno = EIO; } else { -#ifdef DEBUG +#ifdef TFTP_DEBUG printf("tftp-error %d\n", ntohs(t->th_code)); #endif errno = tftperrors[ntohs(t->th_code)]; } return (-1); default: -#ifdef DEBUG +#ifdef TFTP_DEBUG printf("tftp type %d not handled\n", ntohs(t->th_opcode)); #endif return (-1); @@ -303,7 +303,7 @@ tftp_read(struct open_file *f, void *addr, size_t size, res = tftp_getnextblock(tftpfile); if (res) { /* no answer */ -#ifdef DEBUG +#ifdef TFTP_DEBUG printf("tftp: read error\n"); #endif return (res); @@ -319,7 +319,7 @@ tftp_read(struct open_file *f, void *addr, size_t size, inbuffer = tftpfile->validsize - offinblock; if (inbuffer < 0) { -#ifdef DEBUG +#ifdef TFTP_DEBUG printf("tftp: invalid offset %d\n", tftpfile->off); #endif @@ -336,7 +336,7 @@ tftp_read(struct open_file *f, void *addr, size_t size, if ((tftpfile->islastblock) && (count == inbuffer)) break; /* EOF */ } else { -#ifdef DEBUG +#ifdef TFTP_DEBUG printf("tftp: block %d not found\n", needblock); #endif return (EINVAL); From a35a58824b103f71cd34d498cbe34bf9d01da333 Mon Sep 17 00:00:00 2001 From: Ruslan Ermilov Date: Tue, 3 May 2011 10:08:11 +0000 Subject: [PATCH 10/25] Don't call -f option's argument "stdin". MFC after: 3 days --- bin/stty/stty.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bin/stty/stty.c b/bin/stty/stty.c index f6daaf076ad8..b70f49fcad98 100644 --- a/bin/stty/stty.c +++ b/bin/stty/stty.c @@ -61,9 +61,11 @@ main(int argc, char *argv[]) struct info i; enum FMT fmt; int ch; + const char *file; fmt = NOTSET; i.fd = STDIN_FILENO; + file = "stdin"; opterr = 0; while (optind < argc && @@ -79,6 +81,7 @@ main(int argc, char *argv[]) case 'f': if ((i.fd = open(optarg, O_RDONLY | O_NONBLOCK)) < 0) err(1, "%s", optarg); + file = optarg; break; case 'g': fmt = GFLAG; @@ -92,7 +95,7 @@ args: argc -= optind; argv += optind; if (tcgetattr(i.fd, &i.t) < 0) - errx(1, "stdin isn't a terminal"); + errx(1, "%s isn't a terminal", file); if (ioctl(i.fd, TIOCGETD, &i.ldisc) < 0) err(1, "TIOCGETD"); if (ioctl(i.fd, TIOCGWINSZ, &i.win) < 0) From 87a5818245a2c83f385075aef0e9d01e0ae840fa Mon Sep 17 00:00:00 2001 From: Ruslan Ermilov Date: Tue, 3 May 2011 10:11:44 +0000 Subject: [PATCH 11/25] Properly detect interface's state in the LINK_STATE_UNKNOWN case. MFC after: 1 week --- contrib/bsnmp/snmp_mibII/mibII_interfaces.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/contrib/bsnmp/snmp_mibII/mibII_interfaces.c b/contrib/bsnmp/snmp_mibII/mibII_interfaces.c index a1817d39f92f..f425a2703f29 100644 --- a/contrib/bsnmp/snmp_mibII/mibII_interfaces.c +++ b/contrib/bsnmp/snmp_mibII/mibII_interfaces.c @@ -289,8 +289,7 @@ op_ifentry(struct snmp_context *ctx, struct snmp_value *value, * cable) and hence return 'dormant'. */ if (ifp->mib.ifmd_flags & IFF_RUNNING) { - if (ifp->mib.ifmd_data.ifi_link_state == - LINK_STATE_DOWN) + if (ifp->mib.ifmd_data.ifi_link_state != LINK_STATE_UP) value->v.integer = 5; /* state dormant */ else value->v.integer = 1; /* state up */ From ba675b41768e223926bd234d015901092b93bc8c Mon Sep 17 00:00:00 2001 From: Doug Rabson Date: Tue, 3 May 2011 10:18:27 +0000 Subject: [PATCH 12/25] Call pam_setcred() before login_getpwclass to support home directories on GSS-API authenticated NFS where the kerberos credentials need to be saved so that the kernel can authenticate to the NFS server. --- usr.bin/login/login.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/usr.bin/login/login.c b/usr.bin/login/login.c index e671c8dfac75..1de440bfc449 100644 --- a/usr.bin/login/login.c +++ b/usr.bin/login/login.c @@ -380,6 +380,19 @@ main(int argc, char *argv[]) au_login_success(); #endif + /* + * This needs to happen before login_getpwclass to support + * home directories on GSS-API authenticated NFS where the + * kerberos credentials need to be saved so that the kernel + * can authenticate to the NFS server. + */ + pam_err = pam_setcred(pamh, pam_silent|PAM_ESTABLISH_CRED); + if (pam_err != PAM_SUCCESS) { + pam_syslog("pam_setcred()"); + bail(NO_SLEEP_EXIT, 1); + } + pam_cred_established = 1; + /* * Establish the login class. */ @@ -513,12 +526,11 @@ main(int argc, char *argv[]) bail(NO_SLEEP_EXIT, 1); } - pam_err = pam_setcred(pamh, pam_silent|PAM_ESTABLISH_CRED); + pam_err = pam_setcred(pamh, pam_silent|PAM_REINITIALIZE_CRED); if (pam_err != PAM_SUCCESS) { pam_syslog("pam_setcred()"); bail(NO_SLEEP_EXIT, 1); } - pam_cred_established = 1; pam_err = pam_open_session(pamh, pam_silent); if (pam_err != PAM_SUCCESS) { From bd726c262eacb8675c29121f040452106671e929 Mon Sep 17 00:00:00 2001 From: Ruslan Ermilov Date: Tue, 3 May 2011 11:37:03 +0000 Subject: [PATCH 13/25] Vendor import of bwk's 1-May-2011 release. --- FIXES | 26 ++++++++++++++++++++++++++ README | 2 +- b.c | 4 ++-- lib.c | 3 ++- main.c | 9 ++++++++- makefile | 13 ++++++------- run.c | 12 +++++++++--- 7 files changed, 54 insertions(+), 15 deletions(-) diff --git a/FIXES b/FIXES index bda79768606a..36ef237ed91c 100644 --- a/FIXES +++ b/FIXES @@ -25,6 +25,32 @@ THIS SOFTWARE. This file lists all bug fixes, changes, etc., made since the AWK book was sent to the printers in August, 1987. +May 1, 2011: + after advice from todd miller, kevin lo, ruslan ermilov, + and arnold robbins, changed srand() to return the previous + seed (which is 1 on the first call of srand). the seed is + an Awkfloat internally though converted to unsigned int to + pass to the library srand(). thanks, everyone. + + fixed a subtle (and i hope low-probability) overflow error + in fldbld, by adding space for one extra \0. thanks to + robert bassett for spotting this one and providing a fix. + + removed the files related to compilation on windows. i no + longer have anything like a current windows environment, so + i can't test any of it. + +May 23, 2010: + fixed long-standing overflow bug in run.c; many thanks to + nelson beebe for spotting it and providing the fix. + + fixed bug that didn't parse -vd=1 properly; thanks to santiago + vila for spotting it. + +Feb 8, 2010: + i give up. replaced isblank with isspace in b.c; there are + no consistent header files. + Nov 26, 2009: fixed a long-standing issue with when FS takes effect. a change to FS is now noticed immediately for subsequent splits. diff --git a/README b/README index 21255a1ca020..24aaf9092d58 100644 --- a/README +++ b/README @@ -29,7 +29,7 @@ by Al Aho, Brian Kernighan, and Peter Weinberger Changes, mostly bug fixes and occasional enhancements, are listed in FIXES. If you distribute this code further, please please please distribute FIXES with it. If you find errors, please report them -to bwk@bell-labs.com. Thanks. +to bwk@cs.princeton.edu. Thanks. The program itself is created by make diff --git a/b.c b/b.c index 4c6d61be9082..a4a46acbf91a 100644 --- a/b.c +++ b/b.c @@ -734,7 +734,7 @@ Node *unary(Node *np) /* #define HAS_ISBLANK */ #ifndef HAS_ISBLANK -int (isblank)(int c) +int (xisblank)(int c) { return c==' ' || c=='\t'; } @@ -748,7 +748,7 @@ struct charclass { } charclasses[] = { { "alnum", 5, isalnum }, { "alpha", 5, isalpha }, - { "blank", 5, isblank }, + { "blank", 5, isspace }, /* was isblank */ { "cntrl", 5, iscntrl }, { "digit", 5, isdigit }, { "graph", 5, isgraph }, diff --git a/lib.c b/lib.c index 017b37670d07..d7eee31db43f 100644 --- a/lib.c +++ b/lib.c @@ -256,6 +256,7 @@ void fldbld(void) /* create fields from current record */ { /* this relies on having fields[] the same length as $0 */ /* the fields are all stored in this one array with \0's */ + /* possibly with a final trailing \0 not associated with any field */ char *r, *fr, sep; Cell *p; int i, j, n; @@ -268,7 +269,7 @@ void fldbld(void) /* create fields from current record */ n = strlen(r); if (n > fieldssize) { xfree(fields); - if ((fields = (char *) malloc(n+1)) == NULL) + if ((fields = (char *) malloc(n+2)) == NULL) /* possibly 2 final \0s */ FATAL("out of space for fields in fldbld %d", n); fieldssize = n; } diff --git a/main.c b/main.c index 3bc25a579fec..a125bc1eb1fb 100644 --- a/main.c +++ b/main.c @@ -22,7 +22,7 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ****************************************************************/ -const char *version = "version 20091126"; +const char *version = "version 20110501"; #define DEBUG #include @@ -38,6 +38,7 @@ extern char **environ; extern int nfields; int dbg = 0; +Awkfloat srand_seed = 1; char *cmdname; /* gets argv[0] for error messages */ extern FILE *yyin; /* lex input file */ char *lexprog; /* points to program argument if it exists */ @@ -67,6 +68,10 @@ int main(int argc, char *argv[]) exit(1); } signal(SIGFPE, fpecatch); + + srand_seed = 1; + srand(srand_seed); + yyin = NULL; symtab = makesymtab(NSYMTAB/NSYMTAB); while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') { @@ -113,6 +118,8 @@ int main(int argc, char *argv[]) case 'v': /* -v a=1 to be done NOW. one -v for each */ if (argv[1][2] == '\0' && --argc > 1 && isclvar((++argv)[1])) setclvar(argv[1]); + else if (argv[1][2] != '\0') + setclvar(&argv[1][2]); break; case 'd': dbg = atoi(&argv[1][2]); diff --git a/makefile b/makefile index 9d3985be2d4c..f93f0a8bdb87 100644 --- a/makefile +++ b/makefile @@ -26,13 +26,12 @@ CFLAGS = -g CFLAGS = -O2 CFLAGS = -CC = gcc -Wall -g -Wwrite-strings -CC = gcc -fprofile-arcs -ftest-coverage # then gcov f1.c; cat f1.c.gcov CC = gcc -Wall -g CC = cc +CC = gcc -Wall -g -Wwrite-strings +CC = gcc -fprofile-arcs -ftest-coverage # then gcov f1.c; cat f1.c.gcov CC = gcc -O4 - YACC = bison -y YACC = yacc YFLAGS = -d @@ -40,13 +39,13 @@ YFLAGS = -d OFILES = b.o main.o parse.o proctab.o tran.o lib.o run.o lex.o SOURCE = awk.h ytab.c ytab.h proto.h awkgram.y lex.c b.c main.c \ - maketab.c parse.c lib.c run.c tran.c proctab.c missing95.c + maketab.c parse.c lib.c run.c tran.c proctab.c LISTING = awk.h proto.h awkgram.y lex.c b.c main.c maketab.c parse.c \ - lib.c run.c tran.c missing95.c + lib.c run.c tran.c -SHIP = README FIXES $(SOURCE) ytab[ch].bak makefile makefile.win \ - vcvars32.bat buildwin.bat awk.1 +SHIP = README FIXES $(SOURCE) ytab[ch].bak makefile \ + awk.1 a.out: ytab.o $(OFILES) $(CC) $(CFLAGS) ytab.o $(OFILES) $(ALLOC) -lm diff --git a/run.c b/run.c index 72fc4d0f4172..e96379bbd265 100644 --- a/run.c +++ b/run.c @@ -66,6 +66,7 @@ void tempfree(Cell *p) { jmp_buf env; extern int pairstack[]; +extern Awkfloat srand_seed; Node *winner = NULL; /* root of parse tree */ Cell *tmps; /* free temporary cells for execution */ @@ -1466,6 +1467,7 @@ Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg lis Cell *x, *y; Awkfloat u; int t; + Awkfloat tmp; char *p, *buf; Node *nextarg; FILE *fp; @@ -1517,7 +1519,10 @@ Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg lis u = time((time_t *)0); else u = getfval(x); + tmp = u; srand((unsigned int) u); + u = srand_seed; + srand_seed = tmp; break; case FTOUPPER: case FTOLOWER: @@ -1887,9 +1892,10 @@ Cell *gsub(Node **a, int nnn) /* global substitute */ adjbuf(&buf, &bufsz, 1+strlen(sptr)+pb-buf, 0, &pb, "gsub"); while ((*pb++ = *sptr++) != 0) ; - done: if (pb > buf + bufsz) - FATAL("gsub result2 %.30s too big; can't happen", buf); - *pb = '\0'; + done: if (pb < buf + bufsz) + *pb = '\0'; + else if (*(pb-1) != '\0') + FATAL("gsub result2 %.30s truncated; can't happen", buf); setsval(x, buf); /* BUG: should be able to avoid copy + free */ pfa->initstat = tempstat; } From a4638c5ce5c3556e646e844cc1acef54dcc3f5b9 Mon Sep 17 00:00:00 2001 From: Ruslan Ermilov Date: Tue, 3 May 2011 12:22:46 +0000 Subject: [PATCH 14/25] Updated `flags' field description. --- etc/newsyslog.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/newsyslog.conf b/etc/newsyslog.conf index 79ad03739ccb..67aa11726d6a 100644 --- a/etc/newsyslog.conf +++ b/etc/newsyslog.conf @@ -8,7 +8,7 @@ # is no process which needs to be signalled when a given log file is # rotated, then the entry for that file should include the 'N' flag. # -# The 'flags' field is one or more of the letters: BCGJNUWZ or a '-'. +# The 'flags' field is one or more of the letters: BCDGJNUXZ or a '-'. # # Note: some sites will want to select more restrictive protections than the # defaults. In particular, it may be desirable to switch many of the 644 From 41af50287c42323e14a0275196fdac8b7a58c052 Mon Sep 17 00:00:00 2001 From: Ruslan Ermilov Date: Tue, 3 May 2011 12:29:03 +0000 Subject: [PATCH 15/25] Fixed bad format and misorder. --- usr.bin/calendar/calendars/calendar.freebsd | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/usr.bin/calendar/calendars/calendar.freebsd b/usr.bin/calendar/calendars/calendar.freebsd index 65ec5fdcf630..83f3151609b0 100644 --- a/usr.bin/calendar/calendars/calendar.freebsd +++ b/usr.bin/calendar/calendars/calendar.freebsd @@ -45,8 +45,8 @@ 02/01 Juli Mallett born in Washington, Pennsylvania, United States, 1985 02/02 Diomidis D. Spinellis born in Athens, Greece, 1967 02/02 Michael W Lucas born in Detroit, Michigan, United States, 1967 -02/02 Yoichi Nakayama born in Tsu, Mie, Japan, 1976 02/02 Dmitry Chagin born in Stalingrad, USSR, 1976 +02/02 Yoichi Nakayama born in Tsu, Mie, Japan, 1976 02/05 Frank Laszlo born in Howell, Michigan, United States, 1983 02/10 David Greenman born in Portland, Oregon, United States, 1968 02/10 Paul Richards born in Ammanford, Carmarthenshire, United Kingdom, 1968 @@ -68,7 +68,6 @@ 02/24 Johan Karlsson born in Mariannelund, Sweden, 1974 02/24 Colin Percival born in Burnaby, Canada, 1981 02/26 Pietro Cerutti born in Faido, Switzerland, 1984 -05/19 Sofian Brabez born in Toulouse, France, 1984 02/28 Daichi GOTO born in Shimizu Suntou, Shizuoka, Japan, 1980 03/01 Hye-Shik Chang born in Daejeon, Republic of Korea, 1980 03/02 Cy Schubert born in Edmonton, Alberta, Canada, 1956 @@ -151,7 +150,8 @@ 05/17 Thomas Abthorpe born in Port Arthur, Ontario, Canada, 1968 05/19 Philippe Charnier born in Fontainebleau, France, 1966 05/19 Ian Dowse born in Dublin, Ireland, 1975 -05/20 Dan Moschuk died in Burlington, Ontario, Canada, 2010 +05/19 Sofian Brabez born in Toulouse, France, 1984 +05/20 Dan Moschuk died in Burlington, Ontario, Canada, 2010 05/21 Kris Kennaway born in Winnipeg, Manitoba, Canada, 1978 05/22 Clive Tong-I Lin born in Changhua, Taiwan, Republic of China, 1978 05/22 Michael Bushkov born in Rostov-on-Don, Russian Federation, 1985 @@ -175,7 +175,7 @@ 06/04 Justin Gibbs born in San Pedro, California, United States, 1973 06/04 Jason Evans born in Greeley, Colorado, United States, 1973 06/04 Thomas Moestl born in Braunschweig, Niedersachsen, Germany, 1980 -06/04 Zack Kirsch born in Memphis, Tennessee, United States, 1982 +06/04 Zack Kirsch born in Memphis, Tennessee, United States, 1982 06/06 Sergei Kolobov born in Karpinsk, Russian Federation, 1972 06/06 Alan Eldridge died in Denver, Colorado, 2003 06/07 Jimmy Olgeni born in Milano, Italy, 1976 From ce6cf987d81cdfa58b1651e36ff23872d0e8e00c Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Tue, 3 May 2011 13:16:02 +0000 Subject: [PATCH 16/25] Do not report legacy unit numbers (do not create legacy aliases) for disks on port multiplier ports above first two. They don't fit into ATA_STATIC_ID scheme and so can't be mapped properly. No need to pollute dev. --- sys/cam/cam_xpt.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c index cf7394834f08..1ce205d2a64f 100644 --- a/sys/cam/cam_xpt.c +++ b/sys/cam/cam_xpt.c @@ -3600,9 +3600,12 @@ xpt_path_legacy_ata_id(struct cam_path *path) } xpt_unlock_buses(); } - if (path->target != NULL) - return (bus_id * 2 + path->target->target_id); - else + if (path->target != NULL) { + if (path->target->target_id < 2) + return (bus_id * 2 + path->target->target_id); + else + return (-1); + } else return (bus_id * 2); } From 827a0e05b7f8a7779884443db7b5dde0e64b9a03 Mon Sep 17 00:00:00 2001 From: Ruslan Ermilov Date: Tue, 3 May 2011 13:34:40 +0000 Subject: [PATCH 17/25] Fixed the HISTORY section which was copied without editing from aio(4). Submitted by: Igor Sysoev --- share/man/man4/sem.4 | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/share/man/man4/sem.4 b/share/man/man4/sem.4 index 4a641dc646f3..3cc3a499a71f 100644 --- a/share/man/man4/sem.4 +++ b/share/man/man4/sem.4 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 11, 2006 +.Dd May 3, 2011 .Dt SEM 4 .Os .Sh NAME @@ -73,9 +73,5 @@ dynamic kernel module. .Sh HISTORY The .Nm -facility appeared as a kernel option in -.Fx 3.0 . -The -.Nm -kernel module appeared in +facility appeared in .Fx 5.0 . From 20ff6c114f4431e32ec0ff53ba81e420bd4e86a5 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Tue, 3 May 2011 14:43:16 +0000 Subject: [PATCH 18/25] Fix stack smash problem in makeinfo, by increasing buffer sizes in current_chapter_number(). --- contrib/texinfo/makeinfo/sectioning.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/texinfo/makeinfo/sectioning.c b/contrib/texinfo/makeinfo/sectioning.c index ce32aeb3a7e5..1683d11b6e39 100644 --- a/contrib/texinfo/makeinfo/sectioning.c +++ b/contrib/texinfo/makeinfo/sectioning.c @@ -256,13 +256,13 @@ current_chapter_number (void) return xstrdup (""); else if (enum_marker == APPENDIX_MAGIC) { - char s[1]; + char s[2]; sprintf (s, "%c", numbers[0] + 64); return xstrdup (s); } else { - char s[5]; + char s[11]; sprintf (s, "%d", numbers[0]); return xstrdup (s); } From b3fa6d2cf1eea1b02acc2bee3b61d71fb9afe5ec Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Tue, 3 May 2011 15:12:01 +0000 Subject: [PATCH 19/25] Add support for synthesizing an APM partition map to map Mac PowerPC bootstrap partitions from the ISO9660 boot catalog. This preserves OS X's ability to mount the CD, while allowing us a way to provide HFS-ified bootstrap code for Open Firmware. --- usr.sbin/makefs/cd9660/cd9660_eltorito.c | 79 ++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/usr.sbin/makefs/cd9660/cd9660_eltorito.c b/usr.sbin/makefs/cd9660/cd9660_eltorito.c index 055451d1800c..f0c8b2d4b18f 100644 --- a/usr.sbin/makefs/cd9660/cd9660_eltorito.c +++ b/usr.sbin/makefs/cd9660/cd9660_eltorito.c @@ -31,6 +31,9 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ + +#include + #include "cd9660.h" #include "cd9660_eltorito.h" @@ -497,11 +500,43 @@ cd9660_setup_boot_volume_descriptor(volume_descriptor *bvd) return 1; } +static int +cd9660_write_apm_partition_entry(FILE *fd, int index, int total_partitions, + off_t sector_start, off_t nsectors, off_t sector_size, + const char *part_name, const char *part_type) { + uint32_t apm32; + uint16_t apm16; + + fseeko(fd, (off_t)(index + 1) * sector_size, SEEK_SET); + + /* Signature */ + apm16 = htons(0x504d); + fwrite(&apm16, sizeof(apm16), 1, fd); + apm16 = 0; + fwrite(&apm16, sizeof(apm16), 1, fd); + + /* Total number of partitions */ + apm32 = htonl(total_partitions); + fwrite(&apm32, sizeof(apm32), 1, fd); + /* Bounds */ + apm32 = htonl(sector_start); + fwrite(&apm32, sizeof(apm32), 1, fd); + apm32 = htonl(nsectors); + fwrite(&apm32, sizeof(apm32), 1, fd); + + fwrite(part_name, strlen(part_name) + 1, 1, fd); + fseek(fd, 32 - strlen(part_name) - 1, SEEK_CUR); + fwrite(part_type, strlen(part_type) + 1, 1, fd); + + return 0; +} + int cd9660_write_boot(FILE *fd) { struct boot_catalog_entry *e; struct cd9660_boot_image *t; + int apm_partitions = 0; /* write boot catalog */ if (fseeko(fd, (off_t)diskStructure.boot_catalog_sector * @@ -533,7 +568,51 @@ cd9660_write_boot(FILE *fd) t->filename, t->sector); } cd9660_copy_file(fd, t->sector, t->filename); + + if (t->system == ET_SYS_MAC) + apm_partitions++; + } + + if (apm_partitions > 0) { + /* Write DDR and global APM info */ + uint32_t apm32; + uint16_t apm16; + int total_parts; + + fseek(fd, 0, SEEK_SET); + apm16 = htons(0x4552); + fwrite(&apm16, sizeof(apm16), 1, fd); + apm16 = htons(diskStructure.sectorSize); + fwrite(&apm16, sizeof(apm16), 1, fd); + apm32 = htonl(diskStructure.totalSectors); + fwrite(&apm32, sizeof(apm32), 1, fd); + + /* Count total needed entries */ + total_parts = 2 + apm_partitions; /* Self + ISO9660 */ + + /* Write self-descriptor */ + cd9660_write_apm_partition_entry(fd, 0, + total_parts, 1, total_parts, diskStructure.sectorSize, + "Apple", "Apple_partition_map"); + + /* Write ISO9660 descriptor, enclosing the whole disk */ + cd9660_write_apm_partition_entry(fd, 1, + total_parts, 0, diskStructure.totalSectors, + diskStructure.sectorSize, "", "CD_ROM_Mode_1"); + + /* Write all partition entries */ + apm_partitions = 0; + TAILQ_FOREACH(t, &diskStructure.boot_images, image_list) { + if (t->system != ET_SYS_MAC) + continue; + + cd9660_write_apm_partition_entry(fd, + 2 + apm_partitions++, total_parts, + t->sector, t->num_sectors, diskStructure.sectorSize, + "CD Boot", "Apple_Bootstrap"); + } } return 0; } + From e3888a982033e5db7f2843654f81bee47641c26e Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Tue, 3 May 2011 15:50:22 +0000 Subject: [PATCH 20/25] SNDCTL_DSP_GETIPTR: set pointer to sndbuf_getfreeptr() Rationale: - unlike current behavior this seems to be compliant with OSS specification: http://manuals.opensound.com/developer/SNDCTL_DSP_GETIPTR.html - this seems to meet expectations of some OSS programs compiled for or ported from Linux, e.g. ALSA OSS plugin - this doesn't seem to break any programs as far as current testing shows Tested by: nox, hselasky MFC after: 4 days --- sys/dev/sound/pcm/dsp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c index 19801b2e694c..66d0c8c13ef4 100644 --- a/sys/dev/sound/pcm/dsp.c +++ b/sys/dev/sound/pcm/dsp.c @@ -1655,7 +1655,7 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, /* XXX abusive DMA update: chn_rdupdate(rdch); */ a->bytes = sndbuf_gettotal(bs); a->blocks = sndbuf_getblocks(bs) - rdch->blocks; - a->ptr = sndbuf_getreadyptr(bs); + a->ptr = sndbuf_getfreeptr(bs); rdch->blocks = sndbuf_getblocks(bs); CHN_UNLOCK(rdch); } else From 040b46f5ba1fb23f633535985be51c39ac0c876e Mon Sep 17 00:00:00 2001 From: "George V. Neville-Neil" Date: Tue, 3 May 2011 15:58:24 +0000 Subject: [PATCH 21/25] Add in support for multicast. Submitted by: Sriram Rapuru at @ Wipro for Exar Inc. MFC after: 2 weeks --- sys/dev/vxge/include/build-version.h | 2 +- sys/dev/vxge/vxge.c | 23 +++-------------------- sys/dev/vxge/vxge.h | 1 - 3 files changed, 4 insertions(+), 22 deletions(-) diff --git a/sys/dev/vxge/include/build-version.h b/sys/dev/vxge/include/build-version.h index 9eca7b2a673f..5bc550ada8b3 100644 --- a/sys/dev/vxge/include/build-version.h +++ b/sys/dev/vxge/include/build-version.h @@ -3,5 +3,5 @@ #ifndef BUILD_VERSION_H #define BUILD_VERSION_H /* Do not edit! Automatically generated when released. */ -#define GENERATED_BUILD_VERSION 22708 +#define GENERATED_BUILD_VERSION 22770 #endif /* BUILD_VERSION_H */ diff --git a/sys/dev/vxge/vxge.c b/sys/dev/vxge/vxge.c index 05bbbb855a63..94ca609cb69b 100644 --- a/sys/dev/vxge/vxge.c +++ b/sys/dev/vxge/vxge.c @@ -357,6 +357,9 @@ vxge_init_locked(vxge_dev_t *vdev) if (!vpath_handle) continue; + /* Enabling mcast for all vpath */ + vxge_hal_vpath_mcast_enable(vpath_handle); + /* Enabling bcast for all vpath */ status = vxge_hal_vpath_bcast_enable(vpath_handle); if (status != VXGE_HAL_OK) @@ -2879,26 +2882,6 @@ vxge_promisc_set(vxge_dev_t *vdev) ifp = vdev->ifp; - if ((ifp->if_flags & IFF_ALLMULTI) && (!vdev->all_multi_flag)) { - for (i = 0; i < vdev->no_of_vpath; i++) { - vpath_handle = vxge_vpath_handle_get(vdev, i); - if (!vpath_handle) - continue; - - vxge_hal_vpath_mcast_enable(vpath_handle); - vdev->all_multi_flag = 1; - } - - } else if (!(ifp->if_flags & IFF_ALLMULTI) && (vdev->all_multi_flag)) { - for (i = 0; i < vdev->no_of_vpath; i++) { - vpath_handle = vxge_vpath_handle_get(vdev, i); - if (!vpath_handle) - continue; - - vxge_hal_vpath_mcast_disable(vpath_handle); - vdev->all_multi_flag = 0; - } - } for (i = 0; i < vdev->no_of_vpath; i++) { vpath_handle = vxge_vpath_handle_get(vdev, i); if (!vpath_handle) diff --git a/sys/dev/vxge/vxge.h b/sys/dev/vxge/vxge.h index 630bbefed54d..439c1ced443f 100644 --- a/sys/dev/vxge/vxge.h +++ b/sys/dev/vxge/vxge.h @@ -406,7 +406,6 @@ struct vxge_dev_t { int no_of_vpath; u64 active_port; u32 no_of_func; - u32 all_multi_flag; u32 hw_fw_version; u32 max_supported_vpath; int rx_mbuf_sz; From 26a8da6632833fd7dc6fa6424f5ac29db56edc03 Mon Sep 17 00:00:00 2001 From: Jaakko Heinonen Date: Tue, 3 May 2011 16:00:26 +0000 Subject: [PATCH 22/25] Don't pass empty mount options to nmount(2). Reviewed by: pjd MFC after: 2 weeks --- cddl/compat/opensolaris/misc/zmount.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cddl/compat/opensolaris/misc/zmount.c b/cddl/compat/opensolaris/misc/zmount.c index b4f99e3be9fd..d46b378ea92a 100644 --- a/cddl/compat/opensolaris/misc/zmount.c +++ b/cddl/compat/opensolaris/misc/zmount.c @@ -98,8 +98,10 @@ zmount(const char *spec, const char *dir, int mflag, char *fstype, build_iovec(&iov, &iovlen, "fspath", __DECONST(char *, dir), (size_t)-1); build_iovec(&iov, &iovlen, "from", __DECONST(char *, spec), (size_t)-1); - for (p = optstr; p != NULL; strsep(&p, ",/ ")) - build_iovec(&iov, &iovlen, p, NULL, (size_t)-1); + for (p = optstr; p != NULL; strsep(&p, ",/ ")) { + if (*p != '\0') + build_iovec(&iov, &iovlen, p, NULL, (size_t)-1); + } rv = nmount(iov, iovlen, 0); free(optstr); return (rv); From c3b14674a7530d99e4f6ea30c1033aa2657f4579 Mon Sep 17 00:00:00 2001 From: "George V. Neville-Neil" Date: Tue, 3 May 2011 16:00:36 +0000 Subject: [PATCH 23/25] Give some sort of message when the program is not run as root. Root privileges are required to talk to the device. Submitted by: Sriram Rapuru at Wipro for Exar Inc. MFC after: 2 weeks --- tools/tools/vxge/vxge_info.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tools/tools/vxge/vxge_info.c b/tools/tools/vxge/vxge_info.c index 6a561374c6dc..d213d8727476 100644 --- a/tools/tools/vxge/vxge_info.c +++ b/tools/tools/vxge/vxge_info.c @@ -31,6 +31,7 @@ /*$FreeBSD$*/ #include "vxge_info.h" +#include static int sockfd; static struct ifreq ifr; @@ -38,6 +39,15 @@ static struct ifreq ifr; int main(int argc, char *argv[]) { + uid_t uid; + + uid = getuid(); + + if (uid) { + printf("vxge-manage: Operation not permitted.\nExiting...\n"); + goto _exit0; + } + if (argc >= 4) { if (!((strcasecmp(argv[2], "regs") == 0) || (strcasecmp(argv[2], "stats") == 0) || From 83c41143cae5f3523413e5141dbfdbd8fdadfd5c Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Tue, 3 May 2011 17:37:24 +0000 Subject: [PATCH 24/25] Reimplement how PCI-PCI bridges manage their I/O windows. Previously the driver would verify that requests for child devices were confined to any existing I/O windows, but the driver relied on the firmware to initialize the windows and would never grow the windows for new requests. Now the driver actively manages the I/O windows. This is implemented by allocating a bus resource for each I/O window from the parent PCI bus and suballocating that resource to child devices. The suballocations are managed by creating an rman for each I/O window. The suballocated resources are mapped by passing the bus_activate_resource() call up to the parent PCI bus. Windows are grown when needed by using bus_adjust_resource() to adjust the resource allocated from the parent PCI bus. If the adjust request succeeds, the window is adjusted and the suballocation request for the child device is retried. When growing a window, the rman_first_free_region() and rman_last_free_region() routines are used to determine if the front or end of the existing I/O window is free. From using that, the smallest ranges that need to be added to either the front or back of the window are computed. The driver will first try to grow the window in whichever direction requires the smallest growth first followed by the other direction if that fails. Subtractive bridges will first attempt to satisfy requests for child resources from I/O windows (including attempts to grow the windows). If that fails, the request is passed up to the parent PCI bus directly however. The PCI-PCI bridge driver will try to use firmware-assigned ranges for child BARs first and only allocate a "fresh" range if that specific range cannot be accommodated in the I/O window. This allows systems where the firmware assigns resources during boot but later wipes the I/O windows (some ACPI BIOSen are known to do this) to "rediscover" the original I/O window ranges. The ACPI Host-PCI bridge driver has been adjusted to correctly honor hw.acpi.host_mem_start and the I/O port equivalent when a PCI-PCI bridge makes a wildcard request for an I/O window range. The new PCI-PCI bridge driver is only enabled if the NEW_PCIB kernel option is enabled. This is a transition aide to allow platforms that do not yet support bus_activate_resource() and bus_adjust_resource() in their Host-PCI bridge drivers (and possibly other drivers as needed) to use the old driver for now. Once all platforms support the new driver, the kernel option and old driver will be removed. PR: kern/143874 kern/149306 Tested by: mav --- sys/amd64/pci/pci_bus.c | 1 + sys/conf/options | 1 + sys/dev/acpica/acpi_pcib_acpi.c | 13 +- sys/dev/acpica/acpi_pcib_pci.c | 1 + sys/dev/pci/pci.c | 20 + sys/dev/pci/pci_pci.c | 652 +++++++++++++++++++++++++++++++- sys/dev/pci/pcib_private.h | 30 ++ sys/i386/pci/pci_bus.c | 1 + sys/sparc64/pci/apb.c | 1 + sys/sparc64/pci/ofw_pcib.c | 1 + sys/x86/pci/qpi.c | 1 + sys/x86/x86/mptable_pci.c | 1 + 12 files changed, 714 insertions(+), 9 deletions(-) diff --git a/sys/amd64/pci/pci_bus.c b/sys/amd64/pci/pci_bus.c index 0f33cdf229ea..7c377ac4ced5 100644 --- a/sys/amd64/pci/pci_bus.c +++ b/sys/amd64/pci/pci_bus.c @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include diff --git a/sys/conf/options b/sys/conf/options index 4ddb9fad9c3f..a608d86382f6 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -136,6 +136,7 @@ MFI_DEBUG opt_mfi.h MFI_DECODE_LOG opt_mfi.h MPROF_BUFFERS opt_mprof.h MPROF_HASH_SIZE opt_mprof.h +NEW_PCIB opt_global.h NO_ADAPTIVE_MUTEXES opt_adaptive_mutexes.h NO_ADAPTIVE_RWLOCKS NO_ADAPTIVE_SX diff --git a/sys/dev/acpica/acpi_pcib_acpi.c b/sys/dev/acpica/acpi_pcib_acpi.c index dc3e5b10620f..e4efefff66d3 100644 --- a/sys/dev/acpica/acpi_pcib_acpi.c +++ b/sys/dev/acpica/acpi_pcib_acpi.c @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -370,11 +371,17 @@ acpi_pcib_acpi_alloc_resource(device_t dev, device_t child, int type, int *rid, * Hardcoding like this sucks, so a more MD/MI way needs to be * found to do it. This is typically only used on older laptops * that don't have pci busses behind pci bridge, so assuming > 32MB - * is liekly OK. + * is likely OK. + * + * PCI-PCI bridges may allocate smaller ranges for their windows, + * but the heuristics here should apply to those, so we allow + * several different end addresses. */ - if (type == SYS_RES_MEMORY && start == 0UL && end == ~0UL) + if (type == SYS_RES_MEMORY && start == 0UL && (end == ~0UL || + end == 0xffffffff)) start = acpi_host_mem_start; - if (type == SYS_RES_IOPORT && start == 0UL && end == ~0UL) + if (type == SYS_RES_IOPORT && start == 0UL && (end == ~0UL || + end == 0xffff || end == 0xffffffff)) start = 0x1000; return (bus_generic_alloc_resource(dev, child, type, rid, start, end, count, flags)); diff --git a/sys/dev/acpica/acpi_pcib_pci.c b/sys/dev/acpica/acpi_pcib_pci.c index a76698141f08..7dbccd6a2086 100644 --- a/sys/dev/acpica/acpi_pcib_pci.c +++ b/sys/dev/acpica/acpi_pcib_pci.c @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index 70d5590032b4..22046c1f30f7 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -3967,6 +3967,26 @@ pci_alloc_resource(device_t dev, device_t child, int type, int *rid, break; case SYS_RES_IOPORT: case SYS_RES_MEMORY: +#ifdef NEW_PCIB + /* + * PCI-PCI bridge I/O window resources are not BARs. + * For those allocations just pass the request up the + * tree. + */ + if (cfg->hdrtype == PCIM_HDRTYPE_BRIDGE) { + switch (*rid) { + case PCIR_IOBASEL_1: + case PCIR_MEMBASE_1: + case PCIR_PMBASEL_1: + /* + * XXX: Should we bother creating a resource + * list entry? + */ + return (bus_generic_alloc_resource(dev, child, + type, rid, start, end, count, flags)); + } + } +#endif /* Reserve resources for this BAR if needed. */ rle = resource_list_find(rl, type, *rid); if (rle == NULL) { diff --git a/sys/dev/pci/pci_pci.c b/sys/dev/pci/pci_pci.c index eaaf6d3a68f8..f68973b395a9 100644 --- a/sys/dev/pci/pci_pci.c +++ b/sys/dev/pci/pci_pci.c @@ -36,14 +36,16 @@ __FBSDID("$FreeBSD$"); */ #include -#include -#include -#include #include -#include +#include +#include +#include +#include #include #include +#include +#include #include #include @@ -73,8 +75,13 @@ static device_method_t pcib_methods[] = { DEVMETHOD(bus_read_ivar, pcib_read_ivar), DEVMETHOD(bus_write_ivar, pcib_write_ivar), DEVMETHOD(bus_alloc_resource, pcib_alloc_resource), +#ifdef NEW_PCIB + DEVMETHOD(bus_adjust_resource, pcib_adjust_resource), + DEVMETHOD(bus_release_resource, pcib_release_resource), +#else DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource), DEVMETHOD(bus_release_resource, bus_generic_release_resource), +#endif DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), @@ -100,6 +107,243 @@ static devclass_t pcib_devclass; DEFINE_CLASS_0(pcib, pcib_driver, pcib_methods, sizeof(struct pcib_softc)); DRIVER_MODULE(pcib, pci, pcib_driver, pcib_devclass, 0, 0); +#ifdef NEW_PCIB +/* + * XXX Todo: + * - properly handle the ISA enable bit. If it is set, we should change + * the behavior of the I/O window resource and rman to not allocate the + * blocked ranges (upper 768 bytes of each 1K in the first 64k of the + * I/O port address space). + */ + +/* + * Is a resource from a child device sub-allocated from one of our + * resource managers? + */ +static int +pcib_is_resource_managed(struct pcib_softc *sc, int type, struct resource *r) +{ + + switch (type) { + case SYS_RES_IOPORT: + return (rman_is_region_manager(r, &sc->io.rman)); + case SYS_RES_MEMORY: + /* Prefetchable resources may live in either memory rman. */ + if (rman_get_flags(r) & RF_PREFETCHABLE && + rman_is_region_manager(r, &sc->pmem.rman)) + return (1); + return (rman_is_region_manager(r, &sc->mem.rman)); + } + return (0); +} + +static int +pcib_is_window_open(struct pcib_window *pw) +{ + + return (pw->valid && pw->base < pw->limit); +} + +/* + * XXX: If RF_ACTIVE did not also imply allocating a bus space tag and + * handle for the resource, we could pass RF_ACTIVE up to the PCI bus + * when allocating the resource windows and rely on the PCI bus driver + * to do this for us. + */ +static void +pcib_activate_window(struct pcib_softc *sc, int type) +{ + + PCI_ENABLE_IO(device_get_parent(sc->dev), sc->dev, type); +} + +static void +pcib_write_windows(struct pcib_softc *sc, int mask) +{ + device_t dev; + uint32_t val; + + dev = sc->dev; + if (sc->io.valid && mask & WIN_IO) { + val = pci_read_config(dev, PCIR_IOBASEL_1, 1); + if ((val & PCIM_BRIO_MASK) == PCIM_BRIO_32) { + pci_write_config(dev, PCIR_IOBASEH_1, + sc->io.base >> 16, 2); + pci_write_config(dev, PCIR_IOLIMITH_1, + sc->io.limit >> 16, 2); + } + pci_write_config(dev, PCIR_IOBASEL_1, sc->io.base >> 8, 1); + pci_write_config(dev, PCIR_IOLIMITL_1, sc->io.limit >> 8, 1); + } + + if (mask & WIN_MEM) { + pci_write_config(dev, PCIR_MEMBASE_1, sc->mem.base >> 16, 2); + pci_write_config(dev, PCIR_MEMLIMIT_1, sc->mem.limit >> 16, 2); + } + + if (sc->pmem.valid && mask & WIN_PMEM) { + val = pci_read_config(dev, PCIR_PMBASEL_1, 2); + if ((val & PCIM_BRPM_MASK) == PCIM_BRPM_64) { + pci_write_config(dev, PCIR_PMBASEH_1, + sc->pmem.base >> 32, 4); + pci_write_config(dev, PCIR_PMLIMITH_1, + sc->pmem.limit >> 32, 4); + } + pci_write_config(dev, PCIR_PMBASEL_1, sc->pmem.base >> 16, 2); + pci_write_config(dev, PCIR_PMLIMITL_1, sc->pmem.limit >> 16, 2); + } +} + +static void +pcib_alloc_window(struct pcib_softc *sc, struct pcib_window *w, int type, + int flags, pci_addr_t max_address) +{ + char buf[64]; + int error, rid; + + if (max_address != (u_long)max_address) + max_address = ~0ul; + w->rman.rm_start = 0; + w->rman.rm_end = max_address; + w->rman.rm_type = RMAN_ARRAY; + snprintf(buf, sizeof(buf), "%s %s window", + device_get_nameunit(sc->dev), w->name); + w->rman.rm_descr = strdup(buf, M_DEVBUF); + error = rman_init(&w->rman); + if (error) + panic("Failed to initialize %s %s rman", + device_get_nameunit(sc->dev), w->name); + + if (!pcib_is_window_open(w)) + return; + + if (w->base > max_address || w->limit > max_address) { + device_printf(sc->dev, + "initial %s window has too many bits, ignoring\n", w->name); + return; + } + rid = w->reg; + w->res = bus_alloc_resource(sc->dev, type, &rid, w->base, w->limit, + w->limit - w->base + 1, flags); + if (w->res == NULL) { + device_printf(sc->dev, + "failed to allocate initial %s window: %#jx-%#jx\n", + w->name, (uintmax_t)w->base, (uintmax_t)w->limit); + w->base = max_address; + w->limit = 0; + pcib_write_windows(sc, w->mask); + return; + } + pcib_activate_window(sc, type); + + error = rman_manage_region(&w->rman, rman_get_start(w->res), + rman_get_end(w->res)); + if (error) + panic("Failed to initialize rman with resource"); +} + +/* + * Initialize I/O windows. + */ +static void +pcib_probe_windows(struct pcib_softc *sc) +{ + pci_addr_t max; + device_t dev; + uint32_t val; + + dev = sc->dev; + + /* Determine if the I/O port window is implemented. */ + val = pci_read_config(dev, PCIR_IOBASEL_1, 1); + if (val == 0) { + /* + * If 'val' is zero, then only 16-bits of I/O space + * are supported. + */ + pci_write_config(dev, PCIR_IOBASEL_1, 0xff, 1); + if (pci_read_config(dev, PCIR_IOBASEL_1, 1) != 0) { + sc->io.valid = 1; + pci_write_config(dev, PCIR_IOBASEL_1, 0, 1); + } + } else + sc->io.valid = 1; + + /* Read the existing I/O port window. */ + if (sc->io.valid) { + sc->io.reg = PCIR_IOBASEL_1; + sc->io.step = 12; + sc->io.mask = WIN_IO; + sc->io.name = "I/O port"; + if ((val & PCIM_BRIO_MASK) == PCIM_BRIO_32) { + sc->io.base = PCI_PPBIOBASE( + pci_read_config(dev, PCIR_IOBASEH_1, 2), val); + sc->io.limit = PCI_PPBIOLIMIT( + pci_read_config(dev, PCIR_IOLIMITH_1, 2), + pci_read_config(dev, PCIR_IOLIMITL_1, 1)); + max = 0xffffffff; + } else { + sc->io.base = PCI_PPBIOBASE(0, val); + sc->io.limit = PCI_PPBIOLIMIT(0, + pci_read_config(dev, PCIR_IOLIMITL_1, 1)); + max = 0xffff; + } + pcib_alloc_window(sc, &sc->io, SYS_RES_IOPORT, 0, max); + } + + /* Read the existing memory window. */ + sc->mem.valid = 1; + sc->mem.reg = PCIR_MEMBASE_1; + sc->mem.step = 20; + sc->mem.mask = WIN_MEM; + sc->mem.name = "memory"; + sc->mem.base = PCI_PPBMEMBASE(0, + pci_read_config(dev, PCIR_MEMBASE_1, 2)); + sc->mem.limit = PCI_PPBMEMLIMIT(0, + pci_read_config(dev, PCIR_MEMLIMIT_1, 2)); + pcib_alloc_window(sc, &sc->mem, SYS_RES_MEMORY, 0, 0xffffffff); + + /* Determine if the prefetchable memory window is implemented. */ + val = pci_read_config(dev, PCIR_PMBASEL_1, 2); + if (val == 0) { + /* + * If 'val' is zero, then only 32-bits of memory space + * are supported. + */ + pci_write_config(dev, PCIR_PMBASEL_1, 0xffff, 2); + if (pci_read_config(dev, PCIR_PMBASEL_1, 2) != 0) { + sc->pmem.valid = 1; + pci_write_config(dev, PCIR_PMBASEL_1, 0, 2); + } + } else + sc->pmem.valid = 1; + + /* Read the existing prefetchable memory window. */ + if (sc->pmem.valid) { + sc->pmem.reg = PCIR_PMBASEL_1; + sc->pmem.step = 20; + sc->pmem.mask = WIN_PMEM; + sc->pmem.name = "prefetch"; + if ((val & PCIM_BRPM_MASK) == PCIM_BRPM_64) { + sc->pmem.base = PCI_PPBMEMBASE( + pci_read_config(dev, PCIR_PMBASEH_1, 4), val); + sc->pmem.limit = PCI_PPBMEMLIMIT( + pci_read_config(dev, PCIR_PMLIMITH_1, 4), + pci_read_config(dev, PCIR_PMLIMITL_1, 2)); + max = 0xffffffffffffffff; + } else { + sc->pmem.base = PCI_PPBMEMBASE(0, val); + sc->pmem.limit = PCI_PPBMEMLIMIT(0, + pci_read_config(dev, PCIR_PMLIMITL_1, 2)); + max = 0xffffffff; + } + pcib_alloc_window(sc, &sc->pmem, SYS_RES_MEMORY, + RF_PREFETCHABLE, max); + } +} + +#else + /* * Is the prefetch window open (eg, can we allocate memory in it?) */ @@ -230,6 +474,7 @@ pcib_set_mem_decode(struct pcib_softc *sc) pci_write_config(dev, PCIR_PMLIMITH_1, pmemhi, 4); pci_write_config(dev, PCIR_PMLIMITL_1, sc->pmemlimit >> 16, 2); } +#endif /* * Get current bridge configuration. @@ -247,10 +492,12 @@ pcib_cfg_save(struct pcib_softc *sc) sc->subbus = pci_read_config(dev, PCIR_SUBBUS_1, 1); sc->bridgectl = pci_read_config(dev, PCIR_BRIDGECTL_1, 2); sc->seclat = pci_read_config(dev, PCIR_SECLAT_1, 1); +#ifndef NEW_PCIB if (sc->command & PCIM_CMD_PORTEN) pcib_get_io_decode(sc); if (sc->command & PCIM_CMD_MEMEN) pcib_get_mem_decode(sc); +#endif } /* @@ -269,10 +516,14 @@ pcib_cfg_restore(struct pcib_softc *sc) pci_write_config(dev, PCIR_SUBBUS_1, sc->subbus, 1); pci_write_config(dev, PCIR_BRIDGECTL_1, sc->bridgectl, 2); pci_write_config(dev, PCIR_SECLAT_1, sc->seclat, 1); +#ifdef NEW_PCIB + pcib_write_windows(sc, WIN_IO | WIN_MEM | WIN_PMEM); +#else if (sc->command & PCIM_CMD_PORTEN) pcib_set_io_decode(sc); if (sc->command & PCIM_CMD_MEMEN) pcib_set_mem_decode(sc); +#endif } /* @@ -389,18 +640,35 @@ pcib_attach_common(device_t dev) if ((pci_get_devid(dev) & 0xff00ffff) == 0x24008086 || pci_read_config(dev, PCIR_PROGIF, 1) == PCIP_BRIDGE_PCI_SUBTRACTIVE) sc->flags |= PCIB_SUBTRACTIVE; - + +#ifdef NEW_PCIB + pcib_probe_windows(sc); +#endif if (bootverbose) { device_printf(dev, " domain %d\n", sc->domain); device_printf(dev, " secondary bus %d\n", sc->secbus); device_printf(dev, " subordinate bus %d\n", sc->subbus); - device_printf(dev, " I/O decode 0x%x-0x%x\n", sc->iobase, sc->iolimit); +#ifdef NEW_PCIB + if (pcib_is_window_open(&sc->io)) + device_printf(dev, " I/O decode 0x%jx-0x%jx\n", + (uintmax_t)sc->io.base, (uintmax_t)sc->io.limit); + if (pcib_is_window_open(&sc->mem)) + device_printf(dev, " memory decode 0x%jx-0x%jx\n", + (uintmax_t)sc->mem.base, (uintmax_t)sc->mem.limit); + if (pcib_is_window_open(&sc->pmem)) + device_printf(dev, " prefetched decode 0x%jx-0x%jx\n", + (uintmax_t)sc->pmem.base, (uintmax_t)sc->pmem.limit); +#else + if (pcib_is_io_open(sc)) + device_printf(dev, " I/O decode 0x%x-0x%x\n", + sc->iobase, sc->iolimit); if (pcib_is_nonprefetch_open(sc)) device_printf(dev, " memory decode 0x%jx-0x%jx\n", (uintmax_t)sc->membase, (uintmax_t)sc->memlimit); if (pcib_is_prefetch_open(sc)) device_printf(dev, " prefetched decode 0x%jx-0x%jx\n", (uintmax_t)sc->pmembase, (uintmax_t)sc->pmemlimit); +#endif else device_printf(dev, " no prefetched decode\n"); if (sc->flags & PCIB_SUBTRACTIVE) @@ -502,6 +770,377 @@ pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value) return(ENOENT); } +#ifdef NEW_PCIB +static const char * +pcib_child_name(device_t child) +{ + static char buf[64]; + + if (device_get_nameunit(child) != NULL) + return (device_get_nameunit(child)); + snprintf(buf, sizeof(buf), "pci%d:%d:%d:%d", pci_get_domain(child), + pci_get_bus(child), pci_get_slot(child), pci_get_function(child)); + return (buf); +} + +/* + * Attempt to allocate a resource from the existing resources assigned + * to a window. + */ +static struct resource * +pcib_suballoc_resource(struct pcib_softc *sc, struct pcib_window *w, + device_t child, int type, int *rid, u_long start, u_long end, u_long count, + u_int flags) +{ + struct resource *res; + + if (!pcib_is_window_open(w)) + return (NULL); + + res = rman_reserve_resource(&w->rman, start, end, count, + flags & ~RF_ACTIVE, child); + if (res == NULL) + return (NULL); + + if (bootverbose) + device_printf(sc->dev, + "allocated %s range (%#lx-%#lx) for rid %x of %s\n", + w->name, rman_get_start(res), rman_get_end(res), *rid, + pcib_child_name(child)); + rman_set_rid(res, *rid); + + /* + * If the resource should be active, pass that request up the + * tree. This assumes the parent drivers can handle + * activating sub-allocated resources. + */ + if (flags & RF_ACTIVE) { + if (bus_activate_resource(child, type, *rid, res) != 0) { + rman_release_resource(res); + return (NULL); + } + } + + return (res); +} + +/* + * Attempt to grow a window to make room for a given resource request. + * The 'step' parameter is log_2 of the desired I/O window's alignment. + */ +static int +pcib_grow_window(struct pcib_softc *sc, struct pcib_window *w, int type, + u_long start, u_long end, u_long count, u_int flags) +{ + u_long align, start_free, end_free, front, back; + int error, rid; + + /* + * Clamp the desired resource range to the maximum address + * this window supports. Reject impossible requests. + */ + if (!w->valid) + return (EINVAL); + if (end > w->rman.rm_end) + end = w->rman.rm_end; + if (start + count - 1 > end || start + count < start) + return (EINVAL); + + /* + * If there is no resource at all, just try to allocate enough + * aligned space for this resource. + */ + if (w->res == NULL) { + if (RF_ALIGNMENT(flags) < w->step) { + flags &= ~RF_ALIGNMENT_MASK; + flags |= RF_ALIGNMENT_LOG2(w->step); + } + start &= ~((1ul << w->step) - 1); + end |= ((1ul << w->step) - 1); + count = roundup2(count, 1ul << w->step); + rid = w->reg; + w->res = bus_alloc_resource(sc->dev, type, &rid, start, end, + count, flags & ~RF_ACTIVE); + if (w->res == NULL) { + if (bootverbose) + device_printf(sc->dev, + "failed to allocate initial %s window (%#lx-%#lx,%#lx)\n", + w->name, start, end, count); + return (ENXIO); + } + if (bootverbose) + device_printf(sc->dev, + "allocated initial %s window of %#lx-%#lx\n", + w->name, rman_get_start(w->res), + rman_get_end(w->res)); + error = rman_manage_region(&w->rman, rman_get_start(w->res), + rman_get_end(w->res)); + if (error) { + if (bootverbose) + device_printf(sc->dev, + "failed to add initial %s window to rman\n", + w->name); + bus_release_resource(sc->dev, type, w->reg, w->res); + w->res = NULL; + return (error); + } + pcib_activate_window(sc, type); + goto updatewin; + } + + /* + * See if growing the window would help. Compute the minimum + * amount of address space needed on both the front and back + * ends of the existing window to satisfy the allocation. + * + * For each end, build a candidate region adjusting for the + * required alignment, etc. If there is a free region at the + * edge of the window, grow from the inner edge of the free + * region. Otherwise grow from the window boundary. + * + * XXX: Special case: if w->res is completely empty and the + * request size is larger than w->res, we should find the + * optimal aligned buffer containing w->res and allocate that. + */ + if (bootverbose) + device_printf(sc->dev, + "attempting to grow %s window for (%#lx-%#lx,%#lx)\n", + w->name, start, end, count); + align = 1ul << RF_ALIGNMENT(flags); + if (start < rman_get_start(w->res)) { + if (rman_first_free_region(&w->rman, &start_free, &end_free) != + 0 || start_free != rman_get_start(w->res)) + end_free = rman_get_start(w->res) - 1; + if (end_free > end) + end_free = end; + + /* Move end_free down until it is properly aligned. */ + end_free &= ~(align - 1); + front = end_free - count; + + /* + * The resource would now be allocated at (front, + * end_free). Ensure that fits in the (start, end) + * bounds. end_free is checked above. If 'front' is + * ok, ensure it is properly aligned for this window. + * Also check for underflow. + */ + if (front >= start && front <= end_free) { + if (bootverbose) + printf("\tfront candidate range: %#lx-%#lx\n", + front, end_free); + front &= (1ul << w->step) - 1; + front = rman_get_start(w->res) - front; + } else + front = 0; + } else + front = 0; + if (end > rman_get_end(w->res)) { + if (rman_last_free_region(&w->rman, &start_free, &end_free) != + 0 || end_free != rman_get_end(w->res)) + start_free = rman_get_end(w->res) + 1; + if (start_free < start) + start_free = start; + + /* Move start_free up until it is properly aligned. */ + start_free = roundup2(start_free, align); + back = start_free + count; + + /* + * The resource would now be allocated at (start_free, + * back). Ensure that fits in the (start, end) + * bounds. start_free is checked above. If 'back' is + * ok, ensure it is properly aligned for this window. + * Also check for overflow. + */ + if (back <= end && start_free <= back) { + if (bootverbose) + printf("\tback candidate range: %#lx-%#lx\n", + start_free, back); + back = roundup2(back, w->step) - 1; + back -= rman_get_end(w->res); + } else + back = 0; + } else + back = 0; + + /* + * Try to allocate the smallest needed region first. + * If that fails, fall back to the other region. + */ + error = ENOSPC; + while (front != 0 || back != 0) { + if (front != 0 && (front <= back || back == 0)) { + error = bus_adjust_resource(sc->dev, type, w->res, + rman_get_start(w->res) - front, + rman_get_end(w->res)); + if (error == 0) + break; + front = 0; + } else { + error = bus_adjust_resource(sc->dev, type, w->res, + rman_get_start(w->res), + rman_get_end(w->res) + back); + if (error == 0) + break; + back = 0; + } + } + + if (error) + return (error); + if (bootverbose) + device_printf(sc->dev, "grew %s window to %#lx-%#lx\n", + w->name, rman_get_start(w->res), rman_get_end(w->res)); + + /* Add the newly allocated region to the resource manager. */ + if (w->base != rman_get_start(w->res)) { + KASSERT(w->limit == rman_get_end(w->res), ("both ends moved")); + error = rman_manage_region(&w->rman, rman_get_start(w->res), + w->base - 1); + } else { + KASSERT(w->limit != rman_get_end(w->res), + ("neither end moved")); + error = rman_manage_region(&w->rman, w->limit + 1, + rman_get_end(w->res)); + } + if (error) { + if (bootverbose) + device_printf(sc->dev, + "failed to expand %s resource manager\n", w->name); + bus_adjust_resource(sc->dev, type, w->res, w->base, w->limit); + return (error); + } + +updatewin: + /* Save the new window. */ + w->base = rman_get_start(w->res); + w->limit = rman_get_end(w->res); + KASSERT((w->base & ((1ul << w->step) - 1)) == 0, + ("start address is not aligned")); + KASSERT((w->limit & ((1ul << w->step) - 1)) == (1ul << w->step) - 1, + ("end address is not aligned")); + pcib_write_windows(sc, w->mask); + return (0); +} + +/* + * We have to trap resource allocation requests and ensure that the bridge + * is set up to, or capable of handling them. + */ +struct resource * +pcib_alloc_resource(device_t dev, device_t child, int type, int *rid, + u_long start, u_long end, u_long count, u_int flags) +{ + struct pcib_softc *sc; + struct resource *r; + + sc = device_get_softc(dev); + + /* + * VGA resources are decoded iff the VGA enable bit is set in + * the bridge control register. VGA resources do not fall into + * the resource windows and are passed up to the parent. + */ + if ((type == SYS_RES_IOPORT && pci_is_vga_ioport_range(start, end)) || + (type == SYS_RES_MEMORY && pci_is_vga_memory_range(start, end))) { + if (sc->bridgectl & PCIB_BCR_VGA_ENABLE) + return (bus_generic_alloc_resource(dev, child, type, + rid, start, end, count, flags)); + else + return (NULL); + } + + switch (type) { + case SYS_RES_IOPORT: + r = pcib_suballoc_resource(sc, &sc->io, child, type, rid, start, + end, count, flags); + if (r != NULL) + break; + if (pcib_grow_window(sc, &sc->io, type, start, end, count, + flags) == 0) + r = pcib_suballoc_resource(sc, &sc->io, child, type, + rid, start, end, count, flags); + break; + case SYS_RES_MEMORY: + /* + * For prefetchable resources, prefer the prefetchable + * memory window, but fall back to the regular memory + * window if that fails. Try both windows before + * attempting to grow a window in case the firmware + * has used a range in the regular memory window to + * map a prefetchable BAR. + */ + if (flags & RF_PREFETCHABLE) { + r = pcib_suballoc_resource(sc, &sc->pmem, child, type, + rid, start, end, count, flags); + if (r != NULL) + break; + } + r = pcib_suballoc_resource(sc, &sc->mem, child, type, rid, + start, end, count, flags); + if (r != NULL) + break; + if (flags & RF_PREFETCHABLE) { + if (pcib_grow_window(sc, &sc->pmem, type, start, end, + count, flags) == 0) { + r = pcib_suballoc_resource(sc, &sc->pmem, child, + type, rid, start, end, count, flags); + if (r != NULL) + break; + } + } + if (pcib_grow_window(sc, &sc->mem, type, start, end, count, + flags & ~RF_PREFETCHABLE) == 0) + r = pcib_suballoc_resource(sc, &sc->mem, child, type, + rid, start, end, count, flags); + break; + default: + return (bus_generic_alloc_resource(dev, child, type, rid, + start, end, count, flags)); + } + + /* + * If attempts to suballocate from the window fail but this is a + * subtractive bridge, pass the request up the tree. + */ + if (sc->flags & PCIB_SUBTRACTIVE && r == NULL) + return (bus_generic_alloc_resource(dev, child, type, rid, + start, end, count, flags)); + return (r); +} + +int +pcib_adjust_resource(device_t bus, device_t child, int type, struct resource *r, + u_long start, u_long end) +{ + struct pcib_softc *sc; + + sc = device_get_softc(bus); + if (pcib_is_resource_managed(sc, type, r)) + return (rman_adjust_resource(r, start, end)); + return (bus_generic_adjust_resource(bus, child, type, r, start, end)); +} + +int +pcib_release_resource(device_t dev, device_t child, int type, int rid, + struct resource *r) +{ + struct pcib_softc *sc; + int error; + + sc = device_get_softc(dev); + if (pcib_is_resource_managed(sc, type, r)) { + if (rman_get_flags(r) & RF_ACTIVE) { + error = bus_deactivate_resource(child, type, rid, r); + if (error) + return (error); + } + return (rman_release_resource(r)); + } + return (bus_generic_release_resource(dev, child, type, rid, r)); +} +#else /* * We have to trap resource allocation requests and ensure that the bridge * is set up to, or capable of handling them. @@ -657,6 +1296,7 @@ pcib_alloc_resource(device_t dev, device_t child, int type, int *rid, return (bus_generic_alloc_resource(dev, child, type, rid, start, end, count, flags)); } +#endif /* * PCIB interface. diff --git a/sys/dev/pci/pcib_private.h b/sys/dev/pci/pcib_private.h index b6e49de57ae6..1574deb752b3 100644 --- a/sys/dev/pci/pcib_private.h +++ b/sys/dev/pci/pcib_private.h @@ -39,6 +39,24 @@ */ DECLARE_CLASS(pcib_driver); +#ifdef NEW_PCIB +#define WIN_IO 0x1 +#define WIN_MEM 0x2 +#define WIN_PMEM 0x4 + +struct pcib_window { + pci_addr_t base; /* base address */ + pci_addr_t limit; /* topmost address */ + struct rman rman; + struct resource *res; + int reg; /* resource id from parent */ + int valid; + int mask; /* WIN_* bitmask of this window */ + int step; /* log_2 of window granularity */ + const char *name; +}; +#endif + /* * Bridge-specific data. */ @@ -53,12 +71,18 @@ struct pcib_softc u_int pribus; /* primary bus number */ u_int secbus; /* secondary bus number */ u_int subbus; /* subordinate bus number */ +#ifdef NEW_PCIB + struct pcib_window io; /* I/O port window */ + struct pcib_window mem; /* memory window */ + struct pcib_window pmem; /* prefetchable memory window */ +#else pci_addr_t pmembase; /* base address of prefetchable memory */ pci_addr_t pmemlimit; /* topmost address of prefetchable memory */ pci_addr_t membase; /* base address of memory window */ pci_addr_t memlimit; /* topmost address of memory window */ uint32_t iobase; /* base address of port window */ uint32_t iolimit; /* topmost address of port window */ +#endif uint16_t secstat; /* secondary bus status register */ uint16_t bridgectl; /* bridge control register */ uint8_t seclat; /* secondary bus latency timer */ @@ -74,6 +98,12 @@ int pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result); int pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value); struct resource *pcib_alloc_resource(device_t dev, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags); +#ifdef NEW_PCIB +int pcib_adjust_resource(device_t bus, device_t child, int type, + struct resource *r, u_long start, u_long end); +int pcib_release_resource(device_t dev, device_t child, int type, int rid, + struct resource *r); +#endif int pcib_maxslots(device_t dev); uint32_t pcib_read_config(device_t dev, u_int b, u_int s, u_int f, u_int reg, int width); void pcib_write_config(device_t dev, u_int b, u_int s, u_int f, u_int reg, uint32_t val, int width); diff --git a/sys/i386/pci/pci_bus.c b/sys/i386/pci/pci_bus.c index eb26b8664fa4..61dab3f143b8 100644 --- a/sys/i386/pci/pci_bus.c +++ b/sys/i386/pci/pci_bus.c @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include diff --git a/sys/sparc64/pci/apb.c b/sys/sparc64/pci/apb.c index f260f32182ed..87f182109569 100644 --- a/sys/sparc64/pci/apb.c +++ b/sys/sparc64/pci/apb.c @@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include diff --git a/sys/sparc64/pci/ofw_pcib.c b/sys/sparc64/pci/ofw_pcib.c index e533221ac7c3..45c9f1c9747f 100644 --- a/sys/sparc64/pci/ofw_pcib.c +++ b/sys/sparc64/pci/ofw_pcib.c @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include diff --git a/sys/x86/pci/qpi.c b/sys/x86/pci/qpi.c index 131519530194..d14494ca1bbf 100644 --- a/sys/x86/pci/qpi.c +++ b/sys/x86/pci/qpi.c @@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include diff --git a/sys/x86/x86/mptable_pci.c b/sys/x86/x86/mptable_pci.c index c2b6cee6d943..48eec7f6563e 100644 --- a/sys/x86/x86/mptable_pci.c +++ b/sys/x86/x86/mptable_pci.c @@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include From 6162795be06879f34c61a72afae9290e96778597 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Tue, 3 May 2011 18:23:11 +0000 Subject: [PATCH 25/25] Enable the new PCI-PCI bridge driver on amd64 and i386 by default. It can be disabled via 'nooptions NEW_PCIB'. --- sys/amd64/conf/DEFAULTS | 2 ++ sys/i386/conf/DEFAULTS | 2 ++ 2 files changed, 4 insertions(+) diff --git a/sys/amd64/conf/DEFAULTS b/sys/amd64/conf/DEFAULTS index 1fb52b34e0c2..2c221cb76bb9 100644 --- a/sys/amd64/conf/DEFAULTS +++ b/sys/amd64/conf/DEFAULTS @@ -20,3 +20,5 @@ options GEOM_PART_BSD options GEOM_PART_EBR options GEOM_PART_EBR_COMPAT options GEOM_PART_MBR + +options NEW_PCIB diff --git a/sys/i386/conf/DEFAULTS b/sys/i386/conf/DEFAULTS index 32e77e41979b..78d807c3d344 100644 --- a/sys/i386/conf/DEFAULTS +++ b/sys/i386/conf/DEFAULTS @@ -28,3 +28,5 @@ options GEOM_PART_MBR # enable support for native hardware options NATIVE device atpic + +options NEW_PCIB