Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull more kvm updates from Paolo Bonzini:
"New x86 features:
- Guest API and guest kernel support for SEV live migration
- SEV and SEV-ES intra-host migration
Bugfixes and cleanups for x86:
- Fix misuse of gfn-to-pfn cache when recording guest steal time /
preempted status
- Fix selftests on APICv machines
- Fix sparse warnings
- Fix detection of KVM features in CPUID
- Cleanups for bogus writes to MSR_KVM_PV_EOI_EN
- Fixes and cleanups for MSR bitmap handling
- Cleanups for INVPCID
- Make x86 KVM_SOFT_MAX_VCPUS consistent with other architectures
Bugfixes for ARM:
- Fix finalization of host stage2 mappings
- Tighten the return value of kvm_vcpu_preferred_target()
- Make sure the extraction of ESR_ELx.EC is limited to architected
bits"
* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: (34 commits)
KVM: SEV: unify cgroup cleanup code for svm_vm_migrate_from
KVM: x86: move guest_pv_has out of user_access section
KVM: x86: Drop arbitrary KVM_SOFT_MAX_VCPUS
KVM: Move INVPCID type check from vmx and svm to the common kvm_handle_invpcid()
KVM: VMX: Add a helper function to retrieve the GPR index for INVPCID, INVVPID, and INVEPT
KVM: nVMX: Clean up x2APIC MSR handling for L2
KVM: VMX: Macrofy the MSR bitmap getters and setters
KVM: nVMX: Handle dynamic MSR intercept toggling
KVM: nVMX: Query current VMCS when determining if MSR bitmaps are in use
KVM: x86: Don't update vcpu->arch.pv_eoi.msr_val when a bogus value was written to MSR_KVM_PV_EOI_EN
KVM: x86: Rename kvm_lapic_enable_pv_eoi()
KVM: x86: Make sure KVM_CPUID_FEATURES really are KVM_CPUID_FEATURES
KVM: x86: Add helper to consolidate core logic of SET_CPUID{2} flows
kvm: mmu: Use fast PF path for access tracking of huge pages when possible
KVM: x86/mmu: Properly dereference rcu-protected TDP MMU sptep iterator
KVM: x86: inhibit APICv when KVM_GUESTDBG_BLOCKIRQ active
kvm: x86: Convert return type of *is_valid_rdpmc_ecx() to bool
KVM: x86: Fix recording of guest steal time / preempted status
selftest: KVM: Add intra host migration tests
selftest: KVM: Add open sev dev helper
...
This commit is contained in:
@@ -28,6 +28,7 @@
|
||||
#include <linux/swait.h>
|
||||
#include <linux/syscore_ops.h>
|
||||
#include <linux/cc_platform.h>
|
||||
#include <linux/efi.h>
|
||||
#include <asm/timer.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/traps.h>
|
||||
@@ -41,6 +42,7 @@
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/reboot.h>
|
||||
#include <asm/svm.h>
|
||||
#include <asm/e820/api.h>
|
||||
|
||||
DEFINE_STATIC_KEY_FALSE(kvm_async_pf_enabled);
|
||||
|
||||
@@ -434,6 +436,8 @@ static void kvm_guest_cpu_offline(bool shutdown)
|
||||
kvm_disable_steal_time();
|
||||
if (kvm_para_has_feature(KVM_FEATURE_PV_EOI))
|
||||
wrmsrl(MSR_KVM_PV_EOI_EN, 0);
|
||||
if (kvm_para_has_feature(KVM_FEATURE_MIGRATION_CONTROL))
|
||||
wrmsrl(MSR_KVM_MIGRATION_CONTROL, 0);
|
||||
kvm_pv_disable_apf();
|
||||
if (!shutdown)
|
||||
apf_task_wake_all();
|
||||
@@ -548,6 +552,55 @@ static void kvm_send_ipi_mask_allbutself(const struct cpumask *mask, int vector)
|
||||
__send_ipi_mask(local_mask, vector);
|
||||
}
|
||||
|
||||
static int __init setup_efi_kvm_sev_migration(void)
|
||||
{
|
||||
efi_char16_t efi_sev_live_migration_enabled[] = L"SevLiveMigrationEnabled";
|
||||
efi_guid_t efi_variable_guid = AMD_SEV_MEM_ENCRYPT_GUID;
|
||||
efi_status_t status;
|
||||
unsigned long size;
|
||||
bool enabled;
|
||||
|
||||
if (!cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT) ||
|
||||
!kvm_para_has_feature(KVM_FEATURE_MIGRATION_CONTROL))
|
||||
return 0;
|
||||
|
||||
if (!efi_enabled(EFI_BOOT))
|
||||
return 0;
|
||||
|
||||
if (!efi_enabled(EFI_RUNTIME_SERVICES)) {
|
||||
pr_info("%s : EFI runtime services are not enabled\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
size = sizeof(enabled);
|
||||
|
||||
/* Get variable contents into buffer */
|
||||
status = efi.get_variable(efi_sev_live_migration_enabled,
|
||||
&efi_variable_guid, NULL, &size, &enabled);
|
||||
|
||||
if (status == EFI_NOT_FOUND) {
|
||||
pr_info("%s : EFI live migration variable not found\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (status != EFI_SUCCESS) {
|
||||
pr_info("%s : EFI variable retrieval failed\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (enabled == 0) {
|
||||
pr_info("%s: live migration disabled in EFI\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pr_info("%s : live migration enabled in EFI\n", __func__);
|
||||
wrmsrl(MSR_KVM_MIGRATION_CONTROL, KVM_MIGRATION_READY);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
late_initcall(setup_efi_kvm_sev_migration);
|
||||
|
||||
/*
|
||||
* Set the IPI entry points
|
||||
*/
|
||||
@@ -756,7 +809,7 @@ static noinline uint32_t __kvm_cpuid_base(void)
|
||||
return 0; /* So we don't blow up on old processors */
|
||||
|
||||
if (boot_cpu_has(X86_FEATURE_HYPERVISOR))
|
||||
return hypervisor_cpuid_base("KVMKVMKVM\0\0\0", 0);
|
||||
return hypervisor_cpuid_base(KVM_SIGNATURE, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -806,8 +859,62 @@ static bool __init kvm_msi_ext_dest_id(void)
|
||||
return kvm_para_has_feature(KVM_FEATURE_MSI_EXT_DEST_ID);
|
||||
}
|
||||
|
||||
static void kvm_sev_hc_page_enc_status(unsigned long pfn, int npages, bool enc)
|
||||
{
|
||||
kvm_sev_hypercall3(KVM_HC_MAP_GPA_RANGE, pfn << PAGE_SHIFT, npages,
|
||||
KVM_MAP_GPA_RANGE_ENC_STAT(enc) | KVM_MAP_GPA_RANGE_PAGE_SZ_4K);
|
||||
}
|
||||
|
||||
static void __init kvm_init_platform(void)
|
||||
{
|
||||
if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT) &&
|
||||
kvm_para_has_feature(KVM_FEATURE_MIGRATION_CONTROL)) {
|
||||
unsigned long nr_pages;
|
||||
int i;
|
||||
|
||||
pv_ops.mmu.notify_page_enc_status_changed =
|
||||
kvm_sev_hc_page_enc_status;
|
||||
|
||||
/*
|
||||
* Reset the host's shared pages list related to kernel
|
||||
* specific page encryption status settings before we load a
|
||||
* new kernel by kexec. Reset the page encryption status
|
||||
* during early boot intead of just before kexec to avoid SMP
|
||||
* races during kvm_pv_guest_cpu_reboot().
|
||||
* NOTE: We cannot reset the complete shared pages list
|
||||
* here as we need to retain the UEFI/OVMF firmware
|
||||
* specific settings.
|
||||
*/
|
||||
|
||||
for (i = 0; i < e820_table->nr_entries; i++) {
|
||||
struct e820_entry *entry = &e820_table->entries[i];
|
||||
|
||||
if (entry->type != E820_TYPE_RAM)
|
||||
continue;
|
||||
|
||||
nr_pages = DIV_ROUND_UP(entry->size, PAGE_SIZE);
|
||||
|
||||
kvm_sev_hypercall3(KVM_HC_MAP_GPA_RANGE, entry->addr,
|
||||
nr_pages,
|
||||
KVM_MAP_GPA_RANGE_ENCRYPTED | KVM_MAP_GPA_RANGE_PAGE_SZ_4K);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure that _bss_decrypted section is marked as decrypted in the
|
||||
* shared pages list.
|
||||
*/
|
||||
nr_pages = DIV_ROUND_UP(__end_bss_decrypted - __start_bss_decrypted,
|
||||
PAGE_SIZE);
|
||||
early_set_mem_enc_dec_hypercall((unsigned long)__start_bss_decrypted,
|
||||
nr_pages, 0);
|
||||
|
||||
/*
|
||||
* If not booted using EFI, enable Live migration support.
|
||||
*/
|
||||
if (!efi_enabled(EFI_BOOT))
|
||||
wrmsrl(MSR_KVM_MIGRATION_CONTROL,
|
||||
KVM_MIGRATION_READY);
|
||||
}
|
||||
kvmclock_init();
|
||||
x86_platform.apic_post_init = kvm_apic_init;
|
||||
}
|
||||
|
||||
@@ -337,6 +337,7 @@ struct paravirt_patch_template pv_ops = {
|
||||
(void (*)(struct mmu_gather *, void *))tlb_remove_page,
|
||||
|
||||
.mmu.exit_mmap = paravirt_nop,
|
||||
.mmu.notify_page_enc_status_changed = paravirt_nop,
|
||||
|
||||
#ifdef CONFIG_PARAVIRT_XXL
|
||||
.mmu.read_cr2 = __PV_IS_CALLEE_SAVE(pv_native_read_cr2),
|
||||
|
||||
Reference in New Issue
Block a user