There are tons of ways for kernel-mode to user-mode Inter-Process Communication, and different requirements can suit different techniques.
For starters, you have the option of named pipes (even in kernel-mode). However, there's something you should know... It isn't officially documented for a normal kernel-mode device driver (although there is a documented interface for Filesystem Mini-Filter device drivers).
If you want to use a named pipe from a normal kernel-mode device driver, you'll have to locate the address to NtCreateNamedPipeFile or rely on IoCreateFile (which NtCreateNamedPipeFile relies on internally, using an undocumented structure).
For using a named pipe from a Filesystem Mini-Filter device driver, you have FltCreateNamedPipeFile.
Moving on from the named pipes idea, you have the option of Local Procedure Calls! However, once again, another dead-end in terms of documentation. It is relatively straight forward to do it as a client in kernel-mode though. There's a documented interface for Ports with a Filesystem Mini-Filter device driver though: FltCreateCommunicationPort.
Moving on again, you could attach to the user-mode client and write directly to its memory.
If you really wanted, you could rely on something simple like a shared event to notify the user-mode client that you've just attached to it and written into its virtual memory.