[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PULL 55/63] kvm: handle KVM_EXIT_MEMORY_FAULT
|
From: |
Peter Maydell |
|
Subject: |
Re: [PULL 55/63] kvm: handle KVM_EXIT_MEMORY_FAULT |
|
Date: |
Fri, 26 Apr 2024 14:40:09 +0100 |
On Tue, 23 Apr 2024 at 16:16, Paolo Bonzini <pbonzini@redhat.com> wrote:
>
> From: Chao Peng <chao.p.peng@linux.intel.com>
>
> Upon an KVM_EXIT_MEMORY_FAULT exit, userspace needs to do the memory
> conversion on the RAMBlock to turn the memory into desired attribute,
> switching between private and shared.
>
> Currently only KVM_MEMORY_EXIT_FLAG_PRIVATE in flags is valid when
> KVM_EXIT_MEMORY_FAULT happens.
>
> Note, KVM_EXIT_MEMORY_FAULT makes sense only when the RAMBlock has
> guest_memfd memory backend.
>
> Note, KVM_EXIT_MEMORY_FAULT returns with -EFAULT, so special handling is
> added.
>
> When page is converted from shared to private, the original shared
> memory can be discarded via ram_block_discard_range(). Note, shared
> memory can be discarded only when it's not back'ed by hugetlb because
> hugetlb is supposed to be pre-allocated and no need for discarding.
>
> Signed-off-by: Chao Peng <chao.p.peng@linux.intel.com>
> Co-developed-by: Xiaoyao Li <xiaoyao.li@intel.com>
> Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
>
> Message-ID: <20240320083945.991426-13-michael.roth@amd.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Hi; Coverity points out an issue with this code (CID 1544114):
> +int kvm_convert_memory(hwaddr start, hwaddr size, bool to_private)
> +{
> + MemoryRegionSection section;
> + ram_addr_t offset;
offset here is not initialized...
> + MemoryRegion *mr;
> + RAMBlock *rb;
> + void *addr;
> + int ret = -1;
> +
> + trace_kvm_convert_memory(start, size, to_private ? "shared_to_private" :
> "private_to_shared");
> +
> + if (!QEMU_PTR_IS_ALIGNED(start, qemu_real_host_page_size()) ||
> + !QEMU_PTR_IS_ALIGNED(size, qemu_real_host_page_size())) {
> + return -1;
> + }
> +
> + if (!size) {
> + return -1;
> + }
> +
> + section = memory_region_find(get_system_memory(), start, size);
> + mr = section.mr;
> + if (!mr) {
> + return -1;
> + }
> +
> + if (!memory_region_has_guest_memfd(mr)) {
> + error_report("Converting non guest_memfd backed memory region "
> + "(0x%"HWADDR_PRIx" ,+ 0x%"HWADDR_PRIx") to %s",
> + start, size, to_private ? "private" : "shared");
> + goto out_unref;
> + }
> +
> + if (to_private) {
> + ret = kvm_set_memory_attributes_private(start, size);
> + } else {
> + ret = kvm_set_memory_attributes_shared(start, size);
> + }
> + if (ret) {
> + goto out_unref;
> + }
> +
> + addr = memory_region_get_ram_ptr(mr) + section.offset_within_region;
> + rb = qemu_ram_block_from_host(addr, false, &offset);
...and this call to qemu_ram_block_from_host() will only initialize
offset if it does not fail (i.e. doesn't return NULL)...
> +
> + if (to_private) {
> + if (rb->page_size != qemu_real_host_page_size()) {
...but here we assume rb is not NULL...
> + /*
> + * shared memory is backed by hugetlb, which is supposed to be
> + * pre-allocated and doesn't need to be discarded
> + */
> + goto out_unref;
> + }
> + ret = ram_block_discard_range(rb, offset, size);
> + } else {
> + ret = ram_block_discard_guest_memfd_range(rb, offset, size);
...and here we use offset assuming it has been initialized.
I think this code should either handle the case where
qemu_ram_block_from_host() fails, or, if it is impossible
for it to fail in this situation, add an assert() and a
comment about why we know it can't fail.
> + }
> +
> +out_unref:
> + memory_region_unref(mr);
> + return ret;
> +}
thanks
-- PMM
- [PULL 20/63] vga: move dirty memory region code together, (continued)
- [PULL 20/63] vga: move dirty memory region code together, Paolo Bonzini, 2024/04/23
- [PULL 23/63] target/i386: add guest-phys-bits cpu property, Paolo Bonzini, 2024/04/23
- [PULL 25/63] i386/kvm: Move architectural CPUID leaf generation to separate helper, Paolo Bonzini, 2024/04/23
- [PULL 30/63] q35: Introduce smm_ranges property for q35-pci-host, Paolo Bonzini, 2024/04/23
- [PULL 39/63] runstate: skip initial CPU reset if reset is not actually possible, Paolo Bonzini, 2024/04/23
- [PULL 48/63] kvm: Introduce support for memory_attributes, Paolo Bonzini, 2024/04/23
- [PULL 38/63] linux-headers: update to current kvm/next, Paolo Bonzini, 2024/04/23
- [PULL 53/63] RAMBlock: make guest_memfd require uncoordinated discard, Paolo Bonzini, 2024/04/23
- [PULL 55/63] kvm: handle KVM_EXIT_MEMORY_FAULT, Paolo Bonzini, 2024/04/23
- Re: [PULL 55/63] kvm: handle KVM_EXIT_MEMORY_FAULT,
Peter Maydell <=
- [PULL 54/63] physmem: Introduce ram_block_discard_guest_memfd_range(), Paolo Bonzini, 2024/04/23
- [PULL 24/63] kvm: add support for guest physical bits, Paolo Bonzini, 2024/04/23
- [PULL 60/63] target/i386/cpu: Merge the warning and error messages for AMD HT check, Paolo Bonzini, 2024/04/23
- [PULL 63/63] target/i386/translate.c: always write 32-bits for SGDT and SIDT, Paolo Bonzini, 2024/04/23
- [PULL 42/63] target/i386: introduce x86-confidential-guest, Paolo Bonzini, 2024/04/23
- [PULL 15/63] colo: move stubs out of stubs/, Paolo Bonzini, 2024/04/23
- Re: [PULL 00/63] First batch of i386 and build system patch for QEMU 9.1, Richard Henderson, 2024/04/24