x86/pagewalk: Support PKS

PKS is very similar to the existing PKU behaviour, operating on pagewalks for
any supervisor mapping.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
Andrew Cooper committed 2023-01-20 19:39:34 +00:00
1 parent 59bbbb823d
commit e96f634b3d
3 files changed
+13 -4

No files matched your search

+5
View File
@@ -282,6 +282,11 @@ static always_inline bool guest_pku_enabled(const struct vcpu *v)
return !is_pv_vcpu(v) && hvm_pku_enabled(v);
}
static always_inline bool guest_pks_enabled(const struct vcpu *v)
{
return !is_pv_vcpu(v) && hvm_pks_enabled(v);
}
/* Helpers for identifying whether guest entries have reserved bits set. */
/* Bits reserved because of maxphysaddr, and (lack of) EFER.NX */
+3
View File
@@ -407,6 +407,8 @@ int hvm_get_param(struct domain *d, uint32_t index, uint64_t *value);
((v)->arch.hvm.guest_efer & EFER_NXE)
#define hvm_pku_enabled(v) \
(hvm_paging_enabled(v) && ((v)->arch.hvm.guest_cr[4] & X86_CR4_PKE))
#define hvm_pks_enabled(v) \
(hvm_paging_enabled(v) && ((v)->arch.hvm.guest_cr[4] & X86_CR4_PKS))
/* Can we use superpages in the HAP p2m table? */
#define hap_has_1gb (!!(hvm_funcs.hap_capabilities & HVM_HAP_SUPERPAGE_1GB))
@@ -911,6 +913,7 @@ static inline void hvm_set_reg(struct vcpu *v, unsigned int reg, uint64_t val)
#define hvm_smap_enabled(v) ((void)(v), false)
#define hvm_nx_enabled(v) ((void)(v), false)
#define hvm_pku_enabled(v) ((void)(v), false)
#define hvm_pks_enabled(v) ((void)(v), false)
#define arch_vcpu_block(v) ((void)(v))
+5 -4
View File
@@ -406,16 +406,17 @@ guest_walk_tables(const struct vcpu *v, struct p2m_domain *p2m,
#if GUEST_PAGING_LEVELS >= 4 /* 64-bit only... */
/*
* If all access checks are thus far ok, check Protection Key for 64bit
* data accesses to user mappings.
* data accesses.
*
* N.B. In the case that the walk ended with a superpage, the fabricated
* gw->l1e contains the appropriate leaf pkey.
*/
if ( (ar & _PAGE_USER) && !(walk & PFEC_insn_fetch) &&
guest_pku_enabled(v) )
if ( !(walk & PFEC_insn_fetch) &&
((ar & _PAGE_USER) ? guest_pku_enabled(v)
: guest_pks_enabled(v)) )
{
unsigned int pkey = guest_l1e_get_pkey(gw->l1e);
unsigned int pkr = rdpkru();
unsigned int pkr = (ar & _PAGE_USER) ? rdpkru() : rdpkrs();
unsigned int pk_ar = (pkr >> (pkey * PKEY_WIDTH)) & (PKEY_AD | PKEY_WD);
if ( (pk_ar & PKEY_AD) ||
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.