IMHO, most of io_uring's performance should come from reducing transition between kernel and userspace. There doesn't need to be a safety tradeoff there (although in practice, there have been several safety issues). There may be a trade off against having a simple concurrency model; without io_uring you can't really request an accept and not handle the response that comes back, because a syscall is necessarily synchronous from the point of view of the caller; the calling thread can't continue until it gets a response, even if that's EINTR.
Out of my league / knowledge, but a tidbit that you might understand better: last time I mentioned this, someone said something about SELinux can't do security checks and implied it's some fundamental mismatch, rather than some work SELinux can do
Well I'm a little outside my league on SELinux, but as I understand it, SELinux a way to limit syscalls by configuration.
io_uring operations are similar to syscalls, but not exactly the same thing, so if I've read up correctly, I think SELinux originally may not have covered operations --- if the config allowed you to use io_uring, you could bypass SELinux restrictions, and the easiest/safest thing to do for that is to restrict io_uring. I think this may have been resolved, it looks like there was work on SELinux controls for io_uring back in 2021 [1] that looks like it got merged, but I haven't really followed this. There's also the issue that what happened in Linus's tree 2021 doesn't necessarily reflect what's in common kernels in 2024; some distributions are built from ancient branches.
Based on the language in the pull request, I would think you'd end up needing to have near duplicate policy entries for regular syscalls and io_uring operations, which sounds tedious (but the whole SELinux thing sounds tedious to me, so I'm maybe not the right person to ask :D )