mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2026-01-04 23:24:56 +00:00
hv: keylocker: Support keylocker backup MSRs for Guest VM
The logical processor scoped IWKey can be copied to or from a platform-scope storage copy called IWKeyBackup. Copying IWKey to IWKeyBackup is called ‘backing up IWKey’ and copying from IWKeyBackup to IWKey is called ‘restoring IWKey’. IWKeyBackup and the path between it and IWKey are protected against software and simple hardware attacks. This means that IWKeyBackup can be used to distribute an IWKey within the logical processors in a platform in a protected manner. Linux keylocker implementation uses this feature, so they are introduced by this patch. Tracked-On: #5695 Signed-off-by: Shuo A Liu <shuo.a.liu@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
@@ -270,6 +270,7 @@ static void vcpu_reset_internal(struct acrn_vcpu *vcpu, enum reset_mode mode)
|
||||
}
|
||||
|
||||
init_iwkey(vcpu);
|
||||
vcpu->arch.iwkey_copy_status = 0UL;
|
||||
}
|
||||
|
||||
struct acrn_vcpu *get_running_vcpu(uint16_t pcpu_id)
|
||||
|
||||
@@ -468,6 +468,7 @@ int32_t create_vm(uint16_t vm_id, uint64_t pcpu_bitmap, struct acrn_vm_config *v
|
||||
spinlock_init(&vm->vlapic_mode_lock);
|
||||
spinlock_init(&vm->ept_lock);
|
||||
spinlock_init(&vm->emul_mmio_lock);
|
||||
spinlock_init(&vm->arch_vm.iwkey_backup_lock);
|
||||
|
||||
vm->arch_vm.vlapic_mode = VM_VLAPIC_XAPIC;
|
||||
vm->intr_inject_delay_delta = 0UL;
|
||||
@@ -717,6 +718,7 @@ int32_t reset_vm(struct acrn_vm *vm)
|
||||
reset_vioapics(vm);
|
||||
destroy_secure_world(vm, false);
|
||||
vm->sworld_control.flag.active = 0UL;
|
||||
vm->arch_vm.iwkey_backup_status = 0UL;
|
||||
vm->state = VM_CREATED;
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -61,6 +61,12 @@ static const uint32_t emulated_guest_msrs[NUM_GUEST_MSRS] = {
|
||||
|
||||
MSR_IA32_XSS,
|
||||
|
||||
/* KeyLocker backup MSRs */
|
||||
MSR_IA32_COPY_LOCAL_TO_PLATFORM,
|
||||
MSR_IA32_COPY_PLATFORM_TO_LOCAL,
|
||||
MSR_IA32_COPY_STATUS,
|
||||
MSR_IA32_IWKEY_BACKUP_STATUS,
|
||||
|
||||
MSR_TEST_CTL,
|
||||
};
|
||||
|
||||
@@ -402,6 +408,17 @@ static int32_t write_pat_msr(struct acrn_vcpu *vcpu, uint64_t value)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @pre vcpu != NULL
|
||||
*/
|
||||
bool is_iwkey_backup_support(struct acrn_vcpu *vcpu)
|
||||
{
|
||||
uint32_t eax = 0x19U, ebx = 0U, ecx = 0U, edx = 0U;
|
||||
|
||||
guest_cpuid(vcpu, &eax, &ebx, &ecx, &edx);
|
||||
return (ebx & CPUID_EBX_KL_BACKUP_MSR) == CPUID_EBX_KL_BACKUP_MSR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @pre vcpu != NULL
|
||||
*/
|
||||
@@ -516,6 +533,24 @@ int32_t rdmsr_vmexit_handler(struct acrn_vcpu *vcpu)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MSR_IA32_COPY_STATUS:
|
||||
{
|
||||
if (is_iwkey_backup_support(vcpu)) {
|
||||
v = vcpu->arch.iwkey_copy_status;
|
||||
} else {
|
||||
err = -EACCES;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MSR_IA32_IWKEY_BACKUP_STATUS:
|
||||
{
|
||||
if (is_iwkey_backup_support(vcpu)) {
|
||||
v = vcpu->vm->arch_vm.iwkey_backup_status;
|
||||
} else {
|
||||
err = -EACCES;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MSR_TEST_CTL:
|
||||
{
|
||||
/* If has MSR_TEST_CTL, give emulated value
|
||||
@@ -842,6 +877,40 @@ int32_t wrmsr_vmexit_handler(struct acrn_vcpu *vcpu)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MSR_IA32_COPY_LOCAL_TO_PLATFORM:
|
||||
{
|
||||
if ((v == 0x1UL) && is_iwkey_backup_support(vcpu)) {
|
||||
vcpu->vm->arch_vm.iwkey_backup_status = 0UL;
|
||||
spinlock_obtain(&vcpu->vm->arch_vm.iwkey_backup_lock);
|
||||
vcpu->vm->arch_vm.iwkey_backup = vcpu->arch.IWKey;
|
||||
spinlock_release(&vcpu->vm->arch_vm.iwkey_backup_lock);
|
||||
/*
|
||||
* Keylocker spec 0.76 Table 4-1:
|
||||
* 'Backup/restore valid' bit and 'IWKeyBackup consumed' bit
|
||||
*/
|
||||
vcpu->vm->arch_vm.iwkey_backup_status = 0x9UL;
|
||||
vcpu->arch.iwkey_copy_status = 1UL;
|
||||
} else {
|
||||
err = -EINVAL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MSR_IA32_COPY_PLATFORM_TO_LOCAL:
|
||||
{
|
||||
if ((v == 0x1UL) && is_iwkey_backup_support(vcpu) &&
|
||||
(vcpu->vm->arch_vm.iwkey_backup_status == 0x9UL)) {
|
||||
spinlock_obtain(&vcpu->vm->arch_vm.iwkey_backup_lock);
|
||||
vcpu->arch.IWKey = vcpu->vm->arch_vm.iwkey_backup;
|
||||
spinlock_release(&vcpu->vm->arch_vm.iwkey_backup_lock);
|
||||
/* Load the new iwkey for this vcpu */
|
||||
get_cpu_var(whose_iwkey) = NULL;
|
||||
load_iwkey(vcpu);
|
||||
vcpu->arch.iwkey_copy_status = 1UL;
|
||||
} else {
|
||||
err = -EINVAL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MSR_TEST_CTL:
|
||||
{
|
||||
/* If VM has MSR_TEST_CTL, ignore write operation
|
||||
|
||||
Reference in New Issue
Block a user