[PATCH] KVM: x86: Move PIT existence checks into the PIT ioctl helpers

From: Ingyu Jang

Date: Mon Oct 26 2026 - 20:16:27 EST


kvm_vm_ioctl_get_pit() and kvm_vm_ioctl_get_pit2() always return 0,
so the error checks on their return values in kvm_arch_vm_ioctl()
never trigger.

Move the !kvm->arch.vpit checks from the callers into the PIT ioctl
helpers, so that these error checks handle the missing PIT case.

Suggested-by: Sean Christopherson <seanjc@xxxxxxxxxx>
Link: https://lore.kernel.org/all/aYFE-tGOPtKlSWhn@xxxxxxxxxx
Signed-off-by: Ingyu Jang <ingyujang25@xxxxxxxxxxx>
---
arch/x86/kvm/i8254.c | 18 +++++++++++++++++-
arch/x86/kvm/x86.c | 17 -----------------
2 files changed, 17 insertions(+), 18 deletions(-)

diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
index 1982b0077ddda..311d0e8cde99b 100644
--- a/arch/x86/kvm/i8254.c
+++ b/arch/x86/kvm/i8254.c
@@ -651,8 +651,12 @@ static void pit_mask_notifier(struct kvm_irq_mask_notifier *kimn, bool mask)

int kvm_vm_ioctl_get_pit(struct kvm *kvm, struct kvm_pit_state *ps)
{
- struct kvm_kpit_state *kps = &kvm->arch.vpit->pit_state;
+ struct kvm_kpit_state *kps;

+ if (!kvm->arch.vpit)
+ return -ENXIO;
+
+ kps = &kvm->arch.vpit->pit_state;
BUILD_BUG_ON(sizeof(*ps) != sizeof(kps->channels));

mutex_lock(&kps->lock);
@@ -666,6 +670,9 @@ int kvm_vm_ioctl_set_pit(struct kvm *kvm, struct kvm_pit_state *ps)
int i;
struct kvm_pit *pit = kvm->arch.vpit;

+ if (!pit)
+ return -ENXIO;
+
mutex_lock(&pit->pit_state.lock);
memcpy(&pit->pit_state.channels, ps, sizeof(*ps));
for (i = 0; i < 3; i++)
@@ -676,6 +683,9 @@ int kvm_vm_ioctl_set_pit(struct kvm *kvm, struct kvm_pit_state *ps)

int kvm_vm_ioctl_get_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps)
{
+ if (!kvm->arch.vpit)
+ return -ENXIO;
+
mutex_lock(&kvm->arch.vpit->pit_state.lock);
memcpy(ps->channels, &kvm->arch.vpit->pit_state.channels,
sizeof(ps->channels));
@@ -692,6 +702,9 @@ int kvm_vm_ioctl_set_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps)
u32 prev_legacy, cur_legacy;
struct kvm_pit *pit = kvm->arch.vpit;

+ if (!pit)
+ return -ENXIO;
+
mutex_lock(&pit->pit_state.lock);
prev_legacy = pit->pit_state.flags & KVM_PIT_FLAGS_HPET_LEGACY;
cur_legacy = ps->flags & KVM_PIT_FLAGS_HPET_LEGACY;
@@ -711,6 +724,9 @@ int kvm_vm_ioctl_reinject(struct kvm *kvm, struct kvm_reinject_control *control)
{
struct kvm_pit *pit = kvm->arch.vpit;

+ if (!pit)
+ return -ENXIO;
+
/* pit->pit_state.lock was overloaded to prevent userspace from getting
* an inconsistent state after running multiple KVM_REINJECT_CONTROL
* ioctls in parallel. Use a separate lock if that ioctl isn't rare.
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 32563a91fba99..ac5900ba83aaf 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4568,9 +4568,6 @@ int kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
r = -EFAULT;
if (copy_from_user(&u.ps, argp, sizeof(struct kvm_pit_state)))
goto out;
- r = -ENXIO;
- if (!kvm->arch.vpit)
- goto out;
r = kvm_vm_ioctl_get_pit(kvm, &u.ps);
if (r)
goto out;
@@ -4585,18 +4582,11 @@ int kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
if (copy_from_user(&u.ps, argp, sizeof(u.ps)))
goto out;
mutex_lock(&kvm->lock);
- r = -ENXIO;
- if (!kvm->arch.vpit)
- goto set_pit_out;
r = kvm_vm_ioctl_set_pit(kvm, &u.ps);
-set_pit_out:
mutex_unlock(&kvm->lock);
break;
}
case KVM_GET_PIT2: {
- r = -ENXIO;
- if (!kvm->arch.vpit)
- goto out;
r = kvm_vm_ioctl_get_pit2(kvm, &u.ps2);
if (r)
goto out;
@@ -4611,11 +4601,7 @@ int kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
if (copy_from_user(&u.ps2, argp, sizeof(u.ps2)))
goto out;
mutex_lock(&kvm->lock);
- r = -ENXIO;
- if (!kvm->arch.vpit)
- goto set_pit2_out;
r = kvm_vm_ioctl_set_pit2(kvm, &u.ps2);
-set_pit2_out:
mutex_unlock(&kvm->lock);
break;
}
@@ -4624,9 +4610,6 @@ int kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
r = -EFAULT;
if (copy_from_user(&control, argp, sizeof(control)))
goto out;
- r = -ENXIO;
- if (!kvm->arch.vpit)
- goto out;
r = kvm_vm_ioctl_reinject(kvm, &control);
break;
}
--
2.34.1