You do need the entire thread to be CLR-free. As soon as any managed code runs on the thread, it will get added to the CLR's list of threads to suspend during collection.
Your last question, though, suggests that you have no clue about multithreading. There is no correspondence between threads and DLLs. A DLL can have many threads, and each thread can run code from many DLLs (in fact, always does, if you count Windows DLLs). You're also not using the phrase "critical section" in the usual way.
A mixed-mode C++/CLI assembly can contain a native-only thread (start it using the native CreateThread call, passing a native thread procedure, and don't call any managed code directly or indirectly from that thread). Your life will be a little easier if you write the code for the native thread in one or more files set to compile without /clr, not having managed code visible makes it easier to avoid calling it, although beware of function pointers which might be wrapping managed delegates.
Beyond that, use lock-free synchronization, e.g. SList, or your native thread could end up waiting for a lock held on a mixed-mode thread which has been suspended for garbage collection. Among other things this means not using any of the standard shared allocators, because they use locking internally. Some lock-free allocators do exist though.
EDIT: Function pointers which wrap managed delegates are created by calling Marshal::GetDelegateForFunctionPointer. After that, they act just like pointers to native functions (it is possible to tell them apart) and using the function call operator on such a pointer will cause managed code to run on the sensitive thread. In most cases this won't be a problem, just make sure if you are using delegates as a shortcut to produce callbacks to managed code, that you do so from the mixed thread and not the one you intend to be native-only.
In general, you'll probably want some sort of purely native message passing scheme to exchange data. The mixed thread can make whatever native calls are necessary, you can mix native and managed code on all your other threads, just keep the time-sensitive one native-only.
All thunking should occur on the mixed thread, and it won't delay the time-sensitive native thread unless the mixed thread is holding a lock that the native thread needs. Hence my suggestion to use non-locking data exchange.