]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/vm/vm_compressor_pager.c
xnu-4903.221.2.tar.gz
[apple/xnu.git] / osfmk / vm / vm_compressor_pager.c
index ae0195c861f7e4fc9256f5eb13c942be921d832e..c8ec4fed006213c26c63c8faf0fbb908ceb889ab 100644 (file)
@@ -707,6 +707,8 @@ vm_compressor_pager_put(
 {
        compressor_pager_t      pager;
        compressor_slot_t       *slot_p;
+       unsigned int            prev_wimg = VM_WIMG_DEFAULT;
+       boolean_t               set_cache_attr = FALSE;
 
        compressor_pager_stats.put++;
 
@@ -746,11 +748,33 @@ vm_compressor_pager_put(
                vm_compressor_free(slot_p, 0);
                *compressed_count_delta_p -= 1;
        }
-       if (vm_compressor_put(ppnum, slot_p, current_chead, scratch_buf))
-               return (KERN_RESOURCE_SHORTAGE);
+
+       /*
+        * cacheability should be set to the system default (usually writeback)
+        * during compressor operations, both for performance and correctness,
+        * e.g. to avoid compressor codec faults generated by an unexpected
+        * memory type.
+        */
+       prev_wimg = pmap_cache_attributes(ppnum) & VM_WIMG_MASK;
+
+       if ((prev_wimg != VM_WIMG_DEFAULT) && (prev_wimg != VM_WIMG_USE_DEFAULT)) {
+               set_cache_attr = TRUE;
+               pmap_set_cache_attributes(ppnum, VM_WIMG_DEFAULT);
+       }
+       /*
+        * If the compressor operation succeeds, we presumably don't need to
+        * undo any previous WIMG update, as all live mappings should be
+        * disconnected.
+        */
+
+       if (vm_compressor_put(ppnum, slot_p, current_chead, scratch_buf)) {
+               if (set_cache_attr)
+                       pmap_set_cache_attributes(ppnum, prev_wimg);
+               return KERN_RESOURCE_SHORTAGE;
+       }
        *compressed_count_delta_p += 1;
 
-       return (KERN_SUCCESS);
+       return KERN_SUCCESS;
 }
 
 
@@ -796,6 +820,21 @@ vm_compressor_pager_get(
                
        if (kr == KERN_SUCCESS) {
                int     retval;
+               unsigned int prev_wimg = VM_WIMG_DEFAULT;
+               boolean_t set_cache_attr = FALSE;
+
+               /*
+                * cacheability should be set to the system default (usually writeback)
+                * during compressor operations, both for performance and correctness,
+                * e.g. to avoid compressor codec faults generated by an unexpected
+                * memory type.
+                */
+               prev_wimg = pmap_cache_attributes(ppnum) & VM_WIMG_MASK;
+
+               if ((prev_wimg != VM_WIMG_DEFAULT) && (prev_wimg != VM_WIMG_USE_DEFAULT)) {
+                       set_cache_attr = TRUE;
+                       pmap_set_cache_attributes(ppnum, VM_WIMG_DEFAULT);
+               }
 
                /* get the page from the compressor */
                retval = vm_compressor_get(ppnum, slot_p, flags);
@@ -807,6 +846,8 @@ vm_compressor_pager_get(
                        assert((flags & C_DONT_BLOCK));
                        kr = KERN_FAILURE;
                }
+               if (set_cache_attr)
+                       pmap_set_cache_attributes(ppnum, prev_wimg);
        }
 
        if (kr == KERN_SUCCESS) {