From e3027f41d0120b4278cca462f397b6619dcd9ac5 Mon Sep 17 00:00:00 2001 From: Apple Date: Sat, 9 Aug 2003 00:51:56 +0000 Subject: [PATCH] xnu-124.13.tar.gz --- bsd/conf/version.variant | 2 +- bsd/hfs/hfs_vnodeops.c | 105 ++++++++++-------- bsd/kern/sys_socket.c | 9 +- bsd/kern/uipc_socket.c | 55 +++++---- bsd/kern/uipc_socket2.c | 22 ++-- bsd/kern/uipc_syscalls.c | 4 +- bsd/netat/aurp_aurpd.c | 6 +- bsd/netccitt/pk_subr.c | 3 +- bsd/netiso/tp_subr.c | 2 +- bsd/sys/mbuf.h | 4 +- bsd/sys/select.h | 3 +- bsd/sys/socketvar.h | 6 +- .../drvAppleADBDevices/AppleADBKeyboard.cpp | 8 +- .../IONDRVSupport/IONDRVFramebuffer.cpp | 20 ++++ iokit/IOKit/IOMemoryDescriptor.h | 12 ++ iokit/IOKit/ppc/IOSharedLockImp.h | 23 +++- iokit/Kernel/IOMemoryDescriptor.cpp | 74 +++++++++++- iokit/KernelConfigTables.cpp | 30 ++--- iokit/conf/version.variant | 2 +- libkern/conf/version.variant | 2 +- libsa/conf/version.variant | 2 +- osfmk/conf/kernelversion.variant | 2 +- osfmk/conf/version.variant | 2 +- osfmk/device/iokit_rpc.c | 18 ++- osfmk/vm/vm_fault.c | 31 +++--- osfmk/vm/vm_map.c | 25 ++++- pexpert/conf/version.variant | 2 +- 27 files changed, 333 insertions(+), 141 deletions(-) diff --git a/bsd/conf/version.variant b/bsd/conf/version.variant index 00750edc0..7f8f011eb 100644 --- a/bsd/conf/version.variant +++ b/bsd/conf/version.variant @@ -1 +1 @@ -3 +7 diff --git a/bsd/hfs/hfs_vnodeops.c b/bsd/hfs/hfs_vnodeops.c index 14a784ee9..e451aaab2 100644 --- a/bsd/hfs/hfs_vnodeops.c +++ b/bsd/hfs/hfs_vnodeops.c @@ -1314,13 +1314,45 @@ struct proc *a_p; goto ErrorExit; }; - /* do we have permission to change the dates? */ -// if (alist->commonattr & (ATTR_CMN_CRTIME | ATTR_CMN_MODTIME | ATTR_CMN_CHGTIME | ATTR_CMN_ACCTIME | ATTR_CMN_BKUPTIME)) { - if (alist->commonattr & (ATTR_CMN_CHGTIME | ATTR_CMN_ACCTIME)) { - if ((error = hfs_owner_rights(vp, cred, p, true)) != 0) { - goto ErrorExit; - }; - }; + /* + * If we are going to change the times: + * 1. do we have permission to change the dates? + * 2. Is there another fork? If so then clear any flags associated with the times + */ + if (alist->commonattr & (ATTR_CMN_MODTIME | ATTR_CMN_CHGTIME | ATTR_CMN_ACCTIME)) { + if (alist->commonattr & (ATTR_CMN_CHGTIME | ATTR_CMN_ACCTIME)) { + if ((error = hfs_owner_rights(vp, cred, p, true)) != 0) + goto ErrorExit; + } + + /* If there is another fork, clear the flags */ + if ((hp->h_meta->h_usecount > 1) && (H_FORKTYPE(hp) == kDataFork)) { + struct vnode *sib_vp = NULL; + struct hfsnode *nhp; + + /* Loop through all siblings, skipping ourselves */ + simple_lock(&hp->h_meta->h_siblinglock); + CIRCLEQ_FOREACH(nhp, &hp->h_meta->h_siblinghead, h_sibling) { + if (nhp == hp) /* skip ourselves */ + continue; + sib_vp = HTOV(nhp); + } + simple_unlock(&hp->h_meta->h_siblinglock); + + /* The only error that vget returns is when the vnode is going away, so ignore the vnode */ + if (sib_vp && vget(sib_vp, LK_EXCLUSIVE | LK_RETRY, p) == 0) { + if (VTOH(sib_vp)->h_nodeflags & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) { + if (alist->commonattr & ATTR_CMN_MODTIME) + VTOH(sib_vp)->h_nodeflags &= ~IN_UPDATE; + if (alist->commonattr & ATTR_CMN_CHGTIME) + VTOH(sib_vp)->h_nodeflags &= ~IN_CHANGE; + if (alist->commonattr & ATTR_CMN_ACCTIME) + VTOH(sib_vp)->h_nodeflags &= ~IN_ACCESS; + } + vput(sib_vp); + } /* vget() */ + } /* h_use_count > 1 */ + } /* save these in case hfs_chown() or hfs_chmod() fail */ saved_uid = hp->h_meta->h_uid; @@ -1363,59 +1395,40 @@ struct proc *a_p; if ((error = hfs_chflags(vp, flags, cred, p))) goto ErrorExit; }; - + + + /* Update Catalog Tree */ if (alist->volattr == 0) { error = MacToVFSError( UpdateCatalogNode(HTOVCB(hp), pid, filename, H_HINT(hp), &catInfo.nodeData)); } - if (alist->volattr & ATTR_VOL_NAME) { - ExtendedVCB *vcb = VTOVCB(vp); - int namelen = strlen(vcb->vcbVN); - + /* Volume Rename */ + if (alist->volattr & ATTR_VOL_NAME) { + ExtendedVCB *vcb = VTOVCB(vp); + int namelen = strlen(vcb->vcbVN); + if (vcb->vcbVN[0] == 0) { /* - Ignore attempts to rename a volume to a zero-length name: - restore the original name from the metadata. + * Ignore attempts to rename a volume to a zero-length name: + * restore the original name from the metadata. */ copystr(H_NAME(hp), vcb->vcbVN, sizeof(vcb->vcbVN), NULL); } else { - error = MoveRenameCatalogNode(vcb, kRootParID, H_NAME(hp), H_HINT(hp), kRootParID, vcb->vcbVN, &H_HINT(hp)); + error = MoveRenameCatalogNode(vcb, kRootParID, H_NAME(hp), H_HINT(hp), + kRootParID, vcb->vcbVN, &H_HINT(hp)); if (error) { - VCB_LOCK(vcb); - copystr(H_NAME(hp), vcb->vcbVN, sizeof(vcb->vcbVN), NULL); /* Restore the old name in the VCB */ - vcb->vcbFlags |= 0xFF00; // Mark the VCB dirty - VCB_UNLOCK(vcb); - goto ErrorExit; + VCB_LOCK(vcb); + copystr(H_NAME(hp), vcb->vcbVN, sizeof(vcb->vcbVN), NULL); /* Restore the old name in the VCB */ + vcb->vcbFlags |= 0xFF00; // Mark the VCB dirty + VCB_UNLOCK(vcb); + goto ErrorExit; }; - + hfs_set_metaname(vcb->vcbVN, hp->h_meta, HTOHFS(hp)); hp->h_nodeflags |= IN_CHANGE; -#if 0 - /* if hfs wrapper exists, update its name too */ - if (vcb->vcbSigWord == kHFSPlusSigWord && vcb->vcbAlBlSt != 0) { - HFSMasterDirectoryBlock *mdb; - struct buf *bp = NULL; - int size = kMDBSize; /* 512 */ - int volnamelen = MIN(sizeof(Str27), namelen); - - if ( bread(VTOHFS(vp)->hfs_devvp, IOBLKNOFORBLK(kMasterDirectoryBlock, size), - IOBYTECCNTFORBLK(kMasterDirectoryBlock, kMDBSize, size), NOCRED, &bp) == 0) { - - mdb = (HFSMasterDirectoryBlock *)((char *)bp->b_data + IOBYTEOFFSETFORBLK(kMasterDirectoryBlock, size)); - if (SWAP_BE16 (mdb->drSigWord) == kHFSSigWord) { - /* Convert the string to MacRoman, ignoring any errors, */ - (void) utf8_to_hfs(vcb, volnamelen, vcb->vcbVN, Str31 mdb->drVN) - bawrite(bp); - bp = NULL; - } - } - - if (bp) brelse(bp); - } -#endif - }; /* vcb->vcbVN[0] == 0 ... else ... */ - }; /* alist->volattr & ATTR_VOL_NAME */ + } /* vcb->vcbVN[0] == 0 ... else ... */ + } /* alist->volattr & ATTR_VOL_NAME */ ErrorExit: /* unlock catalog b-tree */ diff --git a/bsd/kern/sys_socket.c b/bsd/kern/sys_socket.c index 3a14f6c95..f4637871d 100644 --- a/bsd/kern/sys_socket.c +++ b/bsd/kern/sys_socket.c @@ -317,33 +317,36 @@ soo_select(fp, which, p) switch (which) { case FREAD: + so->so_rcv.sb_sel.si_flags |= SI_SBSEL; if (soreadable(so)) { splx(s); retnum = 1; + so->so_rcv.sb_sel.si_flags &= ~SI_SBSEL; goto done; } selrecord(p, &so->so_rcv.sb_sel); - so->so_rcv.sb_flags |= SB_SEL; break; case FWRITE: + so->so_snd.sb_sel.si_flags |= SI_SBSEL; if (sowriteable(so)) { splx(s); retnum = 1; + so->so_snd.sb_sel.si_flags &= ~SI_SBSEL; goto done; } selrecord(p, &so->so_snd.sb_sel); - so->so_snd.sb_flags |= SB_SEL; break; case 0: + so->so_rcv.sb_sel.si_flags |= SI_SBSEL; if (so->so_oobmark || (so->so_state & SS_RCVATMARK)) { splx(s); retnum = 1; + so->so_rcv.sb_sel.si_flags &= ~SI_SBSEL; goto done; } selrecord(p, &so->so_rcv.sb_sel); - so->so_rcv.sb_flags |= SB_SEL; break; } splx(s); diff --git a/bsd/kern/uipc_socket.c b/bsd/kern/uipc_socket.c index 669d34874..56eb901ee 100644 --- a/bsd/kern/uipc_socket.c +++ b/bsd/kern/uipc_socket.c @@ -461,7 +461,7 @@ solisten(so, backlog) splx(s); return (error); } - if (so->so_comp.tqh_first == NULL) + if (TAILQ_EMPTY(&so->so_comp)) so->so_options |= SO_ACCEPTCONN; if (backlog < 0 || backlog > somaxconn) backlog = somaxconn; @@ -505,15 +505,21 @@ sofree(so) if (so->so_pcb || (so->so_state & SS_NOFDREF) == 0) return; - if (head != NULL) { - if (so->so_state & SS_INCOMP) { - TAILQ_REMOVE(&head->so_incomp, so, so_list); - head->so_incqlen--; - } else if (so->so_state & SS_COMP) { - TAILQ_REMOVE(&head->so_comp, so, so_list); - } else { - panic("sofree: not queued"); - } + if (head != NULL) { + if (so->so_state & SS_INCOMP) { + TAILQ_REMOVE(&head->so_incomp, so, so_list); + head->so_incqlen--; + } else if (so->so_state & SS_COMP) { + /* + * We must not decommission a socket that's + * on the accept(2) queue. If we do, then + * accept(2) may hang after select(2) indicated + * that the listening socket was ready. + */ + return; + } else { + panic("sofree: not queued"); + } head->so_qlen--; so->so_state &= ~(SS_INCOMP|SS_COMP); so->so_head = NULL; @@ -556,14 +562,21 @@ soclose(so) if (so->so_options & SO_ACCEPTCONN) { struct socket *sp, *sonext; - for (sp = so->so_incomp.tqh_first; sp != NULL; sp = sonext) { - sonext = sp->so_list.tqe_next; - (void) soabort(sp); - } - for (sp = so->so_comp.tqh_first; sp != NULL; sp = sonext) { - sonext = sp->so_list.tqe_next; - (void) soabort(sp); - } + sp = TAILQ_FIRST(&so->so_incomp); + for (; sp != NULL; sp = sonext) { + sonext = TAILQ_NEXT(sp, so_list); + (void) soabort(sp); + } + for (sp = TAILQ_FIRST(&so->so_comp); sp != NULL; sp = sonext) { + sonext = TAILQ_NEXT(sp, so_list); + /* Dequeue from so_comp since sofree() won't do it */ + TAILQ_REMOVE(&so->so_comp, sp, so_list); + so->so_qlen--; + sp->so_state &= ~SS_COMP; + sp->so_head = NULL; + (void) soabort(sp); + } + } if (so->so_pcb == 0) goto discard; @@ -592,7 +605,7 @@ drop: error = error2; } discard: - if (so->so_state & SS_NOFDREF) + if (so->so_pcb && so->so_state & SS_NOFDREF) panic("soclose: NOFDREF"); so->so_state |= SS_NOFDREF; so->so_proto->pr_domain->dom_refs--; @@ -1955,12 +1968,12 @@ sopoll(struct socket *so, int events, struct ucred *cred) if (revents == 0) { if (events & (POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND)) { selrecord(p, &so->so_rcv.sb_sel); - so->so_rcv.sb_flags |= SB_SEL; + so->so_rcv.sb_sel.si_flags |= SI_SBSEL; } if (events & (POLLOUT | POLLWRNORM)) { selrecord(p, &so->so_snd.sb_sel); - so->so_snd.sb_flags |= SB_SEL; + so->so_snd.sb_sel.si_flags |= SI_SBSEL; } } diff --git a/bsd/kern/uipc_socket2.c b/bsd/kern/uipc_socket2.c index 0644a63d4..2b61d07fd 100644 --- a/bsd/kern/uipc_socket2.c +++ b/bsd/kern/uipc_socket2.c @@ -88,7 +88,7 @@ char netcon[] = "netcon"; * called during processing of connect() call, * resulting in an eventual call to soisconnected() if/when the * connection is established. When the connection is torn down - * soisdisconnecting() is called during processing of disconnect() call, + * soisdisconnecting() is called during processing of disconnect() call, * and soisdisconnected() is called when the connection to the peer * is totally severed. The semantics of these routines are such that * connectionless protocols can call soisconnected() and soisdisconnected() @@ -96,16 +96,16 @@ char netcon[] = "netcon"; * takes no time. * * From the passive side, a socket is created with - * two queues of sockets: so_q0 for connections in progress - * and so_q for connections already made and awaiting user acceptance. - * As a protocol is preparing incoming connections, it creates a socket - * structure queued on so_q0 by calling sonewconn(). When the connection + * two queues of sockets: so_incomp for connections in progress + * and so_comp for connections already made and awaiting user acceptance. + * As a protocol is preparing incoming connections, it creates a socket + * structure queued on so_incomp by calling sonewconn(). When the connection * is established, soisconnected() is called, and transfers the - * socket structure to so_q, making it available to accept(). - * - * If a socket is closed with sockets on either - * so_q0 or so_q, these sockets are dropped. + * socket structure to so_comp, making it available to accept(). * + * If a socket is closed with sockets on either + * so_incomp or so_comp, these sockets are dropped. + * * If higher level protocols are implemented in * the kernel, the wakeups done here will sometimes * cause software-interrupt process scheduling. @@ -408,11 +408,11 @@ sowakeup(so, sb) struct proc *p = current_proc(); - sb->sb_flags &= ~SB_SEL; thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL); + sb->sb_sel.si_flags &= ~SI_SBSEL; selwakeup(&sb->sb_sel); - thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL); + thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL); if (sb->sb_flags & SB_WAIT) { sb->sb_flags &= ~SB_WAIT; diff --git a/bsd/kern/uipc_syscalls.c b/bsd/kern/uipc_syscalls.c index f27ada463..d6482c0a2 100644 --- a/bsd/kern/uipc_syscalls.c +++ b/bsd/kern/uipc_syscalls.c @@ -283,7 +283,7 @@ accept1(p, uap, retval, compat) splx(s); return (EWOULDBLOCK); } - while (head->so_comp.tqh_first == NULL && head->so_error == 0) { + while (TAILQ_EMPTY(&head->so_comp) && head->so_error == 0) { if (head->so_state & SS_CANTRCVMORE) { head->so_error = ECONNABORTED; break; @@ -310,7 +310,7 @@ accept1(p, uap, retval, compat) * block allowing another process to accept the connection * instead. */ - so = head->so_comp.tqh_first; + so = TAILQ_FIRST(&head->so_comp); TAILQ_REMOVE(&head->so_comp, so, so_list); head->so_qlen--; diff --git a/bsd/netat/aurp_aurpd.c b/bsd/netat/aurp_aurpd.c index 17673ee99..8cc764bda 100644 --- a/bsd/netat/aurp_aurpd.c +++ b/bsd/netat/aurp_aurpd.c @@ -165,8 +165,10 @@ aurpd_start() so->so_upcall = aurp_wakeup; so->so_upcallarg = (caddr_t)AE_UDPIP; /* Yuck */ so->so_state |= SS_NBIO; - so->so_rcv.sb_flags |=(SB_SEL|SB_NOINTR); - so->so_snd.sb_flags |=(SB_SEL|SB_NOINTR); + so->so_rcv.sb_flags |=SB_NOINTR; + so->so_rcv.sb_sel.si_flags |=SI_SBSEL; + so->so_snd.sb_flags |=SB_NOINTR; + so->so_snd.sb_sel.si_flags |=SI_SBSEL; out: sbunlock(&so->so_snd); diff --git a/bsd/netccitt/pk_subr.c b/bsd/netccitt/pk_subr.c index cb6cec959..c45bdd7f4 100644 --- a/bsd/netccitt/pk_subr.c +++ b/bsd/netccitt/pk_subr.c @@ -940,7 +940,8 @@ unsigned pr; lcp -> lcd_window_condition = FALSE; if (so && ((so -> so_snd.sb_flags & SB_WAIT) || - (so -> so_snd.sb_flags & SB_NOTIFY))) + (so -> so_snd.sb_flags & SB_NOTIFY)) || + (so->so_snd.sb_sel.si_flags & SI_SBSEL)) sowwakeup (so); return (PACKET_OK); diff --git a/bsd/netiso/tp_subr.c b/bsd/netiso/tp_subr.c index 409f5dbf7..da59945ce 100644 --- a/bsd/netiso/tp_subr.c +++ b/bsd/netiso/tp_subr.c @@ -449,7 +449,7 @@ tp_sbdrop(tpcb, seq) printf("tp_sbdroping %d pkts %d bytes on %x at 0x%x\n", oldi, oldcc - sb->sb_cc, tpcb, seq); ENDDEBUG - if (sb->sb_flags & SB_NOTIFY) + if ((sb->sb_flags & SB_NOTIFY) || (sb->sb_sel.si_flags & SI_SBSEL)) sowwakeup(tpcb->tp_sock); return (oldcc - sb->sb_cc); } diff --git a/bsd/sys/mbuf.h b/bsd/sys/mbuf.h index 7b051386d..ebd9ac240 100644 --- a/bsd/sys/mbuf.h +++ b/bsd/sys/mbuf.h @@ -260,8 +260,8 @@ decl_simple_lock_data(, mbuf_slock); * and internal data. */ -#ifdef DIAGNOSE -#define MCHECK(m) if ((m)->m_type != MT_FREE) panic("mget") +#if 1 +#define MCHECK(m) if ((m)->m_type != MT_FREE) panic("mget MCHECK: m_type=%x m=%x", m->m_type, m) #else #define MCHECK(m) #endif diff --git a/bsd/sys/select.h b/bsd/sys/select.h index 10cf8b78c..615d5789e 100644 --- a/bsd/sys/select.h +++ b/bsd/sys/select.h @@ -65,7 +65,8 @@ struct selinfo { void *si_thread; /* thread to be notified */ short si_flags; /* see below */ }; -#define SI_COLL 0x0001 /* collision occurred */ +#define SI_COLL 0x0001 /* collision occurred */ +#define SI_SBSEL 0x0002 /* select socket buffer wanted replaces SB_SEL */ #ifdef KERNEL struct proc; diff --git a/bsd/sys/socketvar.h b/bsd/sys/socketvar.h index d9e2b7be5..c8293aeae 100644 --- a/bsd/sys/socketvar.h +++ b/bsd/sys/socketvar.h @@ -143,9 +143,9 @@ struct socket { #define SB_LOCK 0x01 /* lock on data queue */ #define SB_WANT 0x02 /* someone is waiting to lock */ #define SB_WAIT 0x04 /* someone is waiting for data/space */ -#define SB_SEL 0x08 /* someone is selecting */ +#define SB_SEL_XXX 0x08 /* Don't use. replaced by SI_SBSEL in selinfo */ #define SB_ASYNC 0x10 /* ASYNC I/O, need signals */ -#define SB_NOTIFY (SB_WAIT|SB_SEL|SB_ASYNC) +#define SB_NOTIFY (SB_WAIT|SB_ASYNC) #define SB_UPCALL 0x20 /* someone wants an upcall */ #define SB_NOINTR 0x40 /* operations not interruptible */ #define SB_RECV 0x8000 /* this is rcv sb */ @@ -226,7 +226,7 @@ struct xsocket { /* * Do we need to notify the other side when I/O is possible? */ -#define sb_notify(sb) (((sb)->sb_flags & (SB_WAIT|SB_SEL|SB_ASYNC|SB_UPCALL)) != 0) +#define sb_notify(sb) (((sb)->sb_flags & (SB_WAIT|SB_ASYNC|SB_UPCALL)) != 0 || ((sb)->sb_sel.si_flags & SI_SBSEL) != 0) /* * How much space is there in a socket buffer (so->so_snd or so->so_rcv)? diff --git a/iokit/Drivers/hidsystem/drvAppleADBDevices/AppleADBKeyboard.cpp b/iokit/Drivers/hidsystem/drvAppleADBDevices/AppleADBKeyboard.cpp index 6d8d7cd32..d5026c422 100644 --- a/iokit/Drivers/hidsystem/drvAppleADBDevices/AppleADBKeyboard.cpp +++ b/iokit/Drivers/hidsystem/drvAppleADBDevices/AppleADBKeyboard.cpp @@ -140,7 +140,9 @@ void AppleADBKeyboard::setAlphaLockFeedback ( bool to ) else turnLEDon |= ADBKS_LED_CAPSLOCK; - thread_call_func(asyncSetLEDFunc, (thread_call_param_t)this, true); + if ( ! isInactive() ) { + thread_call_func(asyncSetLEDFunc, (thread_call_param_t)this, true); + } } void AppleADBKeyboard::setNumLockFeedback ( bool to ) @@ -150,7 +152,9 @@ void AppleADBKeyboard::setNumLockFeedback ( bool to ) else turnLEDon |= ADBKS_LED_NUMLOCK; - thread_call_func(asyncSetLEDFunc, (thread_call_param_t)this, true); + if ( ! isInactive() ) { + thread_call_func(asyncSetLEDFunc, (thread_call_param_t)this, true); + } } diff --git a/iokit/Families/IONDRVSupport/IONDRVFramebuffer.cpp b/iokit/Families/IONDRVSupport/IONDRVFramebuffer.cpp index 18119f96d..e6adf5dbc 100644 --- a/iokit/Families/IONDRVSupport/IONDRVFramebuffer.cpp +++ b/iokit/Families/IONDRVSupport/IONDRVFramebuffer.cpp @@ -2050,6 +2050,16 @@ IOReturn IONDRVFramebuffer::setPowerState( unsigned long powerStateOrdinal, sleepInfo.powerFlags = 0; sleepInfo.powerReserved1 = 0; sleepInfo.powerReserved2 = 0; + +#if 1 + if( newState == kHardwareSleep) { + IOMemoryDescriptor * vram; + if( (vram = getVRAMRange())) { + vram->redirect( kernel_task, true ); + vram->release(); + } + } +#endif ignore_zero_fault( true ); boolean_t ints = ml_set_interrupts_enabled( false ); @@ -2059,6 +2069,16 @@ IOReturn IONDRVFramebuffer::setPowerState( unsigned long powerStateOrdinal, ml_set_interrupts_enabled( ints ); ignore_zero_fault( false ); +#if 1 + if( newState == kHardwareWake) { + IOMemoryDescriptor * vram; + if( (vram = getVRAMRange())) { + vram->redirect( kernel_task, false ); + vram->release(); + } + } +#endif + if( powerStateOrdinal) { powerState = powerStateOrdinal; if( kAVPowerOn == newState) { diff --git a/iokit/IOKit/IOMemoryDescriptor.h b/iokit/IOKit/IOMemoryDescriptor.h index bb3b5d54e..2c33b3001 100644 --- a/iokit/IOKit/IOMemoryDescriptor.h +++ b/iokit/IOKit/IOMemoryDescriptor.h @@ -394,6 +394,11 @@ public: IOVirtualAddress mapAddress, IOOptionBits options = 0 ); + // Following methods are private implementation + + // make virtual + IOReturn redirect( task_t safeTask, bool redirect ); + protected: virtual IOMemoryMap * makeMapping( IOMemoryDescriptor * owner, @@ -498,6 +503,10 @@ public: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +// The following classes are private implementation of IOMemoryDescriptor - they +// should not be reference directly, just through the public API's in the +// IOMemoryDescriptor class. + enum { kIOMemoryRequiresWire = 0x00000001 }; @@ -675,6 +684,9 @@ public: virtual IOReturn complete(IODirection forDirection = kIODirectionNone); + // make virtual + IOReturn redirect( task_t safeTask, bool redirect ); + protected: virtual IOMemoryMap * makeMapping( IOMemoryDescriptor * owner, diff --git a/iokit/IOKit/ppc/IOSharedLockImp.h b/iokit/IOKit/ppc/IOSharedLockImp.h index f320f9d33..030fd4913 100644 --- a/iokit/IOKit/ppc/IOSharedLockImp.h +++ b/iokit/IOKit/ppc/IOSharedLockImp.h @@ -49,14 +49,35 @@ #define _IOKIT_IOSHAREDLOCKIMP_H #include +#ifdef KERNEL +#undef END +#include +#endif -// 'Till we're building in kernel .macro DISABLE_PREEMPTION #ifdef KERNEL + stwu r1,-(FM_SIZE)(r1) + mflr r0 + stw r3,FM_ARG0(r1) + stw r0,(FM_SIZE+FM_LR_SAVE)(r1) + bl EXT(_disable_preemption) + lwz r3,FM_ARG0(r1) + lwz r1,0(r1) + lwz r0,FM_LR_SAVE(r1) + mtlr r0 #endif .endmacro .macro ENABLE_PREEMPTION #ifdef KERNEL + stwu r1,-(FM_SIZE)(r1) + mflr r0 + stw r3,FM_ARG0(r1) + stw r0,(FM_SIZE+FM_LR_SAVE)(r1) + bl EXT(_enable_preemption) + lwz r3,FM_ARG0(r1) + lwz r1,0(r1) + lwz r0,FM_LR_SAVE(r1) + mtlr r0 #endif .endmacro diff --git a/iokit/Kernel/IOMemoryDescriptor.cpp b/iokit/Kernel/IOMemoryDescriptor.cpp index 129b53f23..dc0ad9b50 100644 --- a/iokit/Kernel/IOMemoryDescriptor.cpp +++ b/iokit/Kernel/IOMemoryDescriptor.cpp @@ -787,7 +787,7 @@ IOReturn IOGeneralMemoryDescriptor::prepare( if(forDirection == kIODirectionNone) forDirection = _direction; - vm_prot_t access = VM_PROT_DEFAULT; // Could be cleverer using direction + vm_prot_t access = VM_PROT_DEFAULT; // Could be cleverer using direction // // Check user read/write access to the data buffer. @@ -1055,6 +1055,7 @@ extern "C" { // osfmk/device/iokit_rpc.c extern kern_return_t IOMapPages( vm_map_t map, vm_offset_t va, vm_offset_t pa, vm_size_t length, unsigned int mapFlags); +extern kern_return_t IOUnmapPages(vm_map_t map, vm_offset_t va, vm_size_t length); }; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ @@ -1122,6 +1123,9 @@ public: IOOptionBits options, IOByteCount offset, IOByteCount length ); + + IOReturn redirect( + task_t intoTask, bool redirect ); }; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ @@ -1204,7 +1208,8 @@ bool _IOMemoryMap::init( options, offset, length )); if( !ok) { logical = 0; - _memory->release(); + memory->release(); + memory = 0; vm_map_deallocate(addressMap); addressMap = 0; } @@ -1328,6 +1333,71 @@ IOReturn IOMemoryDescriptor::doUnmap( return( err ); } +IOReturn IOMemoryDescriptor::redirect( task_t safeTask, bool redirect ) +{ + IOReturn err; + _IOMemoryMap * mapping = 0; + OSIterator * iter; + + LOCK; + + do { + if( (iter = OSCollectionIterator::withCollection( _mappings))) { + while( (mapping = (_IOMemoryMap *) iter->getNextObject())) + mapping->redirect( safeTask, redirect ); + + iter->release(); + } + } while( false ); + + UNLOCK; + + // temporary binary compatibility + IOSubMemoryDescriptor * subMem; + if( (subMem = OSDynamicCast( IOSubMemoryDescriptor, this))) + err = subMem->redirect( safeTask, redirect ); + else + err = kIOReturnSuccess; + + return( err ); +} + +IOReturn IOSubMemoryDescriptor::redirect( task_t safeTask, bool redirect ) +{ +// temporary binary compatibility IOMemoryDescriptor::redirect( safeTask, redirect ); + return( _parent->redirect( safeTask, redirect )); +} + +IOReturn _IOMemoryMap::redirect( task_t safeTask, bool redirect ) +{ + IOReturn err = kIOReturnSuccess; + + if( superMap) { +// err = ((_IOMemoryMap *)superMap)->redirect( safeTask, redirect ); + } else { + + LOCK; + if( logical && addressMap + && (get_task_map( safeTask) != addressMap) + && (0 == (options & kIOMapStatic))) { + + IOUnmapPages( addressMap, logical, length ); + if( !redirect) { + err = vm_deallocate( addressMap, logical, length ); + err = memory->doMap( addressMap, &logical, + (options & ~kIOMapAnywhere) /*| kIOMapReserve*/ ); + } else + err = kIOReturnSuccess; +#ifdef DEBUG + IOLog("IOMemoryMap::redirect(%d, %x) %x from %lx\n", redirect, err, logical, addressMap); +#endif + } + UNLOCK; + } + + return( err ); +} + IOReturn _IOMemoryMap::unmap( void ) { IOReturn err; diff --git a/iokit/KernelConfigTables.cpp b/iokit/KernelConfigTables.cpp index f64c800af..c3ff58157 100644 --- a/iokit/KernelConfigTables.cpp +++ b/iokit/KernelConfigTables.cpp @@ -28,21 +28,21 @@ */ const char * gIOKernelKmods = "{ - 'com.apple.kernel' = '1.3.3'; - 'com.apple.kernel.bsd' = '1.0.3'; - 'com.apple.kernel.iokit' = '1.0.3'; - 'com.apple.kernel.libkern' = '1.0.3'; - 'com.apple.kernel.mach' = '1.0.3'; - 'com.apple.iokit.IOADBFamily' = '1.0.3'; - 'com.apple.iokit.IOCDStorageFamily' = '1.0.3'; - 'com.apple.iokit.IODVDStorageFamily' = '1.0.3'; - 'com.apple.iokit.IOGraphicsFamily' = '1.0.3'; - 'com.apple.iokit.IOHIDSystem' = '1.0.3'; - 'com.apple.iokit.IONDRVSupport' = '1.0.3'; - 'com.apple.iokit.IONetworkingFamily' = '1.0.3'; - 'com.apple.iokit.IOPCIFamily' = '1.0.3'; - 'com.apple.iokit.IOStorageFamily' = '1.0.3'; - 'com.apple.iokit.IOSystemManagementFamily' = '1.0.3'; + 'com.apple.kernel' = '1.3.7'; + 'com.apple.kernel.bsd' = '1.0.7'; + 'com.apple.kernel.iokit' = '1.0.7'; + 'com.apple.kernel.libkern' = '1.0.7'; + 'com.apple.kernel.mach' = '1.0.7'; + 'com.apple.iokit.IOADBFamily' = '1.0.7'; + 'com.apple.iokit.IOCDStorageFamily' = '1.0.7'; + 'com.apple.iokit.IODVDStorageFamily' = '1.0.7'; + 'com.apple.iokit.IOGraphicsFamily' = '1.0.7'; + 'com.apple.iokit.IOHIDSystem' = '1.0.7'; + 'com.apple.iokit.IONDRVSupport' = '1.0.7'; + 'com.apple.iokit.IONetworkingFamily' = '1.0.7'; + 'com.apple.iokit.IOPCIFamily' = '1.0.7'; + 'com.apple.iokit.IOStorageFamily' = '1.0.7'; + 'com.apple.iokit.IOSystemManagementFamily' = '1.0.7'; }"; diff --git a/iokit/conf/version.variant b/iokit/conf/version.variant index 00750edc0..7f8f011eb 100644 --- a/iokit/conf/version.variant +++ b/iokit/conf/version.variant @@ -1 +1 @@ -3 +7 diff --git a/libkern/conf/version.variant b/libkern/conf/version.variant index 00750edc0..7f8f011eb 100644 --- a/libkern/conf/version.variant +++ b/libkern/conf/version.variant @@ -1 +1 @@ -3 +7 diff --git a/libsa/conf/version.variant b/libsa/conf/version.variant index 00750edc0..7f8f011eb 100644 --- a/libsa/conf/version.variant +++ b/libsa/conf/version.variant @@ -1 +1 @@ -3 +7 diff --git a/osfmk/conf/kernelversion.variant b/osfmk/conf/kernelversion.variant index 00750edc0..7f8f011eb 100644 --- a/osfmk/conf/kernelversion.variant +++ b/osfmk/conf/kernelversion.variant @@ -1 +1 @@ -3 +7 diff --git a/osfmk/conf/version.variant b/osfmk/conf/version.variant index 00750edc0..7f8f011eb 100644 --- a/osfmk/conf/version.variant +++ b/osfmk/conf/version.variant @@ -1 +1 @@ -3 +7 diff --git a/osfmk/device/iokit_rpc.c b/osfmk/device/iokit_rpc.c index 637047f7e..7bc5041d4 100644 --- a/osfmk/device/iokit_rpc.c +++ b/osfmk/device/iokit_rpc.c @@ -312,7 +312,7 @@ iokit_no_senders( mach_no_senders_notification_t * notification ) if( (IKOT_IOKIT_OBJECT == type) || (IKOT_IOKIT_CONNECT == type)) iokit_add_reference( obj ); - else + else obj = NULL; } ip_unlock(port); @@ -395,6 +395,22 @@ kern_return_t IOMapPages(vm_map_t map, vm_offset_t va, vm_offset_t pa, return( KERN_SUCCESS ); } +kern_return_t IOUnmapPages(vm_map_t map, vm_offset_t va, vm_size_t length) +{ + pmap_t pmap = map->pmap; + vm_size_t off; + boolean_t b; + +#if __ppc__ + b = mapping_remove(pmap, va); +#else + pmap_remove(pmap, va, va + length); + b = TRUE; +#endif + + return( b ? KERN_SUCCESS : KERN_INVALID_ADDRESS ); +} + void IOGetTime( mach_timespec_t * clock_time); void IOGetTime( mach_timespec_t * clock_time) { diff --git a/osfmk/vm/vm_fault.c b/osfmk/vm/vm_fault.c index 77ec5f18c..e94ac06f4 100644 --- a/osfmk/vm/vm_fault.c +++ b/osfmk/vm/vm_fault.c @@ -3154,13 +3154,15 @@ vm_fault_copy( * zero-fill the page in dst_object. */ src_page = VM_PAGE_NULL; + result_page = VM_PAGE_NULL; } else { vm_object_lock(src_object); src_page = vm_page_lookup(src_object, trunc_page_64(src_offset)); - if (src_page == dst_page) + if (src_page == dst_page) { src_prot = dst_prot; - else { + result_page = VM_PAGE_NULL; + } else { src_prot = VM_PROT_READ; vm_object_paging_begin(src_object); @@ -3205,18 +3207,17 @@ vm_fault_copy( return(KERN_MEMORY_ERROR); } - src_page = result_page; assert((src_top_page == VM_PAGE_NULL) == - (src_page->object == src_object)); + (result_page->object == src_object)); } assert ((src_prot & VM_PROT_READ) != VM_PROT_NONE); - vm_object_unlock(src_page->object); + vm_object_unlock(result_page->object); } if (!vm_map_verify(dst_map, dst_version)) { - if (src_page != VM_PAGE_NULL && src_page != dst_page) - vm_fault_copy_cleanup(src_page, src_top_page); + if (result_page != VM_PAGE_NULL && src_page != dst_page) + vm_fault_copy_cleanup(result_page, src_top_page); vm_fault_copy_dst_cleanup(dst_page); break; } @@ -3226,8 +3227,8 @@ vm_fault_copy( if (dst_page->object->copy != old_copy_object) { vm_object_unlock(dst_page->object); vm_map_verify_done(dst_map, dst_version); - if (src_page != VM_PAGE_NULL && src_page != dst_page) - vm_fault_copy_cleanup(src_page, src_top_page); + if (result_page != VM_PAGE_NULL && src_page != dst_page) + vm_fault_copy_cleanup(result_page, src_top_page); vm_fault_copy_dst_cleanup(dst_page); break; } @@ -3257,11 +3258,11 @@ vm_fault_copy( part_size = amount_left; } - if (src_page == VM_PAGE_NULL) { + if (result_page == VM_PAGE_NULL) { vm_page_part_zero_fill(dst_page, dst_po, part_size); } else { - vm_page_part_copy(src_page, src_po, + vm_page_part_copy(result_page, src_po, dst_page, dst_po, part_size); if(!dst_page->dirty){ vm_object_lock(dst_object); @@ -3273,10 +3274,10 @@ vm_fault_copy( } else { part_size = PAGE_SIZE; - if (src_page == VM_PAGE_NULL) + if (result_page == VM_PAGE_NULL) vm_page_zero_fill(dst_page); else{ - vm_page_copy(src_page, dst_page); + vm_page_copy(result_page, dst_page); if(!dst_page->dirty){ vm_object_lock(dst_object); dst_page->dirty = TRUE; @@ -3292,8 +3293,8 @@ vm_fault_copy( vm_map_verify_done(dst_map, dst_version); - if (src_page != VM_PAGE_NULL && src_page != dst_page) - vm_fault_copy_cleanup(src_page, src_top_page); + if (result_page != VM_PAGE_NULL && src_page != dst_page) + vm_fault_copy_cleanup(result_page, src_top_page); vm_fault_copy_dst_cleanup(dst_page); amount_left -= part_size; diff --git a/osfmk/vm/vm_map.c b/osfmk/vm/vm_map.c index bfb9a05d9..0e1cf4a48 100644 --- a/osfmk/vm/vm_map.c +++ b/osfmk/vm/vm_map.c @@ -6030,16 +6030,31 @@ RestartCopy: if (tmp_entry->is_shared || tmp_entry->object.vm_object->true_share || map_share) { - /* dec ref gained in copy_quickly */ - vm_object_lock(src_object); - src_object->ref_count--; - vm_object_res_deallocate(src_object); - vm_object_unlock(src_object); + vm_map_unlock(src_map); new_entry->object.vm_object = vm_object_copy_delayed( src_object, src_offset, src_size); + /* dec ref gained in copy_quickly */ + vm_object_lock(src_object); + src_object->ref_count--; + vm_object_res_deallocate(src_object); + vm_object_unlock(src_object); + vm_map_lock(src_map); + /* + * it turns out that we have + * finished our copy. No matter + * what the state of the map + * we will lock it again here + * knowing that if there is + * additional data to copy + * it will be checked at + * the top of the loop + * + * Don't do timestamp check + */ + } else { vm_object_pmap_protect( src_object, diff --git a/pexpert/conf/version.variant b/pexpert/conf/version.variant index 00750edc0..7f8f011eb 100644 --- a/pexpert/conf/version.variant +++ b/pexpert/conf/version.variant @@ -1 +1 @@ -3 +7 -- 2.45.2