Currently kvm_vcpu_pre_fault_memory() is the only place where generic code can call vcpu_load() on a vCPU that has not yet been initialised.
This can be problematic, as being uninitialised, a vCPU might not be in a state where it is correct to do so. Provide kvm_arch_vcpu_allow_pre_fault_memory() to allow architectures to override this behaviour before the load is attempted. Implement it as a __weak symbol defaulting to the current state where it is always permitted. This lays the foundation for a future change which implements pre-faulting for arm64 which will wish to disallow this for uninitialised vCPUs. As no architecture currently overrides it, no functional change intended. Suggested-by: Oliver Upton <[email protected]> Signed-off-by: Lorenzo Stoakes (ARM) <[email protected]> --- include/linux/kvm_host.h | 1 + virt/kvm/kvm_main.c | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 03bfc92864b6..c11fda8704a3 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -1693,6 +1693,7 @@ int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu); bool kvm_arch_dy_runnable(struct kvm_vcpu *vcpu); bool kvm_arch_dy_has_pending_interrupt(struct kvm_vcpu *vcpu); bool kvm_arch_vcpu_preempted_in_kernel(struct kvm_vcpu *vcpu); +bool kvm_arch_vcpu_allow_pre_fault_memory(struct kvm_vcpu *vcpu); void kvm_arch_pre_destroy_vm(struct kvm *kvm); void kvm_arch_create_vm_debugfs(struct kvm *kvm); diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 65eb26a0520d..9662baf2bfca 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -3961,6 +3961,11 @@ bool __weak kvm_arch_dy_has_pending_interrupt(struct kvm_vcpu *vcpu) return false; } +bool __weak kvm_arch_vcpu_allow_pre_fault_memory(struct kvm_vcpu *vcpu) +{ + return true; +} + void kvm_vcpu_on_spin(struct kvm_vcpu *me, bool yield_to_kernel_mode) { int nr_vcpus, start, i, idx, yielded; @@ -4365,6 +4370,9 @@ static int kvm_vcpu_pre_fault_memory(struct kvm_vcpu *vcpu, range->gpa + range->size <= range->gpa) return -EINVAL; + if (!kvm_arch_vcpu_allow_pre_fault_memory(vcpu)) + return -ENOEXEC; + vcpu_load(vcpu); idx = srcu_read_lock(&vcpu->kvm->srcu); -- 2.55.0

