Thank you for adding more details to my response to OP. Some further details:
1) Any system that relies on distinguishing caps from other data must deal with C unions and the equivalent in even more typeless languages such as asm. If an integer is added to a a memory location, is that an integer sum or an address increment? Similar problems arise when pointers are not simple memory addresses, as in XOR-bi-directional lists, for example. Grants avoid this, because in grants a pointer is whatever is given as an address to the LOAD and STORE instructions, regardless of how the address was constructed. The CHERI approach is not wrong given that they chose to use caps, but there will still be programs that violate typing enough to require rewrite.
2) Yes, Mill decouples paging from protection. All running programs share the paging; each protection domain (a turf in Mill terminology) has its own rights, which can cross page boundaries.
3) Both CHERI and Mill have chosen a unified single address space, and yes, that choice greatly improves performance on general purpose codes.
4) Revoke is a problem in any protection system that allows sharing. Caps systems generally have fine-grain protection at the granularity of the individual malloc allocation, while grants systems usually have coarse grained protection at the granularity of the mmap call or file open. The fine grain of caps leads to having many more things to keep track of than are present in a grants system, leading to garbage collection, while a grants can use a single-owner model and update (and revoke) rules typical of a conventional process model.
However, revoke offers semantic issues as well as implementation troubles: just what does it mean to revoke a right? If I create an object with certain rights, and I pass it on to you with its rights so you can use it too – can you in turn pass it on to a third party? If so, and I then revoke it, is the revoke only for you an not him, or for both of you? The meanings get messy.