Firstly, you should take a look at my description of why lookup tables don't run in constant time, as I have pictures of how the cache and tagging works.
The cache sits between the MMU and the CPU, and the MMU is what creates virtual memory; thereby cache attacks are actually an independent function of virtual memory. They are a function of forcing a cache flush, and then picking and choosing how the cache will be reloaded because you are looking for temporal information. The fetch externally between caches is what leaks information. (A note, this is basically an x86 problem as it does not allow cache locking, unlike most CPUs since 1990. Another caveat is that I have only made hardware for non-x86 architectures so someone please let me know if I am wrong about cache locking for critical data).
For the sake of a general example, we have a cache of 1k bytes and we will use AES s-box as a lookup table, so 256 entries.
- force a flush of the cache flush via a different process by reading 2k of bytes from memory.
- the AES process starts running and puts the data sbox data into the cache by proxy of bus fetches
- We then do another process read of 1023 bytes of different data from memory to override the all but one of the AES entries and see when that data comes out slow due to a bus read
Now for the MMU version where we attack virtual memory. If you looked at the answer I linked, you will see there are cache tags. Now let's assume a simple example where I have two processes with 20-bits (1MiB of address space). The MMU makes both of those processes have the same virtual table from of 0xYYY00000, where YYY is the actual prefix in memory. If I know how the MMU is mapping the data, and I can create a structured attack based on the tagging information that is created in cache due to the how the memory overlaps.
There's more details on how you structure these attacks on the software side in Bernstein's Cache-timing attacks on AES.