--- a/sys/vm/phys_pager.c +++ b/sys/vm/phys_pager.c @@ -110,8 +110,17 @@ phys_pager_putpages(vm_object_t object, vm_page_t *m, int count, int flags, int *rtvals) { + int i; - panic("phys_pager_putpage called"); + /* + * OBJT_PHYS objects have no backing store. Pages should always + * be PG_UNQUEUED (phys_pager_getpage() and vm_fault set the + * flag), but if a queue-managed page ever reaches us anyway, + * report failure instead of panicking: the page stays dirty and + * resident, preserving its contents. + */ + for (i = 0; i < count; ++i) + rtvals[i] = VM_PAGER_FAIL; } /* --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -2323,7 +2323,16 @@ /* * Zero the page and mark it valid. + * + * OBJT_PHYS pages are unmanaged: phys_pager_getpage() + * sets PG_UNQUEUED. Wiring faults (VM_FAULT_WIRE_MASK) + * bypass the pager (TRYPAGER is false), so mirror the + * pager here or unwiring leaves a queue-managed page in + * a phys object, which the pagedaemon would later try + * to launder -> phys_pager_putpages() panic. */ + if (fs->mary[0]->object->type == OBJT_PHYS) + vm_page_flag_set(fs->mary[0], PG_UNQUEUED); vm_page_zero_fill(fs->mary[0]); mycpu->gd_cnt.v_zfod++; fs->mary[0]->valid = VM_PAGE_BITS_ALL;