On 7/21/19 3:57 PM, David Rientjes wrote: > On Wed, 10 Jul 2019, Singh, Brijesh wrote: > >> diff --git a/Documentation/virtual/kvm/hypercalls.txt b/Documentation/virtual/kvm/hypercalls.txt >> index da24c138c8d1..94f0611f4d88 100644 >> --- a/Documentation/virtual/kvm/hypercalls.txt >> +++ b/Documentation/virtual/kvm/hypercalls.txt >> @@ -141,3 +141,17 @@ a0 corresponds to the APIC ID in the third argument (a2), bit 1 >> corresponds to the APIC ID a2+1, and so on. >> >> Returns the number of CPUs to which the IPIs were delivered successfully. >> + >> +7. KVM_HC_PAGE_ENC_STATUS >> +------------------------- >> +Architecture: x86 >> +Status: active >> +Purpose: Notify the encryption status changes in guest page table (SEV guest) >> + >> +a0: the guest physical address of the start page >> +a1: the number of pages >> +a2: encryption attribute >> + >> + Where: >> + * 1: Encryption attribute is set >> + * 0: Encryption attribute is cleared >> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h >> index 26d1eb83f72a..b463a81dc176 100644 >> --- a/arch/x86/include/asm/kvm_host.h >> +++ b/arch/x86/include/asm/kvm_host.h >> @@ -1199,6 +1199,8 @@ struct kvm_x86_ops { >> uint16_t (*nested_get_evmcs_version)(struct kvm_vcpu *vcpu); >> >> bool (*need_emulation_on_page_fault)(struct kvm_vcpu *vcpu); >> + int (*page_enc_status_hc)(struct kvm *kvm, unsigned long gpa, >> + unsigned long sz, unsigned long mode); >> }; >> >> struct kvm_arch_async_pf { >> diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c >> index 3089942f6630..431718309359 100644 >> --- a/arch/x86/kvm/svm.c >> +++ b/arch/x86/kvm/svm.c >> @@ -135,6 +135,8 @@ struct kvm_sev_info { >> int fd; /* SEV device fd */ >> unsigned long pages_locked; /* Number of pages locked */ >> struct list_head regions_list; /* List of registered regions */ >> + unsigned long *page_enc_bmap; >> + unsigned long page_enc_bmap_size; >> }; >> >> struct kvm_svm { >> @@ -1910,6 +1912,8 @@ static void sev_vm_destroy(struct kvm *kvm) >> >> sev_unbind_asid(kvm, sev->handle); >> sev_asid_free(kvm); >> + >> + kvfree(sev->page_enc_bmap); >> } >> >> static void avic_vm_destroy(struct kvm *kvm) > > Adding Cfir who flagged this kvfree(). > > Other freeing of sev->page_enc_bmap in this patch also set > sev->page_enc_bmap_size to 0 and neither set sev->page_enc_bmap to NULL > after freeing it. > > For extra safety, is it possible to sev->page_enc_bmap = NULL anytime the > bitmap is kvfreed? > Good catch, I'll fix it in next rev. >> @@ -2084,6 +2088,7 @@ static void avic_set_running(struct kvm_vcpu *vcpu, bool is_run) >> >> static void svm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) >> { >> + struct kvm_sev_info *sev = &to_kvm_svm(vcpu->kvm)->sev_info; >> struct vcpu_svm *svm = to_svm(vcpu); >> u32 dummy; >> u32 eax = 1; >> @@ -2105,6 +2110,12 @@ static void svm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) >> >> if (kvm_vcpu_apicv_active(vcpu) && !init_event) >> avic_update_vapic_bar(svm, APIC_DEFAULT_PHYS_BASE); >> + >> + /* reset the page encryption bitmap */ >> + if (sev_guest(vcpu->kvm)) { >> + kvfree(sev->page_enc_bmap); >> + sev->page_enc_bmap_size = 0; >> + } >> } >> >> static int avic_init_vcpu(struct vcpu_svm *svm) > > What is protecting sev->page_enc_bmap and sev->page_enc_bmap_size in calls > to svm_vcpu_reset()? > Yes, it need to be protected with vm lock. I will fix it in next rev. Additionally, I think what I have here is wrong, we need to reset the bitmap only when bsp is getting reset. -Brijesh