@@ -857,7 +857,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
857
857
return new_addr ;
858
858
}
859
859
860
- static bool can_passthrough_madv_dontneed (abi_ulong start , abi_ulong end )
860
+ static bool can_passthrough_madvise (abi_ulong start , abi_ulong end )
861
861
{
862
862
ulong addr ;
863
863
@@ -901,23 +901,53 @@ abi_long target_madvise(abi_ulong start, abi_ulong len_in, int advice)
901
901
return - TARGET_EINVAL ;
902
902
}
903
903
904
+ /* Translate for some architectures which have different MADV_xxx values */
905
+ switch (advice ) {
906
+ case TARGET_MADV_DONTNEED : /* alpha */
907
+ advice = MADV_DONTNEED ;
908
+ break ;
909
+ case TARGET_MADV_WIPEONFORK : /* parisc */
910
+ advice = MADV_WIPEONFORK ;
911
+ break ;
912
+ case TARGET_MADV_KEEPONFORK : /* parisc */
913
+ advice = MADV_KEEPONFORK ;
914
+ break ;
915
+ /* we do not care about the other MADV_xxx values yet */
916
+ }
917
+
904
918
/*
905
- * A straight passthrough may not be safe because qemu sometimes turns
906
- * private file-backed mappings into anonymous mappings.
919
+ * Most advice values are hints, so ignoring and returning success is ok.
920
+ *
921
+ * However, some advice values such as MADV_DONTNEED, MADV_WIPEONFORK and
922
+ * MADV_KEEPONFORK are not hints and need to be emulated.
907
923
*
908
- * This is a hint, so ignoring and returning success is ok.
924
+ * A straight passthrough for those may not be safe because qemu sometimes
925
+ * turns private file-backed mappings into anonymous mappings.
926
+ * can_passthrough_madvise() helps to check if a passthrough is possible by
927
+ * comparing mappings that are known to have the same semantics in the host
928
+ * and the guest. In this case passthrough is safe.
909
929
*
910
- * This breaks MADV_DONTNEED, completely implementing which is quite
911
- * complicated. However, there is one low-hanging fruit: mappings that are
912
- * known to have the same semantics in the host and the guest. In this case
913
- * passthrough is safe, so do it.
930
+ * We pass through MADV_WIPEONFORK and MADV_KEEPONFORK if possible and
931
+ * return failure if not.
932
+ *
933
+ * MADV_DONTNEED is passed through as well, if possible.
934
+ * If passthrough isn't possible, we nevertheless (wrongly!) return
935
+ * success, which is broken but some userspace programs fail to work
936
+ * otherwise. Completely implementing such emulation is quite complicated
937
+ * though.
914
938
*/
915
939
mmap_lock ();
916
- if (advice == TARGET_MADV_DONTNEED &&
917
- can_passthrough_madv_dontneed (start , end )) {
918
- ret = get_errno (madvise (g2h_untagged (start ), len , MADV_DONTNEED ));
919
- if (ret == 0 ) {
920
- page_reset_target_data (start , start + len );
940
+ switch (advice ) {
941
+ case MADV_WIPEONFORK :
942
+ case MADV_KEEPONFORK :
943
+ ret = - EINVAL ;
944
+ /* fall through */
945
+ case MADV_DONTNEED :
946
+ if (can_passthrough_madvise (start , end )) {
947
+ ret = get_errno (madvise (g2h_untagged (start ), len , advice ));
948
+ if ((advice == MADV_DONTNEED ) && (ret == 0 )) {
949
+ page_reset_target_data (start , start + len );
950
+ }
921
951
}
922
952
}
923
953
mmap_unlock ();
0 commit comments