/*
 * DF-2673 - recursive vm_map_lock panic in vm_map_growstack() when
 * MAP_WIREFUTURE is set (mlockall(MCL_FUTURE)).
 *
 * vm_map_growstack() (sys/vm/vm_map.c:4228-4233) upgrades to the
 * exclusive map lock, inserts the growth, then at sys/vm/vm_map.c:4274
 * calls vm_map_user_wiring() which does vm_map_lock(map) again
 * (sys/vm/vm_map.c:2594) -> lockmgr(LK_EXCLUSIVE) recursion without
 * LK_CANRECURSE -> panic("lockmgr: locking against myself").
 *
 * MUST RUN AS ROOT (mlockall requires SYSCAP_RESTRICTEDROOT).
 * Expected: kernel panic on the fault below the stack.
 */
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>

int
main(void)
{
	volatile char probe;
	uintptr_t sp, target;

	if (mlockall(MCL_FUTURE) != 0) {
		perror("mlockall");
		return (1);
	}
	printf("[*] MCL_FUTURE set, faulting below the stack...\n");
	fflush(stdout);

	sp = (uintptr_t)&probe;
	target = (sp - (8UL << 20)) & ~4095UL;	/* 8MB below, page aligned */
	*(volatile char *)target = 1;		/* triggers vm_map_growstack */

	printf("[!] no panic?!\n");
	return (0);
}
