The line is fuzzy though.
You might say that each RAM access is really a message over a bus, and so is each cache access. Conversely, you could write a message passing style key value store and create race conditions by using like shared memory.
Transactional memory is also 'message passing' like -> you bundle up access of shared memory into a single transaction 'message'.
A lot of shared memory code uses constructions like FIFO/queues which are really not too distinct from message passing except when ownership is shared or goes back and forth. Perhaps that's just an 'implementation' of message passing.
Of course if you don't have shared memory then you have to copy anyway :) And because of CPU caching architecture the benefits of having an owned copy of the data can sometimes outweigh the cost of copying it, even if shared memory is available.
We're also now talking about patterns which are common in other contexts, but I don't have a problem with that. io_uring for example - is it shared memory, asynchronous, message passing, or all three (probably yes)?