target/i86: implement PKS

Protection Keys for Supervisor-mode pages is a simple extension of
the PKU feature that QEMU already implements.  For supervisor-mode
pages, protection key restrictions come from a new MSR.  The MSR
has no XSAVE state associated to it.

PKS is only respected in long mode.  However, in principle it is
possible to set the MSR even outside long mode, and in fact
even the XSAVE state for PKRU could be set outside long mode
using XRSTOR.  So do not limit the migration subsections for
PKRU and PKRS to long mode.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Paolo Bonzini 2021-01-27 09:28:49 +01:00
parent 51909241d2
commit e7e7bdabab
6 changed files with 64 additions and 18 deletions

View file

@ -244,6 +244,7 @@ void helper_rdmsr(CPUX86State *env)
void helper_wrmsr(CPUX86State *env)
{
uint64_t val;
CPUState *cs = env_cpu(env);
cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 1, GETPC());
@ -296,6 +297,13 @@ void helper_wrmsr(CPUX86State *env)
case MSR_PAT:
env->pat = val;
break;
case MSR_IA32_PKRS:
if (val & 0xFFFFFFFF00000000ull) {
goto error;
}
env->pkrs = val;
tlb_flush(cs);
break;
case MSR_VM_HSAVE_PA:
env->vm_hsave = val;
break;
@ -399,6 +407,9 @@ void helper_wrmsr(CPUX86State *env)
/* XXX: exception? */
break;
}
return;
error:
raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC());
}
void helper_rdmsr(CPUX86State *env)
@ -430,6 +441,9 @@ void helper_rdmsr(CPUX86State *env)
case MSR_PAT:
val = env->pat;
break;
case MSR_IA32_PKRS:
val = env->pkrs;
break;
case MSR_VM_HSAVE_PA:
val = env->vm_hsave;
break;