Then the attacker would also have to force the system into enough memory pressure to be requesting to recycle these pages - something it may not be in the position to do if it is a guest with capped resources. The pages would also presumably be recycled in a less predictable order, making it harder to come up with simple a "wait 10 minutes" rule to ensure the recycling has taken place.
Now, I'm sure what I've described would not be particularly simple to implement, but that's another thing.
Well, kinda. They only eventually have to be created.
You don't have to create the new copy immediately, you could overlay new data on the old page
(IE create new sparse page. Anything filled in on the new page is read from new page, anything else goes to backing dedupe'd page. real copy is made in background so this goes back to being fast)
Of course, this mostly just makes it harder, assuming you can place enough memory pressure on the machine.
Without hardware support, the only idea I can think of is to mark the page unreadable and pass all memory reads through the kernel. Which would be readily detectable... among other problems.
Sparse pages are at least feasible in hardware.
Also, you realize that passing all memory reads through the kernel is what any read barrier garbage collected language does, right?
Essentially, the first method is a timing attack. If can tell if a crafted page is duplicated or not by the time it takes to modify the page.
Modifying a defuplicated page will take longer, because a new copy has to be created. The only way I can see around this is to introduce random delays into all page writes, this might be feasible I guess, if you only needed to delay a small percentage of writes. However it's likely the performance penalty would be unacceptable.