Re: fix ld -Z on powerpc
Date: Tue, 18 Aug 2015 05:03:19 + From: Miod Vallat m...@online.fr I spent some time today figuting out why the binutils update broke ld -Z on powerpc. Turns out to be a fairly thorny issue. The new binutils discard empty setions. As a result the .gotpad0 and .gotpad1 sections have disappeared. And a s a consequence the __got_start and __got_end symbols are now absolute symbols as the section they referenced to is no longer there. For example, an older libc has: 845: 000eeb68 0 NOTYPE GLOBAL DEFAULT 17 __got_start whereas -current has: 810: 000eeb58 0 NOTYPE GLOBAL DEFAULT ABS __got_start On powerpc, crt0.o has weak references to __got_start and __got_end. When building a binary with ld -Z, these are resolved to the absolute symbols from libc. At runtime we then use these values, relocated as if they were addresses within the binary itself, to change protections and flush the instruction cache. This is very likely to result in a segmentation fault. There is probably a linker bug here, as it doesn't make any sense for the linker to pick the address of these symbols from libc and stick it into the binary. But I'm not sure about this. And it isn't all that obvious what the fix would be. Is the bug that the symbols end up as absolute? Or is the problem that it sibsequently resolves these to the values from libc.so? Wouldn't something like that address the problem better? Unfortunately not. Using PROVIDE() makes the __got_start/end symbols disappear from shared libraries. If I use: GOTSTART=__got_start = .; I end up with the same absolute symbols as before. You really have to tie the symbols to a specific section that isn't discarded to make them end up as normal symbols. And that is difficult since we try to make __got_start/end cover multiple sections, some of which may or may not be present. I still think my diff to remove code is the way to go. As I explained, it isn't really clear which set of symbols the references in crt0.o will actually resolve to. And the secure-plt work will require changes to the code anyway to make sure we don't end up with an executable GOT after all. Index: elf.sc === RCS file: /OpenBSD/src/gnu/usr.bin/binutils-2.17/ld/scripttempl/elf.sc,v retrieving revision 1.8 diff -u -p -r1.8 elf.sc --- elf.sc9 Aug 2014 04:49:47 - 1.8 +++ elf.sc18 Aug 2015 05:02:41 - @@ -195,10 +195,12 @@ if test $NO_PAD = y ; then PAD_RO0=${RELOCATING+${RODATA_ALIGN} + ${RODATA_ALIGN_ADD_VAL};} PAD_PLT0=${RELOCATING+. = ALIGN(${MAXPAGESIZE}) + (. (${MAXPAGESIZE} - 1));} .pltpad0 ${RELOCATING-0} : { ${RELOCATING+__plt_start = .;} } PAD_PLT1=.pltpad1 ${RELOCATING-0} : { ${RELOCATING+__plt_end = .;}} ${RELOCATING+. = ALIGN(${MAXPAGESIZE}) + (. (${MAXPAGESIZE} - 1));} - PAD_GOT0=${RELOCATING+. = ALIGN(${MAXPAGESIZE}) + (. (${MAXPAGESIZE} - 1));} .gotpad0 ${RELOCATING-0} : { ${RELOCATING+__got_start = .;} } - PAD_GOT1=.gotpad1 ${RELOCATING-0} : { ${RELOCATING+__got_end = .;}} ${RELOCATING+. = ALIGN(${MAXPAGESIZE}) + (. (${MAXPAGESIZE} - 1));} + PAD_GOT0=${RELOCATING+. = ALIGN(${MAXPAGESIZE}) + (. (${MAXPAGESIZE} - 1));} + PAD_GOT1=${RELOCATING+. = ALIGN(${MAXPAGESIZE}) + (. (${MAXPAGESIZE} - 1));} test $NO_PAD_CDTOR = y || PAD_CDTOR= fi +GOTSTART=PROVIDE (__got_start = .); +GOTEND=PROVIDE (__got_end = .); CTOR=.ctors${CONSTRUCTING-0} : { @@ -420,9 +422,11 @@ cat EOF ${OTHER_RELRO_SECTIONS} ${TEXT_DYNAMIC-${DYNAMIC}} ${DATA_GOT+${PAD_GOT+${PAD_GOT0}}} + ${DATA_GOT+${GOTSTART}} ${DATA_GOT+${DATA_NONEXEC_PLT+${PLT}}} ${DATA_GOT+${RELRO_NOW+${GOT}}} ${DATA_GOT+${RELRO_NOW+${GOTPLT}}} + ${DATA_GOT+${RELRO_NOW+${GOTEND}}} ${DATA_GOT+${RELRO_NOW+${PAD_GOT+${PAD_GOT1 ${DATA_GOT+${RELRO_NOW-${SEPARATE_GOTPLT+${GOT /* If PAD_CDTOR, and separate .got and .got.plt sections, CTOR and DTOR @@ -430,11 +434,13 @@ cat EOF ${DATA_GOT+${RELRO_NOW-${SEPARATE_GOTPLT+${PAD_CDTOR+${RELOCATING+${CTOR}} ${DATA_GOT+${RELRO_NOW-${SEPARATE_GOTPLT+${PAD_CDTOR+${RELOCATING+${DTOR}} ${DATA_GOT+${RELRO_NOW-${SEPARATE_GOTPLT+${PAD_GOT+${PAD_GOT1} + ${DATA_GOT+${RELRO_NOW-${SEPARATE_GOTPLT+${GOTEND ${RELOCATING+${DATA_SEGMENT_RELRO_END}} ${DATA_GOT+${RELRO_NOW-${SEPARATE_GOTPLT-${GOT ${DATA_GOT+${RELRO_NOW-${SEPARATE_GOTPLT-${PAD_CDTOR+${RELOCATING+${CTOR}} ${DATA_GOT+${RELRO_NOW-${SEPARATE_GOTPLT-${PAD_CDTOR+${RELOCATING+${DTOR}} ${DATA_GOT+${RELRO_NOW-${SEPARATE_GOTPLT-${PAD_GOT+${PAD_GOT1} + ${DATA_GOT+${RELRO_NOW-${SEPARATE_GOTPLT-${GOTEND ${DATA_GOT+${RELRO_NOW-${GOTPLT}}} ${DATA_NONEXEC_PLT-${DATA_PLT+${PLT_BEFORE_GOT-${PAD_PLT+${PAD_PLT0} @@ -458,6 +464,7 @@ cat EOF ${DATA_NONEXEC_PLT-${DATA_PLT+${PLT_BEFORE_GOT+${PLT
Re: fix ld -Z on powerpc
On Tue, Aug 18, 2015 at 6:22 AM, Mark Kettenis mark.kette...@xs4all.nl wrote: Date: Tue, 18 Aug 2015 05:03:19 + From: Miod Vallat m...@online.fr I spent some time today figuting out why the binutils update broke ld -Z on powerpc. Turns out to be a fairly thorny issue. The new binutils discard empty setions. As a result the .gotpad0 and .gotpad1 sections have disappeared. And a s a consequence the __got_start and __got_end symbols are now absolute symbols as the section they referenced to is no longer there. For example, an older libc has: 845: 000eeb68 0 NOTYPE GLOBAL DEFAULT 17 __got_start whereas -current has: 810: 000eeb58 0 NOTYPE GLOBAL DEFAULT ABS __got_start On powerpc, crt0.o has weak references to __got_start and __got_end. When building a binary with ld -Z, these are resolved to the absolute symbols from libc. At runtime we then use these values, relocated as if they were addresses within the binary itself, to change protections and flush the instruction cache. This is very likely to result in a segmentation fault. There is probably a linker bug here, as it doesn't make any sense for the linker to pick the address of these symbols from libc and stick it into the binary. But I'm not sure about this. And it isn't all that obvious what the fix would be. Is the bug that the symbols end up as absolute? Or is the problem that it sibsequently resolves these to the values from libc.so? Wouldn't something like that address the problem better? Unfortunately not. Using PROVIDE() makes the __got_start/end symbols disappear from shared libraries. If I use: GOTSTART=__got_start = .; I end up with the same absolute symbols as before. You really have to tie the symbols to a specific section that isn't discarded to make them end up as normal symbols. And that is difficult since we try to make __got_start/end cover multiple sections, some of which may or may not be present. I still think my diff to remove code is the way to go. As I explained, it isn't really clear which set of symbols the references in crt0.o will actually resolve to. And the secure-plt work will require changes to the code anyway to make sure we don't end up with an executable GOT after all. Would KEEP statements in a linker script be a suitable workaround? https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep --david
Re: rtfree(9) and nd6_prefix_{on,off}link
On 17/08/15(Mon) 19:24, Alexander Bluhm wrote: On Mon, Aug 17, 2015 at 07:03:55PM +0200, Martin Pieuchot wrote: On 17/08/15(Mon) 18:25, Alexander Bluhm wrote: On Mon, Aug 17, 2015 at 12:34:13PM +0200, Martin Pieuchot wrote: Ultimately my goal is to use rt_ifa_{add,del}() instead of nd6_prefix_{on,off}link() but right now I need to remove the rt-ref_cnt--. @@ -1861,26 +1856,11 @@ nd6_prefix_onlink(struct nd_prefix *pr) info.rti_info[RTAX_NETMASK] = sin6tosa(mask6); error = rtrequest1(RTM_ADD, info, RTP_CONNECTED, rt, ifp-if_rdomain); - if (error == 0) { - if (rt != NULL) /* this should be non NULL, though */ - rt_sendmsg(rt, RTM_ADD, ifp-if_rdomain); + if (error == 0 rt != NULL) { pr-ndpr_stateflags |= NDPRF_ONLINK; Here you change the check for setting ndpr_stateflags from (error == 0) to (error == 0 rt != NULL). Although I think that both checks have the same result, would it be better to use the same logic as in defrouter_addreq()? I'm changing the logic to match what's done in rt_ifa_add() but if you look at rtrequest1(RTM_ADD, ...) you'll see that rt cannot be NULL when error is 0. I think it is be better to have the same check everywhere and I don't care if it is (error != 0), (rt == NULL) or both. I also want to have the same logic everywhere, it is quite inconsistent now. I think the best would be to check only for (error == 0). Then it is clear that rtrequest1() guarantees rt != NULL. The man page rtrequest1(9) should mention this. If we agree upon this, I can make a diff to unify the caller. I agree on this, I'd love to see a diff to unify this behavior.
Re: rtfree(9) and nd6_prefix_{on,off}link
On Mon, Aug 17, 2015 at 12:34:13PM +0200, Martin Pieuchot wrote: Ultimately my goal is to use rt_ifa_{add,del}() instead of nd6_prefix_{on,off}link() but right now I need to remove the rt-ref_cnt--. This diff does that and reduce the differences between these functions. Note that nd6_prefix_onlink()'s error are always logged so I doubt we need two messages. Ok? We, mpi@ and bluhm@, both agree that checking error == 0 and rt != NULL after rtrequest1() is equivalent. We can figure out the best coding style later. OK bluhm@ Index: netinet6/nd6.h === RCS file: /cvs/src/sys/netinet6/nd6.h,v retrieving revision 1.44 diff -u -p -r1.44 nd6.h --- netinet6/nd6.h18 Jul 2015 15:05:32 - 1.44 +++ netinet6/nd6.h17 Aug 2015 10:04:04 - @@ -309,8 +309,6 @@ void prelist_remove(struct nd_prefix *); int prelist_update(struct nd_prefix *, struct nd_defrouter *, struct mbuf *); int nd6_prelist_add(struct nd_prefix *, struct nd_defrouter *, struct nd_prefix **); -int nd6_prefix_onlink(struct nd_prefix *); -int nd6_prefix_offlink(struct nd_prefix *); void pfxlist_onlink_check(void); struct nd_defrouter *defrouter_lookup(struct in6_addr *, struct ifnet *); Index: netinet6/nd6_rtr.c === RCS file: /cvs/src/sys/netinet6/nd6_rtr.c,v retrieving revision 1.113 diff -u -p -r1.113 nd6_rtr.c --- netinet6/nd6_rtr.c18 Jul 2015 15:51:17 - 1.113 +++ netinet6/nd6_rtr.c17 Aug 2015 10:04:05 - @@ -69,7 +69,8 @@ void pfxrtr_del(struct nd_pfxrouter *); struct nd_pfxrouter *find_pfxlist_reachable_router(struct nd_prefix *); void defrouter_delreq(struct nd_defrouter *); void purge_detached(struct ifnet *); - +int nd6_prefix_onlink(struct nd_prefix *); +int nd6_prefix_offlink(struct nd_prefix *); void in6_init_address_ltimes(struct nd_prefix *, struct in6_addrlifetime *); int rt6_deleteroute(struct rtentry *, void *, unsigned int); @@ -601,7 +602,7 @@ defrouter_addreq(struct nd_defrouter *ne { struct rt_addrinfo info; struct sockaddr_in6 def, mask, gate; - struct rtentry *newrt = NULL; + struct rtentry *rt = NULL; int s; int error; @@ -622,11 +623,11 @@ defrouter_addreq(struct nd_defrouter *ne info.rti_info[RTAX_NETMASK] = sin6tosa(mask); s = splsoftnet(); - error = rtrequest1(RTM_ADD, info, RTP_DEFAULT, newrt, + error = rtrequest1(RTM_ADD, info, RTP_DEFAULT, rt, new-ifp-if_rdomain); - if (newrt) { - rt_sendmsg(newrt, RTM_ADD, new-ifp-if_rdomain); - newrt-rt_refcnt--; + if (rt) { + rt_sendmsg(rt, RTM_ADD, new-ifp-if_rdomain); + rtfree(rt); } if (error == 0) new-installed = 1; @@ -1783,14 +1784,8 @@ nd6_prefix_onlink(struct nd_prefix *pr) char addr[INET6_ADDRSTRLEN]; /* sanity check */ - if ((pr-ndpr_stateflags NDPRF_ONLINK) != 0) { - nd6log((LOG_ERR, - nd6_prefix_onlink: %s/%d is already on-link\n, - inet_ntop(AF_INET6, pr-ndpr_prefix.sin6_addr, - addr, sizeof(addr)), - pr-ndpr_plen)); + if ((pr-ndpr_stateflags NDPRF_ONLINK) != 0) return (EEXIST); - } /* * Add the interface route associated with the prefix. Before @@ -1861,26 +1856,11 @@ nd6_prefix_onlink(struct nd_prefix *pr) info.rti_info[RTAX_NETMASK] = sin6tosa(mask6); error = rtrequest1(RTM_ADD, info, RTP_CONNECTED, rt, ifp-if_rdomain); - if (error == 0) { - if (rt != NULL) /* this should be non NULL, though */ - rt_sendmsg(rt, RTM_ADD, ifp-if_rdomain); + if (error == 0 rt != NULL) { pr-ndpr_stateflags |= NDPRF_ONLINK; - } else { - char gw[INET6_ADDRSTRLEN], mask[INET6_ADDRSTRLEN]; - nd6log((LOG_ERR, nd6_prefix_onlink: failed to add route for a - prefix (%s/%d) on %s, gw=%s, mask=%s, flags=%lx - errno = %d\n, - inet_ntop(AF_INET6, pr-ndpr_prefix.sin6_addr, - addr, sizeof(addr)), - pr-ndpr_plen, ifp-if_xname, - inet_ntop(AF_INET6, satosin6(ifa-ifa_addr)-sin6_addr, - gw, sizeof(gw)), - inet_ntop(AF_INET6, mask6.sin6_addr, mask, sizeof(mask)), - rtflags, error)); + rt_sendmsg(rt, RTM_ADD, ifp-if_rdomain); + rtfree(rt); } - - if (rt != NULL) - rt-rt_refcnt--; return (error); }
Re: v6 autoconf, where have my connected routes gone?
On 18/08/15(Tue) 13:05, Stuart Henderson wrote: I'm trying to add v6 to my second ISP connection on pppoe1, unlike my first ISP, this one requires autoconf and dhcpv6-pd to pick up addresses and have them routed. (They are referring to TR-187, https://www.broadband-forum.org/technical/download/TR-187.pdf - the residential gateway requirements are in section 6.1) I haven't got as far as looking at dhcpv6-pd because when I enable autoconf, as soon as it picks up the address I lose connected routes to my local /64 subnets: Which prefixes (ndp -p) and default routers (ndp -r) do you have before and after the interface picks up the address? # sysctl kern.version kern.version=OpenBSD 5.8 (GENERIC.MP) #1236: Sun Aug 16 02:31:04 MDT 2015 dera...@amd64.openbsd.org:/usr/src/sys/arch/amd64/compile/GENERIC.MP # netstat -rnfinet6|grep ^2001.*/64 2001:4b10:1002:ff::/64 fe80::225:90ff:fec0:77b4%pppoe0 U 00 - 4 pppoe0 2001:4b10:1002:cc01::/64 fe80::200:5eff:fe00:102%carp2 UC 20 - 4 carp2 2001:4b10:1002:cc03::/64 fe80::210:18ff:fe7f:1f06%vlan3 UC 10 - 4 vlan3 2001:4b10:1002:cc05::/64 fe80::210:18ff:fe7f:1f06%vlan5 UC 00 - 4 vlan5 2001:4b10:1002:cc07::/64 fe80::210:18ff:fe7f:1f06%vlan3666 UC 00 - 4 vlan3666 # ifconfig pppoe1 inet6 autoconf # netstat -rnfinet6|grep ^2001.*/64 # ifconfig pppoe1 -inet6 # ifconfig pppoe1 pppoe1: flags=208851UP,POINTOPOINT,RUNNING,SIMPLEX,MULTICAST,AUTOCONF6 mtu 1500 priority: 0 dev: em1 state: session sid: 0x93f PADI retries: 2 PADR retries: 0 time: 00:02:12 sppp: phase network authproto chap authname xx groups: pppoe egress status: active inet6 fe80::225:90ff:fec0:77b4%pppoe1 - prefixlen 64 scopeid 0x14 inet 82.68.199.142 -- 62.3.84.27 netmask 0x inet6 2a02:8011:d00e:3:225:90ff:fec0:77b4 - prefixlen 64 autoconf pltime 1799 vltime 17999 inet6 2a02:8011:d00e:3:a4f6:285a:fe8d:d1ac - prefixlen 64 autoconf autoconfprivacy pltime 1799 vltime 17999 # netstat -rnfinet6|grep ^2001.*/64 2001:4b10:1002:ff::/64 fe80::225:90ff:fec0:77b4%pppoe0 U 00 - 4 pppoe0 2001:4b10:1002:cc01::/64 fe80::200:5eff:fe00:102%carp2 UC 10 - 4 carp2 2001:4b10:1002:cc03::/64 fe80::210:18ff:fe7f:1f06%vlan3 UC 00 - 4 vlan3 2001:4b10:1002:cc05::/64 fe80::210:18ff:fe7f:1f06%vlan5 UC 00 - 4 vlan5 2001:4b10:1002:cc07::/64 fe80::210:18ff:fe7f:1f06%vlan3666 UC 00 - 4 vlan3666 Diffs of netstat -rnfinet6 (followed by full output, before+after) below. Anyone have an idea what's going on? ... $ diff -u0 before after | grep -v ^@ --- before Tue Aug 18 12:39:39 2015 +++ after Tue Aug 18 12:39:48 2015 +defaultfe80::230:88ff:fe16:5eff%pppoe1 UG 00 -56 pppoe1 -2001:4b10:1002:cc01::/64 fe80::225:90ff:fec0:77b4%vlan2 UC 20 - 4 vlan2 -2001:4b10:1002:cc01:20d:93ff:fe63:da5a 00:0d:93:63:da:5a UHLc 03 - 4 vlan2 -2001:4b10:1002:cc01:230:48ff:fe58:8640 f8:b1:56:ac:32:76 UHLc 0 664 - 4 vlan2 -2001:4b10:1002:cc03::/64 fe80::210:18ff:fe7f:1f06%vlan3 UC 10 - 4 vlan3 -2001:4b10:1002:cc03:220:4aff:fec5:5b55 00:20:4a:c5:5b:55 UHLc 0 40 - 4 vlan3 -2001:4b10:1002:cc05::/64 fe80::210:18ff:fe7f:1f06%vlan5 UC 00 - 4 vlan5 -2001:4b10:1002:cc07::/64 fe80::210:18ff:fe7f:1f06%vlan3666 UC 00 - 4 vlan3666 +2a02:8011:d00e:3:225:90ff:fec0:77b4 2a02:8011:d00e:3:225:90ff:fec0:77b4 UHl 00 - 1 lo0 +2a02:8011:d00e:3:a4f6:285a:fe8d:d1ac 2a02:8011:d00e:3:a4f6:285a:fe8d:d1ac UHl00 - 1 lo0 -fe80::fab1:56ff:feac:3276%vlan2f8:b1:56:ac:32:76 UHLc 07 - 4 vlan2 +fe80::fab1:56ff:feac:3276%vlan2f8:b1:56:ac:32:76 UHLc 08 - 4 vlan2 -fe80::220:4aff:fec5:5b55%vlan3 00:20:4a:c5:5b:55 UHLc 06 - 4 vlan3 +fe80::220:4aff:fec5:5b55%vlan3 00:20:4a:c5:5b:55 UHLc 08 - 4 vlan3 -fe80::%pppoe1/64 fe80::225:90ff:fec0:77b4%pppoe1 U 00 - 4 pppoe1 +fe80::%pppoe1/64 fe80::225:90ff:fec0:77b4%pppoe1 U 10 - 4 pppoe1 +fe80::230:88ff:fe16:5eff%pppoe1pppoe1 UHL 00 - 4 pppoe1 # cat before Routing tables
Re: v6 autoconf, where have my connected routes gone?
On 2015/08/18 14:27, Martin Pieuchot wrote: On 18/08/15(Tue) 13:05, Stuart Henderson wrote: I'm trying to add v6 to my second ISP connection on pppoe1, unlike my first ISP, this one requires autoconf and dhcpv6-pd to pick up addresses and have them routed. (They are referring to TR-187, https://www.broadband-forum.org/technical/download/TR-187.pdf - the residential gateway requirements are in section 6.1) I haven't got as far as looking at dhcpv6-pd because when I enable autoconf, as soon as it picks up the address I lose connected routes to my local /64 subnets: Which prefixes (ndp -p) and default routers (ndp -r) do you have before and after the interface picks up the address? Before: no default routers showing with ndp -r. $ ndp -p | paste - - - | sed 's/vltime=infinity, pltime=infinity, expire=Never, //' fe80::%pppoe1/64 if=pppoe1 flags=LAO ref=0 No advertising router fe80::%pppoe0/64 if=pppoe0 flags=LAO ref=0 No advertising router 2001:4b10:1002:cc01::/64 if=carp2 flags=L ref=1 No advertising router fe80::%carp2/64 if=carp2flags=LAO ref=0 No advertising router 2001:4b10:1002:cc05::/64 if=vlan5 flags=LO ref=1No advertising router fe80::%vlan5/64 if=vlan5flags=LAO ref=0 No advertising router 2001:4b10:1002:cc07::/64 if=vlan3666flags=LO ref=1No advertising router fe80::%vlan3666/64 if=vlan3666 flags=LAO ref=0 No advertising router 2001:4b10:1002:cc03::/64 if=vlan3 flags=LO ref=1No advertising router fe80::%vlan3/64 if=vlan3flags=LAO ref=0 No advertising router 2001:4b10:1002:cc01::/64 if=vlan2 flags=LO ref=1No advertising router fe80::%vlan2/64 if=vlan2flags=LAO ref=0 No advertising router fe80::%lo0/64 if=lo0flags=LAO ref=0 No advertising router ... After: $ ndp -r fe80::230:88ff:fe16:5eff%pppoe1 if=pppoe1, flags=O, pref=medium, expire=19m55s 2a02:8011:d00e:3::/64 if=pppoe1 flags=LAD vltime=18000, pltime=1800, expire=4h59m19s, ref=2 advertised by fe80::230:88ff:fe16:5eff%pppoe1 (no neighbor state) fe80::%pppoe1/64 if=pppoe1 flags=LAO ref=0 No advertising router fe80::%pppoe0/64 if=pppoe0 flags=LAO ref=0 No advertising router 2001:4b10:1002:cc01::/64 if=carp2 flags=LD ref=1No advertising router fe80::%carp2/64 if=carp2flags=LAO ref=0 No advertising router 2001:4b10:1002:cc05::/64 if=vlan5 flags=LD ref=1No advertising router fe80::%vlan5/64 if=vlan5flags=LAO ref=0 No advertising router 2001:4b10:1002:cc07::/64 if=vlan3666flags=LD ref=1No advertising router fe80::%vlan3666/64 if=vlan3666 flags=LAO ref=0 No advertising router 2001:4b10:1002:cc03::/64 if=vlan3 flags=LD ref=1No advertising router fe80::%vlan3/64 if=vlan3flags=LAO ref=0 No advertising router 2001:4b10:1002:cc01::/64 if=vlan2 flags=LD ref=1No advertising router fe80::%vlan2/64 if=vlan2flags=LAO ref=0 No advertising router fe80::%lo0/64 if=lo0flags=LAO ref=0 No advertising router [ no more unquoted text below; I've avoided trimming it to keep everything together in one mail ] # sysctl kern.version kern.version=OpenBSD 5.8 (GENERIC.MP) #1236: Sun Aug 16 02:31:04 MDT 2015 dera...@amd64.openbsd.org:/usr/src/sys/arch/amd64/compile/GENERIC.MP # netstat -rnfinet6|grep ^2001.*/64 2001:4b10:1002:ff::/64 fe80::225:90ff:fec0:77b4%pppoe0 U 00 - 4 pppoe0 2001:4b10:1002:cc01::/64 fe80::200:5eff:fe00:102%carp2 UC 20 - 4 carp2 2001:4b10:1002:cc03::/64 fe80::210:18ff:fe7f:1f06%vlan3 UC 10 - 4 vlan3 2001:4b10:1002:cc05::/64 fe80::210:18ff:fe7f:1f06%vlan5 UC 00 - 4 vlan5 2001:4b10:1002:cc07::/64 fe80::210:18ff:fe7f:1f06%vlan3666 UC 00 - 4 vlan3666 # ifconfig pppoe1 inet6 autoconf # netstat -rnfinet6|grep ^2001.*/64 # ifconfig pppoe1 -inet6 # ifconfig pppoe1 pppoe1: flags=208851UP,POINTOPOINT,RUNNING,SIMPLEX,MULTICAST,AUTOCONF6 mtu 1500 priority: 0 dev: em1 state: session sid: 0x93f PADI retries: 2 PADR retries: 0 time: 00:02:12 sppp: phase network authproto chap authname xx groups: pppoe egress status: active inet6 fe80::225:90ff:fec0:77b4%pppoe1 - prefixlen 64 scopeid 0x14 inet 82.68.199.142 -- 62.3.84.27 netmask 0x inet6 2a02:8011:d00e:3:225:90ff:fec0:77b4 - prefixlen 64 autoconf pltime 1799 vltime 17999 inet6 2a02:8011:d00e:3:a4f6:285a:fe8d:d1ac - prefixlen 64 autoconf autoconfprivacy pltime 1799 vltime 17999 # netstat -rnfinet6|grep ^2001.*/64 2001:4b10:1002:ff::/64
v6 autoconf, where have my connected routes gone?
I'm trying to add v6 to my second ISP connection on pppoe1, unlike my first ISP, this one requires autoconf and dhcpv6-pd to pick up addresses and have them routed. (They are referring to TR-187, https://www.broadband-forum.org/technical/download/TR-187.pdf - the residential gateway requirements are in section 6.1) I haven't got as far as looking at dhcpv6-pd because when I enable autoconf, as soon as it picks up the address I lose connected routes to my local /64 subnets: # sysctl kern.version kern.version=OpenBSD 5.8 (GENERIC.MP) #1236: Sun Aug 16 02:31:04 MDT 2015 dera...@amd64.openbsd.org:/usr/src/sys/arch/amd64/compile/GENERIC.MP # netstat -rnfinet6|grep ^2001.*/64 2001:4b10:1002:ff::/64 fe80::225:90ff:fec0:77b4%pppoe0 U 0 0 - 4 pppoe0 2001:4b10:1002:cc01::/64 fe80::200:5eff:fe00:102%carp2 UC 2 0 - 4 carp2 2001:4b10:1002:cc03::/64 fe80::210:18ff:fe7f:1f06%vlan3 UC 1 0 - 4 vlan3 2001:4b10:1002:cc05::/64 fe80::210:18ff:fe7f:1f06%vlan5 UC 0 0 - 4 vlan5 2001:4b10:1002:cc07::/64 fe80::210:18ff:fe7f:1f06%vlan3666 UC 00 - 4 vlan3666 # ifconfig pppoe1 inet6 autoconf # netstat -rnfinet6|grep ^2001.*/64 # ifconfig pppoe1 -inet6 # ifconfig pppoe1 pppoe1: flags=208851UP,POINTOPOINT,RUNNING,SIMPLEX,MULTICAST,AUTOCONF6 mtu 1500 priority: 0 dev: em1 state: session sid: 0x93f PADI retries: 2 PADR retries: 0 time: 00:02:12 sppp: phase network authproto chap authname xx groups: pppoe egress status: active inet6 fe80::225:90ff:fec0:77b4%pppoe1 - prefixlen 64 scopeid 0x14 inet 82.68.199.142 -- 62.3.84.27 netmask 0x inet6 2a02:8011:d00e:3:225:90ff:fec0:77b4 - prefixlen 64 autoconf pltime 1799 vltime 17999 inet6 2a02:8011:d00e:3:a4f6:285a:fe8d:d1ac - prefixlen 64 autoconf autoconfprivacy pltime 1799 vltime 17999 # netstat -rnfinet6|grep ^2001.*/64 2001:4b10:1002:ff::/64 fe80::225:90ff:fec0:77b4%pppoe0 U 0 0 - 4 pppoe0 2001:4b10:1002:cc01::/64 fe80::200:5eff:fe00:102%carp2 UC 1 0 - 4 carp2 2001:4b10:1002:cc03::/64 fe80::210:18ff:fe7f:1f06%vlan3 UC 0 0 - 4 vlan3 2001:4b10:1002:cc05::/64 fe80::210:18ff:fe7f:1f06%vlan5 UC 0 0 - 4 vlan5 2001:4b10:1002:cc07::/64 fe80::210:18ff:fe7f:1f06%vlan3666 UC 00 - 4 vlan3666 Diffs of netstat -rnfinet6 (followed by full output, before+after) below. Anyone have an idea what's going on? ... $ diff -u0 before after | grep -v ^@ --- before Tue Aug 18 12:39:39 2015 +++ after Tue Aug 18 12:39:48 2015 +defaultfe80::230:88ff:fe16:5eff%pppoe1 UG 00 -56 pppoe1 -2001:4b10:1002:cc01::/64 fe80::225:90ff:fec0:77b4%vlan2 UC 2 0 - 4 vlan2 -2001:4b10:1002:cc01:20d:93ff:fe63:da5a 00:0d:93:63:da:5a UHLc 03 - 4 vlan2 -2001:4b10:1002:cc01:230:48ff:fe58:8640 f8:b1:56:ac:32:76 UHLc 0 664 - 4 vlan2 -2001:4b10:1002:cc03::/64 fe80::210:18ff:fe7f:1f06%vlan3 UC 1 0 - 4 vlan3 -2001:4b10:1002:cc03:220:4aff:fec5:5b55 00:20:4a:c5:5b:55 UHLc 0 40 - 4 vlan3 -2001:4b10:1002:cc05::/64 fe80::210:18ff:fe7f:1f06%vlan5 UC 0 0 - 4 vlan5 -2001:4b10:1002:cc07::/64 fe80::210:18ff:fe7f:1f06%vlan3666 UC 00 - 4 vlan3666 +2a02:8011:d00e:3:225:90ff:fec0:77b4 2a02:8011:d00e:3:225:90ff:fec0:77b4 UHl 00 - 1 lo0 +2a02:8011:d00e:3:a4f6:285a:fe8d:d1ac 2a02:8011:d00e:3:a4f6:285a:fe8d:d1ac UHl 00 - 1 lo0 -fe80::fab1:56ff:feac:3276%vlan2f8:b1:56:ac:32:76 UHLc 0 7 - 4 vlan2 +fe80::fab1:56ff:feac:3276%vlan2f8:b1:56:ac:32:76 UHLc 0 8 - 4 vlan2 -fe80::220:4aff:fec5:5b55%vlan3 00:20:4a:c5:5b:55 UHLc 0 6 - 4 vlan3 +fe80::220:4aff:fec5:5b55%vlan3 00:20:4a:c5:5b:55 UHLc 0 8 - 4 vlan3 -fe80::%pppoe1/64 fe80::225:90ff:fec0:77b4%pppoe1 U 00 - 4 pppoe1 +fe80::%pppoe1/64 fe80::225:90ff:fec0:77b4%pppoe1 U 10 - 4 pppoe1 +fe80::230:88ff:fe16:5eff%pppoe1pppoe1 UHL0 0 - 4 pppoe1 # cat before Routing tables Internet6: DestinationGatewayFlags Refs Use Mtu Prio Iface ::/104 ::1UGRS 0 0 32768 8 lo0 ::/96 ::1
Re: fix ld -Z on powerpc
Date: Tue, 18 Aug 2015 06:58:43 -0400 From: David Higgs hig...@gmail.com On Tue, Aug 18, 2015 at 6:22 AM, Mark Kettenis mark.kette...@xs4all.nl wrote: Date: Tue, 18 Aug 2015 05:03:19 + From: Miod Vallat m...@online.fr I spent some time today figuting out why the binutils update broke ld -Z on powerpc. Turns out to be a fairly thorny issue. The new binutils discard empty setions. As a result the .gotpad0 and .gotpad1 sections have disappeared. And a s a consequence the __got_start and __got_end symbols are now absolute symbols as the section they referenced to is no longer there. For example, an older libc has: 845: 000eeb68 0 NOTYPE GLOBAL DEFAULT 17 __got_start whereas -current has: 810: 000eeb58 0 NOTYPE GLOBAL DEFAULT ABS __got_start On powerpc, crt0.o has weak references to __got_start and __got_end. When building a binary with ld -Z, these are resolved to the absolute symbols from libc. At runtime we then use these values, relocated as if they were addresses within the binary itself, to change protections and flush the instruction cache. This is very likely to result in a segmentation fault. There is probably a linker bug here, as it doesn't make any sense for the linker to pick the address of these symbols from libc and stick it into the binary. But I'm not sure about this. And it isn't all that obvious what the fix would be. Is the bug that the symbols end up as absolute? Or is the problem that it sibsequently resolves these to the values from libc.so? Wouldn't something like that address the problem better? Unfortunately not. Using PROVIDE() makes the __got_start/end symbols disappear from shared libraries. If I use: GOTSTART=__got_start = .; I end up with the same absolute symbols as before. You really have to tie the symbols to a specific section that isn't discarded to make them end up as normal symbols. And that is difficult since we try to make __got_start/end cover multiple sections, some of which may or may not be present. I still think my diff to remove code is the way to go. As I explained, it isn't really clear which set of symbols the references in crt0.o will actually resolve to. And the secure-plt work will require changes to the code anyway to make sure we don't end up with an executable GOT after all. Would KEEP statements in a linker script be a suitable workaround? https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep No that doesn't work, presumably because .gotpad0 and .gotpad1 aren't really input sections.
[patch] ports.7 macro fixes
Hi, This is in the same vein as [1], which replaced the usage of `Ar' with `Cm' where applicable. Besides that, I unindented line 134 because `-offset indent' is already being used, but that's it. Regards, Michael [1]: https://marc.info/?l=openbsd-techm=143778713715847w=2 Index: src/share/man/man7/ports.7 === RCS file: /cvs/src/share/man/man7/ports.7,v retrieving revision 1.102 diff -u -p -r1.102 ports.7 --- src/share/man/man7/ports.7 30 Jul 2015 08:03:50 - 1.102 +++ src/share/man/man7/ports.7 18 Aug 2015 16:47:40 - @@ -80,19 +80,19 @@ The ports master Makefile, normally loca below) offers a few useful targets. .Bl -tag -width configure -.It Ar index +.It Cm index rebuild the ports complete index, .Pa /usr/ports/INDEX -.It Ar pkglocatedb +.It Cm pkglocatedb build a .Xr pkg_mklocatedb 1 database file and place it in .Pa ${PORTSDIR}/packages/${MACHINE_ARCH}/ftp , for use by .Xr locate 1 , -.It Ar print-index +.It Cm print-index display the contents of the index in a user-friendly way, -.It Ar search +.It Cm search invoked with a key, e.g., .Ic make search key=foo , retrieve information relevant to a given port (obsolescent). @@ -128,10 +128,10 @@ port maintained by a given person. .El .Pp For instance, to invoke -.Ar clean +.Cm clean on all ports in the x11 category, one can say: .Bd -literal -offset indent - $ make category=x11 clean +$ make category=x11 clean .Ed .Pp The index search is done by a perl script, so all regular expressions from @@ -201,17 +201,17 @@ with the target that failed to and proceed. .Pp Some targets that do this are -.Ar all , build , checksum , clean , -.Ar configure , extract , fake , -.Ar fetch , install , distclean , -.Ar deinstall , reinstall , package , prepare , -.Ar link-categories , unlink-categories , -.Ar describe , show , regress , -.Ar lib-depends-check , homepage-links , manpages-check , -.Ar license-check , all-dir-depends , build-dir-depends , -.Ar run-dir-depends +.Cm all , build , checksum , clean , +.Cm configure , extract , fake , +.Cm fetch , install , distclean , +.Cm deinstall , reinstall , package , prepare , +.Cm link-categories , unlink-categories , +.Cm describe , show , regress , +.Cm lib-depends-check , homepage-links , manpages-check , +.Cm license-check , all-dir-depends , build-dir-depends , +.Cm run-dir-depends and -.Ar readmes . +.Cm readmes . .Pp Target names starting with .Sq _ @@ -221,26 +221,26 @@ should not be invoked directly, and are In the following list, each target will run the preceding targets in order automatically. That is, -.Ar build +.Cm build will be run .Pq if necessary by -.Ar install , +.Cm install , and so on all the way to -.Ar fetch . +.Cm fetch . In typical use, one will only run -.Ar install +.Cm install explicitly (as normal user, with .Ev SUDO defined in .Pa /etc/mk.conf ) , or -.Ar build +.Cm build (as user), then -.Ar install +.Cm install (as root). .Bl -tag -width configure -.It Ar fetch +.It Cm fetch Fetch all of the files needed to build this port from the site(s) listed in .Ev MASTER_SITES . @@ -253,7 +253,7 @@ Use with option .Fl F to quickly fetch distfiles for a subtree. -.It Ar checksum +.It Cm checksum Verify that the fetched distfile matches the one the port was tested against. Defining .Ev NO_CHECKSUM @@ -270,7 +270,7 @@ $ make checksum REFETCH=true .Ed .Pp will try to get a set of distfiles that match the recorded checksum. -.It Ar prepare +.It Cm prepare Install any build dependencies of the current port. Defining @@ -278,63 +278,63 @@ Defining to .Dv Yes will skip this step. -.It Ar extract +.It Cm extract Expand the distfile into a work directory. -.It Ar patch +.It Cm patch Apply any patches that are necessary for the port. -.It Ar configure +.It Cm configure Configure the port. Some ports will ask questions during this stage. See .Ev INTERACTIVE and .Ev BATCH . -.It Ar build +.It Cm build Build the port. This is the same as calling the -.Ar all +.Cm all target. -.It Ar fake +.It Cm fake Pretend to install the port under a subdirectory of the work directory. -.It Ar package +.It Cm package Create a binary package from the fake installation. The package is a .tgz file that can be used to install the port with .Xr pkg_add 1 . -.It Ar install +.It Cm install Install the resulting package. .El .Pp The following targets are not run during the normal install process. .Bl -tag -width fetch-list -.It Ar print-build-depends , print-run-depends +.It Cm print-build-depends , print-run-depends Print an ordered list of all the compile and run dependencies. -.It Ar clean +.It Cm clean Remove the expanded source code. This does not recurse to dependencies unless .Ev CLEANDEPENDS is defined to .Dv Yes . -.It Ar distclean +.It Cm distclean Remove the port's distfile(s). This does not recurse to dependencies. -.It Ar regress +.It Cm regress
Re: fix ld -Z on powerpc
Date: Tue, 18 Aug 2015 05:03:19 + From: Miod Vallat m...@online.fr I spent some time today figuting out why the binutils update broke ld -Z on powerpc. Turns out to be a fairly thorny issue. The new binutils discard empty setions. As a result the .gotpad0 and .gotpad1 sections have disappeared. And a s a consequence the __got_start and __got_end symbols are now absolute symbols as the section they referenced to is no longer there. For example, an older libc has: 845: 000eeb68 0 NOTYPE GLOBAL DEFAULT 17 __got_start whereas -current has: 810: 000eeb58 0 NOTYPE GLOBAL DEFAULT ABS __got_start On powerpc, crt0.o has weak references to __got_start and __got_end. When building a binary with ld -Z, these are resolved to the absolute symbols from libc. At runtime we then use these values, relocated as if they were addresses within the binary itself, to change protections and flush the instruction cache. This is very likely to result in a segmentation fault. There is probably a linker bug here, as it doesn't make any sense for the linker to pick the address of these symbols from libc and stick it into the binary. But I'm not sure about this. And it isn't all that obvious what the fix would be. Is the bug that the symbols end up as absolute? Or is the problem that it sibsequently resolves these to the values from libc.so? Wouldn't something like that address the problem better? Unfortunately not. Using PROVIDE() makes the __got_start/end symbols disappear from shared libraries. If I use: GOTSTART=__got_start = .; I end up with the same absolute symbols as before. You really have to tie the symbols to a specific section that isn't discarded to make them end up as normal symbols. And that is difficult since we try to make __got_start/end cover multiple sections, some of which may or may not be present. I still think my diff to remove code is the way to go. As I explained, it isn't really clear which set of symbols the references in crt0.o will actually resolve to. And the secure-plt work will require changes to the code anyway to make sure we don't end up with an executable GOT after all. This sucks. I'd love to see a libelf-based linker appear eventually, but to be a drop-in replacement for GNU ld, it needs linker script support, and then the nightmare start. That said, I only have two things to say: 1. going the opposite way of strict memory permissions, even in a diminishing use case (true static binaries) does not fit with the ``no compromises'' OpenBSD way of doing things. 2. I believe that some light smarts could be added to bfd to make .ctors and .dtors read-only when linking a true static binary, which would alleviate crt0 (.got being already RO in that case). So I will come with a binutils diff shortly, so that you will be able to put your crt0 diff in.
Re: netcat non blocking socket
On Mon, Aug 17, 2015 at 08:26:21PM +0200, Alexander Bluhm wrote: When running my pf regression tests, I triggered netcat hanging in write(2). This is bit strange as poll(2) should check that the socket is writeable. Disregard the netstat diff, fix poll(2) in the kernel instead. bluhm Index: netinet/tcp_usrreq.c === RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_usrreq.c,v retrieving revision 1.126 diff -u -p -r1.126 tcp_usrreq.c --- netinet/tcp_usrreq.c15 Jul 2015 22:16:42 - 1.126 +++ netinet/tcp_usrreq.c18 Aug 2015 19:57:48 - @@ -980,6 +980,14 @@ tcp_update_sndspace(struct tcpcb *tp) nmax = MIN(sb_max, so-so_snd.sb_wat + tp-snd_max - tp-snd_una); + /* a writable socket must be preserved because of poll(2) semantics */ + if (sbspace(so-so_snd) = so-so_snd.sb_lowat) { + if (nmax so-so_snd.sb_cc + so-so_snd.sb_lowat) + nmax = so-so_snd.sb_cc + so-so_snd.sb_lowat; + if (nmax * 2 so-so_snd.sb_mbcnt + so-so_snd.sb_lowat) + nmax = (so-so_snd.sb_mbcnt+so-so_snd.sb_lowat+1) / 2; + } + /* round to MSS boundary */ nmax = roundup(nmax, tp-t_maxseg); @@ -1011,6 +1019,11 @@ tcp_update_rcvspace(struct tcpcb *tp) nmax = MIN(sb_max, so-so_rcv.sb_hiwat + tcp_autorcvbuf_inc); } + + /* a readable socket must be preserved because of poll(2) semantics */ + if (so-so_rcv.sb_cc = so-so_rcv.sb_lowat + nmax so-so_snd.sb_lowat) + nmax = so-so_snd.sb_lowat; if (nmax == so-so_rcv.sb_hiwat) return;
Re: v6 autoconf, where have my connected routes gone?
On 18/08/15(Tue) 14:00, Stuart Henderson wrote: On 2015/08/18 14:27, Martin Pieuchot wrote: On 18/08/15(Tue) 13:05, Stuart Henderson wrote: I'm trying to add v6 to my second ISP connection on pppoe1, unlike my first ISP, this one requires autoconf and dhcpv6-pd to pick up addresses and have them routed. (They are referring to TR-187, https://www.broadband-forum.org/technical/download/TR-187.pdf - the residential gateway requirements are in section 6.1) I haven't got as far as looking at dhcpv6-pd because when I enable autoconf, as soon as it picks up the address I lose connected routes to my local /64 subnets: Which prefixes (ndp -p) and default routers (ndp -r) do you have before and after the interface picks up the address? Before: no default routers showing with ndp -r. $ ndp -p | paste - - - | sed 's/vltime=infinity, pltime=infinity, expire=Never, //' fe80::%pppoe1/64 if=pppoe1flags=LAO ref=0 No advertising router fe80::%pppoe0/64 if=pppoe0flags=LAO ref=0 No advertising router 2001:4b10:1002:cc01::/64 if=carp2 flags=L ref=1 No advertising router fe80::%carp2/64 if=carp2 flags=LAO ref=0 No advertising router 2001:4b10:1002:cc05::/64 if=vlan5 flags=LO ref=1No advertising router fe80::%vlan5/64 if=vlan5 flags=LAO ref=0 No advertising router 2001:4b10:1002:cc07::/64 if=vlan3666flags=LO ref=1No advertising router fe80::%vlan3666/64 if=vlan3666flags=LAO ref=0 No advertising router 2001:4b10:1002:cc03::/64 if=vlan3 flags=LO ref=1No advertising router fe80::%vlan3/64 if=vlan3 flags=LAO ref=0 No advertising router 2001:4b10:1002:cc01::/64 if=vlan2 flags=LO ref=1No advertising router fe80::%vlan2/64 if=vlan2 flags=LAO ref=0 No advertising router fe80::%lo0/64 if=lo0 flags=LAO ref=0 No advertising router ... After: $ ndp -r fe80::230:88ff:fe16:5eff%pppoe1 if=pppoe1, flags=O, pref=medium, expire=19m55s 2a02:8011:d00e:3::/64 if=pppoe1 flags=LAD vltime=18000, pltime=1800, expire=4h59m19s, ref=2 advertised by fe80::230:88ff:fe16:5eff%pppoe1 (no neighbor state) fe80::%pppoe1/64 if=pppoe1flags=LAO ref=0 No advertising router fe80::%pppoe0/64 if=pppoe0flags=LAO ref=0 No advertising router 2001:4b10:1002:cc01::/64 if=carp2 flags=LD ref=1No advertising router fe80::%carp2/64 if=carp2 flags=LAO ref=0 No advertising router 2001:4b10:1002:cc05::/64 if=vlan5 flags=LD ref=1No advertising router fe80::%vlan5/64 if=vlan5 flags=LAO ref=0 No advertising router 2001:4b10:1002:cc07::/64 if=vlan3666flags=LD ref=1No advertising router fe80::%vlan3666/64 if=vlan3666flags=LAO ref=0 No advertising router 2001:4b10:1002:cc03::/64 if=vlan3 flags=LD ref=1No advertising router fe80::%vlan3/64 if=vlan3 flags=LAO ref=0 No advertising router 2001:4b10:1002:cc01::/64 if=vlan2 flags=LD ref=1No advertising router fe80::%vlan2/64 if=vlan2 flags=LAO ref=0 No advertising router fe80::%lo0/64 if=lo0 flags=LAO ref=0 No advertising router See how all your prefix suddenly became detached D? That's a limitation of pfxlist_onlink_check() which does not make a difference between prefixes added to the global prefix list via an advertisement or via manual configuration. I'll see if it's possible to split the prefix lists in such way that the RS/RA code only mess with its own states.
acpi pci config space access fix
Here is a new version of the diff to make sure we respect the access size of pci config space reads and writes in acpi code that was backed out. This version adds some code to make sure those reads and writes are properly aligned. This should prevent the panic that some people saw with the previous diff. Apparently some AML writers think it makes perfect sense to have a region that is only 16-bit aligned but demand 32-bit access to it. Giovanni, can you try this on that bigio machine? Index: acpi.c === RCS file: /cvs/src/sys/dev/acpi/acpi.c,v retrieving revision 1.291 diff -u -p -r1.291 acpi.c --- acpi.c 4 Aug 2015 15:21:59 - 1.291 +++ acpi.c 18 Aug 2015 21:11:05 - @@ -218,6 +218,50 @@ struct acpi_softc *acpi_softc; #define acpi_bus_space_map _bus_space_map #define acpi_bus_space_unmap _bus_space_unmap +uint8_t +acpi_pci_conf_read_1(pci_chipset_tag_t pc, pcitag_t tag, int reg) +{ + uint32_t val = pci_conf_read(pc, tag, reg ~0x3); + return (val ((reg 0x3) 3)); +} + +uint16_t +acpi_pci_conf_read_2(pci_chipset_tag_t pc, pcitag_t tag, int reg) +{ + uint32_t val = pci_conf_read(pc, tag, reg ~0x2); + return (val ((reg 0x2) 3)); +} + +uint32_t +acpi_pci_conf_read_4(pci_chipset_tag_t pc, pcitag_t tag, int reg) +{ + return pci_conf_read(pc, tag, reg); +} + +void +acpi_pci_conf_write_1(pci_chipset_tag_t pc, pcitag_t tag, int reg, uint8_t val) +{ + uint32_t tmp = pci_conf_read(pc, tag, reg ~0x3); + tmp = ~(0xff ((reg 0x3) 3)); + tmp |= (val ((reg 0x3) 3)); + pci_conf_write(pc, tag, reg ~0x3, tmp); +} + +void +acpi_pci_conf_write_2(pci_chipset_tag_t pc, pcitag_t tag, int reg, uint16_t val) +{ + uint32_t tmp = pci_conf_read(pc, tag, reg ~0x2); + tmp = ~(0x ((reg 0x2) 3)); + tmp |= (val ((reg 0x2) 3)); + pci_conf_write(pc, tag, reg ~0x2, tmp); +} + +void +acpi_pci_conf_write_4(pci_chipset_tag_t pc, pcitag_t tag, int reg, uint32_t val) +{ + pci_conf_write(pc, tag, reg, val); +} + int acpi_gasio(struct acpi_softc *sc, int iodir, int iospace, uint64_t address, int access_size, int len, void *buffer) @@ -227,7 +271,7 @@ acpi_gasio(struct acpi_softc *sc, int io bus_space_handle_t ioh; pci_chipset_tag_t pc; pcitag_t tag; - int reg, idx, ival, sval; + int reg, idx; dnprintf(50, gasio: %.2x 0x%.8llx %s\n, iospace, address, (iodir == ACPI_IOWRITE) ? write : read); @@ -326,19 +370,47 @@ acpi_gasio(struct acpi_softc *sc, int io ACPI_PCI_BUS(address), ACPI_PCI_DEV(address), ACPI_PCI_FN(address)); - /* XXX: This is ugly. read-modify-write does a byte at a time */ reg = ACPI_PCI_REG(address); - for (idx = reg; idx reg+len; idx++) { - ival = pci_conf_read(pc, tag, idx ~0x3); + for (idx = 0; idx len; idx += access_size) { if (iodir == ACPI_IOREAD) { - *pb = ival (8 * (idx 0x3)); + switch (access_size) { + case 1: + *(uint8_t *)(pb + idx) = + acpi_pci_conf_read_1(pc, tag, reg + idx); + break; + case 2: + *(uint16_t *)(pb + idx) = + acpi_pci_conf_read_2(pc, tag, reg + idx); + break; + case 4: + *(uint32_t *)(pb + idx) = + acpi_pci_conf_read_4(pc, tag, reg + idx); + break; + default: + printf(%s: rdcfg: invalid size %d\n, + DEVNAME(sc), access_size); + return (-1); + } } else { - sval = *pb; - ival = ~(0xFF (8* (idx 0x3))); - ival |= sval (8* (idx 0x3)); - pci_conf_write(pc, tag, idx ~0x3, ival); + switch (access_size) { + case 1: + acpi_pci_conf_write_1(pc, tag, reg + idx, + *(uint8_t *)(pb + idx)); + break; + case 2: + acpi_pci_conf_write_2(pc, tag, reg + idx, + *(uint16_t *)(pb + idx)); +