@ -129,6 +129,59 @@ static inline abi_long do_bsd_munlockall(void)
return get_errno ( munlockall ( ) ) ;
}
/* madvise(2) */
static inline abi_long do_bsd_madvise ( abi_long arg1 , abi_long arg2 ,
abi_long arg3 )
{
abi_ulong len ;
int ret = 0 ;
abi_long start = arg1 ;
abi_long len_in = arg2 ;
abi_long advice = arg3 ;
if ( start & ~ TARGET_PAGE_MASK ) {
return - TARGET_EINVAL ;
}
if ( len_in = = 0 ) {
return 0 ;
}
len = TARGET_PAGE_ALIGN ( len_in ) ;
if ( len = = 0 | | ! guest_range_valid_untagged ( start , len ) ) {
return - TARGET_EINVAL ;
}
/*
* Most advice values are hints , so ignoring and returning success is ok .
*
* However , some advice values such as MADV_DONTNEED , are not hints and
* need to be emulated .
*
* A straight passthrough for those may not be safe because qemu sometimes
* turns private file - backed mappings into anonymous mappings .
* If all guest pages have PAGE_PASSTHROUGH set , mappings have the
* same semantics for the host as for the guest .
*
* MADV_DONTNEED is passed through , if possible .
* If passthrough isn ' t possible , we nevertheless ( wrongly ! ) return
* success , which is broken but some userspace programs fail to work
* otherwise . Completely implementing such emulation is quite complicated
* though .
*/
mmap_lock ( ) ;
switch ( advice ) {
case MADV_DONTNEED :
if ( page_check_range ( start , len , PAGE_PASSTHROUGH ) ) {
ret = get_errno ( madvise ( g2h_untagged ( start ) , len , advice ) ) ;
if ( ret = = 0 ) {
page_reset_target_data ( start , start + len - 1 ) ;
}
}
}
mmap_unlock ( ) ;
return ret ;
}
/* minherit(2) */
static inline abi_long do_bsd_minherit ( abi_long addr , abi_long len ,
abi_long inherit )