Re: [PATCH] LoongArch: KVM: Allow to set pv_feature until vCPU run
Bibo Mao <[email protected]> Thu, 16 Jul 2026 14:12:59 +0800
| Newsgroups | dev.linux.lists.loongarch,org.kernel.vger.kvm,org.kernel.vger.linux-kernel,org.kernel.vger.linux-kselftest |
|---|---|
| Message-ID | <[email protected]> |
On 2026/7/16 下午12:46, Tao Cui wrote: > > > 在 2026/7/16 09:38, Bibo Mao 写道: >> Now pv_feature can be set only once, there is problem with VM migration. >> Where it is set when vCPU is created and after migration, here it is >> allow to set for many times, until vCPU starts to run. >> > Hi Bibo, > > The Sashiko AI review raised two concerns on this patch that I think > are valid: > > 1. Since ran_atleast_once is per-vCPU but pv_features is VM-wide, > userspace could run vCPU 0 and then use vCPU 1 (whose > ran_atleast_once is still false) to change pv_features while > vCPU 0 is executing. > > 2. Without the old LOONGARCH_PV_FEAT_UPDATED latch, setting different > PV features on different un-run vCPUs silently overwrites > pv_features instead of returning -EINVAL. > > Both stem from using a per-vCPU flag to protect VM-wide state. > Would a VM-level bool in kvm_arch (e.g. pv_features_configured), > set on first SET_ATTR or first RUN of any vCPU, work? It would > not be migrated since it is not exposed via any ioctl. Now pv_features is per VM, will set it as per CPU to avoid access contention in next version. Consistent checking should with per CPU pv_features will be done in VMM, rather than KVM, similar with per CPU cpucfg feature. Regards Bibo Mao > > Thanks, > Tao >> Signed-off-by: Bibo Mao <[email protected]> >> --- >> arch/loongarch/include/asm/kvm_host.h | 4 +++- >> arch/loongarch/kvm/vcpu.c | 15 +++++++++++---- >> 2 files changed, 14 insertions(+), 5 deletions(-) >> >> diff --git a/arch/loongarch/include/asm/kvm_host.h b/arch/loongarch/include/asm/kvm_host.h >> index 23cfbecebbd7..af376fc44c44 100644 >> --- a/arch/loongarch/include/asm/kvm_host.h >> +++ b/arch/loongarch/include/asm/kvm_host.h >> @@ -163,7 +163,6 @@ enum emulation_result { >> #define KVM_LARCH_SWCSR_LATEST (0x1 << 3) >> #define KVM_LARCH_HWCSR_USABLE (0x1 << 4) >> >> -#define LOONGARCH_PV_FEAT_UPDATED BIT_ULL(63) >> #define LOONGARCH_PV_FEAT_MASK (BIT(KVM_FEATURE_IPI) | \ >> BIT(KVM_FEATURE_PREEMPT) | \ >> BIT(KVM_FEATURE_STEAL_TIME) | \ >> @@ -250,6 +249,9 @@ struct kvm_vcpu_arch { >> /* cpucfg */ >> u32 cpucfg[KVM_MAX_CPUCFG_REGS]; >> >> + /* VCPU ran at least once */ >> + bool ran_atleast_once; >> + >> /* paravirt steal time */ >> struct { >> u64 guest_addr; >> diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c >> index 20c207d80e31..ce6a1b06d50d 100644 >> --- a/arch/loongarch/kvm/vcpu.c >> +++ b/arch/loongarch/kvm/vcpu.c >> @@ -1164,11 +1164,14 @@ static int kvm_loongarch_cpucfg_set_attr(struct kvm_vcpu *vcpu, >> if (val & ~valid) >> return -EINVAL; >> >> - /* All vCPUs need set the same PV features */ >> - if ((kvm->arch.pv_features & LOONGARCH_PV_FEAT_UPDATED) >> - && ((kvm->arch.pv_features & valid) != val)) >> + if ((kvm->arch.pv_features & valid) == val) >> + return 0; >> + >> + if (vcpu->arch.ran_atleast_once) >> return -EINVAL; >> - kvm->arch.pv_features = val | LOONGARCH_PV_FEAT_UPDATED; >> + >> + /* All vCPUs need set the same PV features */ >> + kvm->arch.pv_features = val; >> return 0; >> default: >> return -ENXIO; >> @@ -1851,6 +1854,10 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) >> int r = -EINTR; >> struct kvm_run *run = vcpu->run; >> >> + /* Mark this VCPU ran at least once */ >> + if (!vcpu->arch.ran_atleast_once) >> + vcpu->arch.ran_atleast_once = true; >> + >> if (vcpu->mmio_needed) { >> if (!vcpu->mmio_is_write) >> kvm_complete_mmio_read(vcpu, run); >> >> base-commit: a13c140cc289c0b7b3770bce5b3ad42ab35074aa >