kvmalloc() was a simple wrapper around the FreeBSD native malloc(). Unlike the more involved implementation of kmalloc(), it didn't end and being the FPU context around the actual call to malloc().
This caused the following panic in the amdgup DRM driver:
panic: malloc: called with spinlock or critical section held
... triggered by the call:
struct dc_3dlut *lut = kvzalloc(sizeof(*lut), GFP_KERNEL);
(for the record, GFP_KERNEL is defined as M_WAITOK)
Replicating the same behaviour as kmalloc(), in other words, ending the FPU context before the call to the underlying malloc(), and beginning it again afterwards solves the problem.
Sponsored by: The FreeBSD Foundation.