diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 76102efbf0796631f490fe0b1056bd6df18a52fa..74995f0a2a3cbc0805b05904686fc9f4df82e410 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -1185,7 +1185,15 @@ __gfn_to_memslot(struct kvm_memslots *slots, gfn_t gfn) static inline unsigned long __gfn_to_hva_memslot(const struct kvm_memory_slot *slot, gfn_t gfn) { - return slot->userspace_addr + (gfn - slot->base_gfn) * PAGE_SIZE; + /* + * The index was checked originally in search_memslots. To avoid + * that a malicious guest builds a Spectre gadget out of e.g. page + * table walks, do not let the processor speculate loads outside + * the guest's registered memslots. + */ + unsigned long offset = array_index_nospec(gfn - slot->base_gfn, + slot->npages); + return slot->userspace_addr + offset * PAGE_SIZE; } static inline int memslot_id(struct kvm *kvm, gfn_t gfn)