Unfortunately it's not that easy. coding_system has many fields that setup_coding_system doesn't initialize.
static void
json_check_utf8 (Lisp_Object string)
{
eassert (!STRING_MULTIBYTE (string));
struct coding_system coding;
setup_coding_system (Qutf_8_unix, &coding);
/* We initialize only the fields that check_utf_8 accesses. */
coding.src_pos = 0;
coding.src_pos_byte = 0;
coding.src_chars = SCHARS (string);
coding.src_bytes = SBYTES (string);
coding.src_object = string;
coding.eol_seen = EOL_SEEN_NONE;
CHECK_TYPE (check_utf_8 (&coding) >= 0, Qutf_8_string_p, string);
}
This apparently fails to detect the unibyte string "u\xFFv" as invalid UTF-8.