From: Apple Date: Fri, 8 Aug 2003 23:41:13 +0000 (+0000) Subject: xnu-124.1.tar.gz X-Git-Tag: mac-os-x-1001^0 X-Git-Url: https://git.saurik.com/apple/xnu.git/commitdiff_plain/150bd0745008d57c273e65929515dd6bbe568d83 xnu-124.1.tar.gz --- diff --git a/bsd/hfs/hfs_lookup.c b/bsd/hfs/hfs_lookup.c index 8ade827fc..d627217ca 100644 --- a/bsd/hfs/hfs_lookup.c +++ b/bsd/hfs/hfs_lookup.c @@ -569,9 +569,12 @@ hfs_lookup(ap) /* * Insert name in cache if wanted. * Names with composed chars are not put into the name cache. + * Resource forks are not entered in the name cache. This + * avoids deadlocks. */ if ((cnp->cn_flags & MAKEENTRY) - && (cnp->cn_namelen == catInfo.nodeData.cnm_length)) { + && (cnp->cn_namelen == catInfo.nodeData.cnm_length) + && ((H_FORKTYPE(VTOH(target_vp))) != kRsrcFork)) { /* * XXX SER - Might be good idea to bcopy(catInfo.nodeData.fsspec.name, cnp->cn_nameptr) * to "normalize" the name cache. This will avoid polluting the name cache with diff --git a/iokit/Families/IONDRVSupport/IONDRVFramebuffer.cpp b/iokit/Families/IONDRVSupport/IONDRVFramebuffer.cpp index 2fe80f342..472e54d9e 100644 --- a/iokit/Families/IONDRVSupport/IONDRVFramebuffer.cpp +++ b/iokit/Families/IONDRVSupport/IONDRVFramebuffer.cpp @@ -1506,6 +1506,158 @@ UInt32 IONDRVFramebuffer::getConnectionCount( void ) return 1; } +/* + File: DDCPowerOnOffUtils.c +*/ + +enum{ + kVCPSendSize = 8, + kVCPReplySize = 64, + kI2CDisplayWriteAddress = 0x6E, + kI2CDisplayReadAddress = 0x6F, + // Messed up specification says checksum should be calculated with ACCESS.bus value of 50. + kI2CDisplayReadHostCheckSumAddress = 0x50, + // Messed up specification says checksum should be calculated with ACCESS.bus value of 50. + kI2CDisplayReadHostAddress = 0x51, + + kI2CVCPGetCode = 0x01, + kI2CVCPGetLength = 0x82, + kI2CVCPGetMessageSize = 0x05, + + kI2CVCPReplyLength = 0x88, + kI2CNullReplyLength = 0x80, + kI2CNullReplyCheckSum = 0xBE, + + kI2CVCPSetCode = 0x03, + kI2CVCPSetLength = 0x84, + kI2CVCPReplyCode = 0x02, + + kDDCPowerOn = 0x01, + kDDCPowerOff = 0x04 +}; +enum { + kBasicI2CCommTransactionsMask = ( (1<>8) & 0xff) ? false : true ); + err = kIOReturnSuccess; break; @@ -1668,6 +1821,40 @@ bool IONDRVFramebuffer::hasDDCConnect( IOIndex connectIndex ) == kNeedFlags ); } +// I2C first year for Apple displays. +// Apple monitors older than this (and Manta) +// are never called with I2C commands +enum { + kFirstAppleI2CYear = 1999, + kAppleVESAVendorID = 0x0610 +}; + +struct EDID { + UInt8 header[8]; + UInt8 vendorProduct[4]; + UInt8 serialNumber[4]; + UInt8 weekOfManufacture; + UInt8 yearOfManufacture; + UInt8 version; + UInt8 revision; + UInt8 displayParams[5]; + UInt8 colorCharacteristics[10]; + UInt8 establishedTimings[3]; + UInt16 standardTimings[8]; + UInt8 descriptors[4][18]; + UInt8 extension; + UInt8 checksum; +}; + +static bool IsApplePowerBlock(UInt8 * theBlock) +{ + return( theBlock && + 0x00000000 == *(UInt32 *)&theBlock[0] && + 0x00 == theBlock[4] && + 0x06 == theBlock[5] && + 0x10 == theBlock[6] ); +} + IOReturn IONDRVFramebuffer::getDDCBlock( IOIndex /* connectIndex */, UInt32 blockNumber, IOSelect blockType, @@ -1693,7 +1880,32 @@ IOReturn IONDRVFramebuffer::getDDCBlock( IOIndex /* connectIndex */, actualLength = kDDCBlockSize; bcopy( ddcRec.ddcBlockData, data, actualLength); *length = actualLength; + + if( (1 == blockNumber) && (kIODDCBlockTypeEDID == blockType) + && (actualLength >= sizeof( EDID))) do { + + EDID * edid; + UInt32 vendor; + UInt32 product; + + edid = (EDID *) data; + vendor = (edid->vendorProduct[0] << 8) | edid->vendorProduct[1]; + product = (edid->vendorProduct[3] << 8) | edid->vendorProduct[2]; + if( kAppleVESAVendorID == vendor) { + if( (0x01F4 == product) || (0x9D02 == product)) + continue; + if( edid->yearOfManufacture && ((edid->yearOfManufacture + 1990) < kFirstAppleI2CYear)) + continue; + } + shouldDoI2CPower = (IsApplePowerBlock( &edid->descriptors[1][0]) + || IsApplePowerBlock( &edid->descriptors[2][0]) + || IsApplePowerBlock( &edid->descriptors[3][0])); + + } while( false ); } + + IOLog("%s: i2cPower %d\n", getName(), shouldDoI2CPower); + return( err); } diff --git a/iokit/Families/IOSCSICDDrive/IOSCSICDDrive.cpp b/iokit/Families/IOSCSICDDrive/IOSCSICDDrive.cpp index 2c02c8df6..52691d032 100644 --- a/iokit/Families/IOSCSICDDrive/IOSCSICDDrive.cpp +++ b/iokit/Families/IOSCSICDDrive/IOSCSICDDrive.cpp @@ -579,6 +579,7 @@ IOSCSICDDrive::readTOC(IOMemoryDescriptor *buffer) req->setCDB( &scsiCDB ); req->setPointers(cx->senseDataDesc, 255, false, true); + buffer->retain(); /* bump the retain count */ cx->memory = buffer; req->setPointers( cx->memory, cx->memory->getLength(), false ); diff --git a/iokit/IOKit/ndrvsupport/IOMacOSVideo.h b/iokit/IOKit/ndrvsupport/IOMacOSVideo.h index 978c4e0fc..e18339ca5 100644 --- a/iokit/IOKit/ndrvsupport/IOMacOSVideo.h +++ b/iokit/IOKit/ndrvsupport/IOMacOSVideo.h @@ -752,7 +752,10 @@ enum { kVideoDDCciReplyType = 2 /* DDC/ci message (with imbedded length)*/ }; - +// VDCommunicationRec.csCommFlags and VDCommunicationInfoRec.csSupportedCommFlags +enum { + kVideoReplyMicroSecDelayMask = (1<<0) /* If set, the driver should delay csMinReplyDelay micro seconds between send and receive*/ +}; struct VDResolutionInfoRec { @@ -1171,8 +1174,8 @@ enum { struct VDCommunicationRec { SInt32 csBusID; /* kVideoDefaultBus for single headed cards.*/ - UInt32 csReserved0; /* Always zero*/ - UInt32 csReserved1; /* Always zero*/ + UInt32 csCommFlags; /* Always zero*/ + UInt32 csMinReplyDelay; /* Minimum delay between send and reply transactions (units depend on csCommFlags)*/ UInt32 csReserved2; /* Always zero*/ UInt32 csSendAddress; /* Usually I2C address (eg 0x6E)*/ @@ -1201,7 +1204,7 @@ struct VDCommunicationInfoRec { SInt32 csMaxBus; /* Max bus (usually kVideoDefaultBus). Used to probe additional busses*/ UInt32 csSupportedTypes; /* Bit field for first 32 supported transaction types. Eg. 0x07 => support for kVideoNoTransactionType, kVideoSimpleI2CType and kVideoDDCciReplyType.*/ - UInt32 csReserved1; /* Always zero*/ + UInt32 csSupportedCommFlags; /* Return the flags csCommFlags understood by this driver. */ UInt32 csReserved2; /* Always zero*/ UInt32 csReserved3; /* Always zero*/ diff --git a/iokit/IOKit/ndrvsupport/IONDRVFramebuffer.h b/iokit/IOKit/ndrvsupport/IONDRVFramebuffer.h index 846c3eedc..d81e8f29a 100644 --- a/iokit/IOKit/ndrvsupport/IONDRVFramebuffer.h +++ b/iokit/IOKit/ndrvsupport/IONDRVFramebuffer.h @@ -91,8 +91,10 @@ protected: struct _VSLService * vslServices; UInt32 accessFlags; + UInt8 shouldDoI2CPower; - UInt32 __reserved[32]; + UInt8 __reservedB[3]; + UInt32 __reservedA[31]; private: OSMetaClassDeclareReservedUnused(IONDRVFramebuffer, 0); @@ -151,6 +153,7 @@ private: virtual void getCurrentConfiguration( void ); static const IOTVector * _undefinedSymbolHandler( void * self, const char * libraryName, const char * symbolName ); + void displayI2CPower( bool enable ); public: virtual IOReturn doControl( UInt32 code, void * params ); diff --git a/osfmk/ppc/cache.s b/osfmk/ppc/cache.s index d21ffeed8..c5253d2ef 100644 --- a/osfmk/ppc/cache.s +++ b/osfmk/ppc/cache.s @@ -200,7 +200,6 @@ ENTRY(invalidate_dcache, TAG_NO_FRAME_USED) .L_invalidate_dcache_invalidate_loop: subic r4, r4, CACHE_LINE_SIZE dcbi r3, r4 - dcbi r3, r4 bdnz .L_invalidate_dcache_invalidate_loop .L_invalidate_dcache_done: @@ -216,7 +215,6 @@ ENTRY(invalidate_dcache, TAG_NO_FRAME_USED) .L_invalidate_dcache_one_line: xor r4,r4,r4 dcbi 0,r3 - dcbi 0,r3 b .L_invalidate_dcache_done /* @@ -260,21 +258,15 @@ ENTRY(invalidate_icache, TAG_NO_FRAME_USED) .L_invalidate_icache_invalidate_loop: subic r4, r4, CACHE_LINE_SIZE icbi r3, r4 - icbi r3, r4 bdnz .L_invalidate_icache_invalidate_loop .L_invalidate_icache_done: - /* Sync restore msr if it was modified */ - cmpwi r5, 0 sync /* make sure invalidates have completed */ - beq+ 0f mtmsr r6 /* Restore original translations */ isync /* Ensure data translations are on */ -0: blr .L_invalidate_icache_one_line: xor r4,r4,r4 icbi 0,r3 - icbi 0,r3 b .L_invalidate_icache_done diff --git a/osfmk/ppc/hw_vm.s b/osfmk/ppc/hw_vm.s index f525675f6..c0e8c75c8 100644 --- a/osfmk/ppc/hw_vm.s +++ b/osfmk/ppc/hw_vm.s @@ -574,6 +574,7 @@ tlbhang1: lwarx r5,0,r12 /* Get the TLBIE lock */ eieio /* Make sure that the tlbie happens first */ tlbsync /* wait for everyone to catch up */ + isync its603a: sync /* Make sure of it all */ stw r11,0(r12) /* Clear the tlbie lock */ @@ -798,6 +799,7 @@ tlbhangp: lwarx r11,0,r12 /* Get the TLBIE lock */ eieio /* Make sure that the tlbie happens first */ tlbsync /* wait for everyone to catch up */ + isync its603p: stw r11,0(r12) /* Clear the lock */ srw r5,r5,r8 /* Make a "free slot" mask */ @@ -974,6 +976,7 @@ tlbhangpv: lwarx r11,0,r12 /* Get the TLBIE lock */ eieio /* Make sure that the tlbie happens first */ tlbsync /* wait for everyone to catch up */ + isync its603pv: stw r11,0(r12) /* Clear the lock */ srw r5,r5,r8 /* Make a "free slot" mask */ @@ -1148,6 +1151,7 @@ tlbhangav: lwarx r11,0,r12 /* Get the TLBIE lock */ eieio /* Make sure that the tlbie happens first */ tlbsync /* wait for everyone to catch up */ + isync its603av: stw r11,0(r12) /* Clear the lock */ srw r5,r5,r8 /* Make a "free slot" mask */ @@ -1431,6 +1435,7 @@ tlbhangco: lwarx r11,0,r12 /* Get the TLBIE lock */ eieio /* Make sure that the tlbie happens first */ tlbsync /* wait for everyone to catch up */ + isync its603co: stw r11,0(r12) /* Clear the lock */ srw r5,r5,r8 /* Make a "free slot" mask */ @@ -1667,6 +1672,7 @@ htrtlbhang: lwarx r11,0,r12 ; Get the TLBIE lock eieio ; Make sure that the tlbie happens first tlbsync ; wait for everyone to catch up + isync htr603: stw r11,0(r12) ; Clear the lock srw r5,r5,r8 ; Make a "free slot" mask @@ -2273,6 +2279,7 @@ tlbhang: lwarx r5,0,r9 /* Get the TLBIE lock */ eieio /* Make sure that the tlbie happens first */ tlbsync /* wait for everyone to catch up */ + isync its603: rlwinm. r21,r21,0,0,0 ; See if we just stole an autogenned entry sync /* Make sure of it all */ @@ -2693,7 +2700,8 @@ rbnFirst: bne- rbPerm ; This is permanent, do not remove... blt rbHash ; Nope, length is right subi r6,r4,32+31 ; Back down to correct length -rbHash: xor r2,r8,r5 ; Hash into table +rbHash: rlwinm r5,r5,0,10,25 ; Keep only the page index + xor r2,r8,r5 ; Hash into table and r2,r2,r4 ; Wrap into the table add r2,r2,r12 ; Point right at the PCA @@ -2784,6 +2792,7 @@ rbTlbN: addic. r5,r5,-1 ; See if we did them all eieio ; Make sure that the tlbie happens first tlbsync ; wait for everyone to catch up + isync rbits603a: sync ; Wait for quiet again stw r2,0(r12) ; Unlock invalidates diff --git a/osfmk/ppc/machine_routines_asm.s b/osfmk/ppc/machine_routines_asm.s index 48e918762..b67ea1091 100644 --- a/osfmk/ppc/machine_routines_asm.s +++ b/osfmk/ppc/machine_routines_asm.s @@ -587,6 +587,7 @@ cipurgeTLB: tlbie r6 ; Purge this entry tlbsync ; Sync all TLBs sync + isync cinoSMP: stw r2,0(r5) ; Unlock TLBIE lock diff --git a/osfmk/ppc/savearea_asm.s b/osfmk/ppc/savearea_asm.s index 425e41cca..2d7ef5e3d 100644 --- a/osfmk/ppc/savearea_asm.s +++ b/osfmk/ppc/savearea_asm.s @@ -49,25 +49,33 @@ ENTRY(save_queue,TAG_NO_FRAME_USED) - mfmsr r12 /* Get the MSR */ - lis r10,HIGH_ADDR(EXT(saveanchor)) /* Get the high part of the anchor */ - andi. r11,r12,0x7FCF /* Turn off all translation and 'rupts */ - ori r10,r10,LOW_ADDR(EXT(saveanchor)) /* Bottom half of the anchor */ - mtmsr r11 /* Make the MSR current */ - - isync + mfsprg r9,2 ; Get the feature flags + mr r11,r3 ; Save the block + mtcrf 0x04,r9 ; Set the features + mfmsr r12 ; Get the MSR + lis r10,HIGH_ADDR(EXT(saveanchor)) ; Get the high part of the anchor + andi. r3,r12,0x7FCF ; Turn off all translation and rupts + ori r10,r10,LOW_ADDR(EXT(saveanchor)) ; Bottom half of the anchor + + bt pfNoMSRirb,sqNoMSR ; No MSR... + + mtmsr r3 ; Translation and all off + isync ; Toss prefetch + b sqNoMSRx + +sqNoMSR: li r0,loadMSR ; Get the MSR setter SC + sc ; Set it +sqNoMSRx: #if 0 - rlwinm. r3,r3,0,0,19 /* (TEST/DEBUG) */ + rlwinm. r3,r11,0,0,19 /* (TEST/DEBUG) */ bne+ notraceit /* (TEST/DEBUG) */ BREAKPOINT_TRAP /* (TEST/DEBUG) */ notraceit: /* (TEST/DEBUG) */ #else - rlwinm r3,r3,0,0,19 /* Make sure it's clean and tidy */ + rlwinm r3,r11,0,0,19 /* Make sure it's clean and tidy */ #endif - lwarx r9,0,r10 ; ? - sqlck: lwarx r9,0,r10 /* Grab the lock value */ li r8,1 /* Use part of the delay time */ mr. r9,r9 /* Is it locked? */ @@ -122,14 +130,22 @@ sqlckd: isync /* Make sure translation is off */ ENTRY(save_dequeue,TAG_NO_FRAME_USED) + mfsprg r9,2 ; Get the feature flags mfmsr r12 /* Get the MSR */ + mtcrf 0x04,r9 ; Set the features lis r10,HIGH_ADDR(EXT(saveanchor)) /* Get the high part of the anchor */ - andi. r11,r12,0x7FCF /* Turn off all translation and 'rupts */ + andi. r3,r12,0x7FCF /* Turn off all translation and 'rupts */ ori r10,r10,LOW_ADDR(EXT(saveanchor)) /* Bottom half of the anchor */ - mtmsr r11 /* Make the MSR current */ - isync /* Make sure translation is off */ - lwarx r9,0,r10 ; ? + bt pfNoMSRirb,sdNoMSR ; No MSR... + + mtmsr r3 ; Translation and all off + isync ; Toss prefetch + b sdNoMSRx + +sdNoMSR: li r0,loadMSR ; Get the MSR setter SC + sc ; Set it +sdNoMSRx: sdqlck: lwarx r9,0,r10 /* Grab the lock value */ li r8,1 /* Use part of the delay time */ @@ -211,14 +227,25 @@ ENTRY(save_get,TAG_NO_FRAME_USED) cmplwi cr1,r1,0 ; Set CR1_ne to indicate we want virtual address -csaveget: mfmsr r11 /* Get the MSR */ +csaveget: mfsprg r9,2 ; Get the feature flags + mfmsr r11 ; Get the MSR + mtcrf 0x04,r9 ; Set the features lis r10,HIGH_ADDR(EXT(saveanchor)) /* Get the high part of the anchor */ - andi. r8,r11,0x7FCF /* Turn off all translation and 'rupts */ + andi. r3,r11,0x7FCF /* Turn off all translation and 'rupts */ ori r10,r10,LOW_ADDR(EXT(saveanchor)) /* Bottom half of the anchor */ - mtmsr r8 /* Make the MSR current */ - isync ; Make sure it is done + + bt pfNoMSRirb,sgNoMSR ; No MSR... + + mtmsr r3 ; Translation and all off + isync ; Toss prefetch + b sgNoMSRx - lwarx r9,0,r10 ; ? +sgNoMSR: mr r9,r0 ; Save this + li r0,loadMSR ; Get the MSR setter SC + sc ; Set it + mr r0,r9 ; Restore it + +sgNoMSRx: sglck: lwarx r9,0,r10 /* Grab the lock value */ li r7,1 /* Use part of the delay time */ @@ -313,20 +340,31 @@ notpage0: rlwinm r6,r3,0,0,19 /* (TEST/DEBUG) */ nodoublefret: /* (TEST/DEBUG) */ #endif + mfsprg r9,2 ; Get the feature flags lwz r7,SAVflags(r3) /* Get the flags */ rlwinm r6,r3,0,0,19 /* Round back down to the savearea page block */ andis. r7,r7,HIGH_ADDR(SAVinuse) /* Still in use? */ mfmsr r12 /* Get the MSR */ bnelr- /* Still in use, just leave... */ lwz r5,SACvrswap(r6) /* Get the conversion to real */ + mr r8,r3 ; Save the savearea address + mtcrf 0x04,r9 ; Set the features lis r10,HIGH_ADDR(EXT(saveanchor)) /* Get the high part of the anchor */ - andi. r11,r12,0x7FCF /* Turn off all translation and 'rupts */ + andi. r3,r12,0x7FCF /* Turn off all translation and 'rupts */ ori r10,r10,LOW_ADDR(EXT(saveanchor)) /* Bottom half of the anchor */ - mtmsr r11 /* Make the MSR current */ - isync /* Make sure translation is off */ + + bt pfNoMSRirb,srNoMSR ; No MSR... + + mtmsr r3 ; Translation and all off + isync ; Toss prefetch + b srNoMSRx + +srNoMSR: li r0,loadMSR ; Get the MSR setter SC + sc ; Set it +srNoMSRx: mfsprg r11,1 /* Get the active save area */ - xor r3,r3,r5 /* Get the real address of the savearea */ + xor r3,r8,r5 /* Get the real address of the savearea */ cmplw r11,r3 /* Are we trying to toss the active one? */ xor r6,r6,r5 /* Make the savearea block real also */ beq- srbigtimepanic /* This is a no-no... */ @@ -335,8 +373,6 @@ nodoublefret: /* (TEST/DEBUG) */ lis r8,0x8000 /* Build a bit mask and assume first savearea */ srw r8,r8,r7 /* Get bit position of do deallocate */ - lwarx r11,0,r10 ; ? - srlck: lwarx r11,0,r10 /* Grab the lock value */ li r7,1 /* Use part of the delay time */ mr. r11,r11 /* Is it locked? */ @@ -422,20 +458,31 @@ LEXT(save_cpv) * block and disable for interruptions. * Note really well: this is only for debugging, don't expect it to always work! * - * We take a virtual address in R4 to save the original MSR, and + * We take a virtual address in R3 to save the original MSR, and * return the virtual address. * */ ENTRY(save_deb,TAG_NO_FRAME_USED) + mfsprg r9,2 ; Get the feature flags mfmsr r12 /* Get the MSR */ lis r10,HIGH_ADDR(EXT(saveanchor)) /* Get the high part of the anchor */ + mtcrf 0x04,r9 ; Set the features stw r12,0(r3) /* Save it */ - andi. r11,r12,0x7FCF /* Turn off all translation and 'rupts */ + andi. r3,r12,0x7FCF /* Turn off all translation and 'rupts */ ori r10,r10,LOW_ADDR(EXT(saveanchor)) /* Bottom half of the anchor */ - mtmsr r11 /* Make the MSR current */ - isync /* Make sure translation is off */ + + bt pfNoMSRirb,sdbNoMSR ; No MSR... + + mtmsr r3 ; Translation and all off + isync ; Toss prefetch + b sdbNoMSRx + +sdbNoMSR: li r0,loadMSR ; Get the MSR setter SC + sc ; Set it +sdbNoMSRx: + lwz r3,SVfree(r10) /* Get the physical first in list */ andi. r11,r12,0x7FFF /* Clear only interruption */ lwz r5,SACvrswap(r3) /* Get the conversion to virtual */ diff --git a/osfmk/vm/vm_resident.c b/osfmk/vm/vm_resident.c index 51bddcff3..be2bb3971 100644 --- a/osfmk/vm/vm_resident.c +++ b/osfmk/vm/vm_resident.c @@ -958,10 +958,8 @@ vm_page_grab_fictitious(void) m = (vm_page_t)zget(vm_page_zone); if (m) { m->free = FALSE; -#if MACH_ASSERT || ZONE_DEBUG vm_page_init(m, vm_page_fictitious_addr); m->fictitious = TRUE; -#endif /* MACH_ASSERT || ZONE_DEBUG */ } c_vm_page_grab_fictitious++; diff --git a/osfmk/vm/vm_user.c b/osfmk/vm/vm_user.c index 371898e02..ec4dcfbf2 100644 --- a/osfmk/vm/vm_user.c +++ b/osfmk/vm/vm_user.c @@ -1924,8 +1924,16 @@ vm_map_get_upl( { vm_map_entry_t entry; int caller_flags; + int sync_cow_data = FALSE; + vm_object_t local_object; + vm_offset_t local_offset; + vm_offset_t local_start; + kern_return_t ret; caller_flags = *flags; + if (!(caller_flags & UPL_COPYOUT_FROM)) { + sync_cow_data = TRUE; + } if(upl == NULL) return KERN_INVALID_ARGUMENT; REDISCOVER_ENTRY: @@ -1977,49 +1985,105 @@ REDISCOVER_ENTRY: } } if (entry->is_sub_map) { + vm_map_t submap; + + submap = entry->object.sub_map; + local_start = entry->vme_start; + local_offset = entry->offset; + vm_map_reference(submap); vm_map_unlock(map); - return (vm_map_get_upl(entry->object.sub_map, - entry->offset + (offset - entry->vme_start), + + ret = (vm_map_get_upl(submap, + local_offset + (offset - local_start), upl_size, upl, page_list, count, flags, force_data_sync)); + + vm_map_deallocate(submap); + return ret; } - if (!(caller_flags & UPL_COPYOUT_FROM)) { + if (sync_cow_data) { if (entry->object.vm_object->shadow) { - int flags; + int flags; + + local_object = entry->object.vm_object; + local_start = entry->vme_start; + local_offset = entry->offset; + vm_object_reference(local_object); vm_map_unlock(map); - vm_object_reference(entry->object.vm_object); - if(entry->object.vm_object->copy == NULL) { + if(local_object->copy == NULL) { flags = MEMORY_OBJECT_DATA_SYNC; } else { flags = MEMORY_OBJECT_COPY_SYNC; } + + if((local_object->paging_offset) && + (local_object->pager == 0)) { + /* + * do a little clean-up for our unorthodox + * entry into a pager call from a non-pager + * context. Normally the pager code + * assumes that an object it has been called + * with has a backing pager and so does + * not bother to check the pager field + * before relying on the paging_offset + */ + vm_object_lock(local_object); + if (local_object->pager == 0) { + local_object->paging_offset = 0; + } + vm_object_unlock(local_object); + } memory_object_lock_request( - entry->object.vm_object, - (offset - entry->vme_start) - + entry->offset, + local_object, ((offset - local_start) + + local_offset) + + local_object->paging_offset, (vm_object_size_t)*upl_size, FALSE, flags, VM_PROT_NO_CHANGE, NULL, 0); - vm_map_lock(map); + sync_cow_data = FALSE; + goto REDISCOVER_ENTRY; } } if (force_data_sync) { + + local_object = entry->object.vm_object; + local_start = entry->vme_start; + local_offset = entry->offset; + vm_object_reference(local_object); vm_map_unlock(map); - vm_object_reference(entry->object.vm_object); + if((local_object->paging_offset) && + (local_object->pager == 0)) { + /* + * do a little clean-up for our unorthodox + * entry into a pager call from a non-pager + * context. Normally the pager code + * assumes that an object it has been called + * with has a backing pager and so does + * not bother to check the pager field + * before relying on the paging_offset + */ + vm_object_lock(local_object); + if (local_object->pager == 0) { + local_object->paging_offset = 0; + } + vm_object_unlock(local_object); + } + memory_object_lock_request( - entry->object.vm_object, - (offset - entry->vme_start) - + entry->offset, - (vm_object_size_t)*upl_size, FALSE, - MEMORY_OBJECT_DATA_SYNC, - VM_PROT_NO_CHANGE, - NULL, 0); - vm_map_lock(map); + local_object, ((offset - local_start) + + local_offset) + + local_object->paging_offset, + (vm_object_size_t)*upl_size, FALSE, + MEMORY_OBJECT_DATA_SYNC, + VM_PROT_NO_CHANGE, + NULL, 0); + force_data_sync = FALSE; + goto REDISCOVER_ENTRY; } if(!(entry->object.vm_object->private)) { @@ -2033,14 +2097,20 @@ REDISCOVER_ENTRY: } else { *flags = UPL_DEV_MEMORY | UPL_PHYS_CONTIG; } + local_object = entry->object.vm_object; + local_offset = entry->offset; + local_start = entry->vme_start; + vm_object_reference(local_object); vm_map_unlock(map); - return(vm_fault_list_request(entry->object.vm_object, - ((offset - entry->vme_start) + entry->offset), + ret = (vm_fault_list_request(local_object, + ((offset - local_start) + local_offset), *upl_size, upl, page_list, *count, caller_flags)); + vm_object_deallocate(local_object); + return(ret); } vm_map_unlock(map); @@ -2627,7 +2697,7 @@ shared_region_mapping_dealloc( sm_info.alternate_base = shared_region->alternate_base; sm_info.alternate_next = shared_region->alternate_next; sm_info.flags = shared_region->flags; - sm_info.self = shared_region; + sm_info.self = (vm_offset_t)shared_region; lsf_remove_regions_mappings(shared_region, &sm_info); pmap_remove(((vm_named_entry_t)