Skip to content

Commit 00b5ebf

Browse files
committed
KVM: x86: Move PIT ioctl helpers to i8254.c
Move the PIT ioctl helpers to i8254.c, i.e. to the file that implements PIT emulation. Eliminating PIT code in x86.c will allow adding a Kconfig to control support for in-kernel I/O APIC, PIC, and PIT emulation with minimal #ifdefs. Opportunistically make kvm_pit_set_reinject() and kvm_pit_load_count() local to i8254.c as they were only publicly visible to make them available to the ioctl helpers. No functional change intended. Acked-by: Kai Huang <kai.huang@intel.com> Link: https://lore.kernel.org/r/20250611213557.294358-6-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent 20218e6 commit 00b5ebf

File tree

3 files changed

+84
-81
lines changed

3 files changed

+84
-81
lines changed

arch/x86/kvm/i8254.c

Lines changed: 76 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ static inline void kvm_pit_reset_reinject(struct kvm_pit *pit)
288288
atomic_set(&pit->pit_state.irq_ack, 1);
289289
}
290290

291-
void kvm_pit_set_reinject(struct kvm_pit *pit, bool reinject)
291+
static void kvm_pit_set_reinject(struct kvm_pit *pit, bool reinject)
292292
{
293293
struct kvm_kpit_state *ps = &pit->pit_state;
294294
struct kvm *kvm = pit->kvm;
@@ -400,8 +400,8 @@ static void pit_load_count(struct kvm_pit *pit, int channel, u32 val)
400400
}
401401
}
402402

403-
void kvm_pit_load_count(struct kvm_pit *pit, int channel, u32 val,
404-
int hpet_legacy_start)
403+
static void kvm_pit_load_count(struct kvm_pit *pit, int channel, u32 val,
404+
int hpet_legacy_start)
405405
{
406406
u8 saved_mode;
407407

@@ -649,6 +649,79 @@ static void pit_mask_notifer(struct kvm_irq_mask_notifier *kimn, bool mask)
649649
kvm_pit_reset_reinject(pit);
650650
}
651651

652+
int kvm_vm_ioctl_get_pit(struct kvm *kvm, struct kvm_pit_state *ps)
653+
{
654+
struct kvm_kpit_state *kps = &kvm->arch.vpit->pit_state;
655+
656+
BUILD_BUG_ON(sizeof(*ps) != sizeof(kps->channels));
657+
658+
mutex_lock(&kps->lock);
659+
memcpy(ps, &kps->channels, sizeof(*ps));
660+
mutex_unlock(&kps->lock);
661+
return 0;
662+
}
663+
664+
int kvm_vm_ioctl_set_pit(struct kvm *kvm, struct kvm_pit_state *ps)
665+
{
666+
int i;
667+
struct kvm_pit *pit = kvm->arch.vpit;
668+
669+
mutex_lock(&pit->pit_state.lock);
670+
memcpy(&pit->pit_state.channels, ps, sizeof(*ps));
671+
for (i = 0; i < 3; i++)
672+
kvm_pit_load_count(pit, i, ps->channels[i].count, 0);
673+
mutex_unlock(&pit->pit_state.lock);
674+
return 0;
675+
}
676+
677+
int kvm_vm_ioctl_get_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps)
678+
{
679+
mutex_lock(&kvm->arch.vpit->pit_state.lock);
680+
memcpy(ps->channels, &kvm->arch.vpit->pit_state.channels,
681+
sizeof(ps->channels));
682+
ps->flags = kvm->arch.vpit->pit_state.flags;
683+
mutex_unlock(&kvm->arch.vpit->pit_state.lock);
684+
memset(&ps->reserved, 0, sizeof(ps->reserved));
685+
return 0;
686+
}
687+
688+
int kvm_vm_ioctl_set_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps)
689+
{
690+
int start = 0;
691+
int i;
692+
u32 prev_legacy, cur_legacy;
693+
struct kvm_pit *pit = kvm->arch.vpit;
694+
695+
mutex_lock(&pit->pit_state.lock);
696+
prev_legacy = pit->pit_state.flags & KVM_PIT_FLAGS_HPET_LEGACY;
697+
cur_legacy = ps->flags & KVM_PIT_FLAGS_HPET_LEGACY;
698+
if (!prev_legacy && cur_legacy)
699+
start = 1;
700+
memcpy(&pit->pit_state.channels, &ps->channels,
701+
sizeof(pit->pit_state.channels));
702+
pit->pit_state.flags = ps->flags;
703+
for (i = 0; i < 3; i++)
704+
kvm_pit_load_count(pit, i, pit->pit_state.channels[i].count,
705+
start && i == 0);
706+
mutex_unlock(&pit->pit_state.lock);
707+
return 0;
708+
}
709+
710+
int kvm_vm_ioctl_reinject(struct kvm *kvm, struct kvm_reinject_control *control)
711+
{
712+
struct kvm_pit *pit = kvm->arch.vpit;
713+
714+
/* pit->pit_state.lock was overloaded to prevent userspace from getting
715+
* an inconsistent state after running multiple KVM_REINJECT_CONTROL
716+
* ioctls in parallel. Use a separate lock if that ioctl isn't rare.
717+
*/
718+
mutex_lock(&pit->pit_state.lock);
719+
kvm_pit_set_reinject(pit, control->pit_reinject);
720+
mutex_unlock(&pit->pit_state.lock);
721+
722+
return 0;
723+
}
724+
652725
static const struct kvm_io_device_ops pit_dev_ops = {
653726
.read = pit_ioport_read,
654727
.write = pit_ioport_write,

arch/x86/kvm/i8254.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
#include <kvm/iodev.h>
88

9+
#include <uapi/asm/kvm.h>
10+
911
struct kvm_kpit_channel_state {
1012
u32 count; /* can be 65536 */
1113
u16 latched_count;
@@ -55,11 +57,13 @@ struct kvm_pit {
5557
#define KVM_MAX_PIT_INTR_INTERVAL HZ / 100
5658
#define KVM_PIT_CHANNEL_MASK 0x3
5759

60+
int kvm_vm_ioctl_get_pit(struct kvm *kvm, struct kvm_pit_state *ps);
61+
int kvm_vm_ioctl_set_pit(struct kvm *kvm, struct kvm_pit_state *ps);
62+
int kvm_vm_ioctl_get_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps);
63+
int kvm_vm_ioctl_set_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps);
64+
int kvm_vm_ioctl_reinject(struct kvm *kvm, struct kvm_reinject_control *control);
65+
5866
struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags);
5967
void kvm_free_pit(struct kvm *kvm);
6068

61-
void kvm_pit_load_count(struct kvm_pit *pit, int channel, u32 val,
62-
int hpet_legacy_start);
63-
void kvm_pit_set_reinject(struct kvm_pit *pit, bool reinject);
64-
6569
#endif

arch/x86/kvm/x86.c

Lines changed: 0 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -6450,80 +6450,6 @@ static int kvm_vm_ioctl_set_irqchip(struct kvm *kvm, struct kvm_irqchip *chip)
64506450
return r;
64516451
}
64526452

6453-
static int kvm_vm_ioctl_get_pit(struct kvm *kvm, struct kvm_pit_state *ps)
6454-
{
6455-
struct kvm_kpit_state *kps = &kvm->arch.vpit->pit_state;
6456-
6457-
BUILD_BUG_ON(sizeof(*ps) != sizeof(kps->channels));
6458-
6459-
mutex_lock(&kps->lock);
6460-
memcpy(ps, &kps->channels, sizeof(*ps));
6461-
mutex_unlock(&kps->lock);
6462-
return 0;
6463-
}
6464-
6465-
static int kvm_vm_ioctl_set_pit(struct kvm *kvm, struct kvm_pit_state *ps)
6466-
{
6467-
int i;
6468-
struct kvm_pit *pit = kvm->arch.vpit;
6469-
6470-
mutex_lock(&pit->pit_state.lock);
6471-
memcpy(&pit->pit_state.channels, ps, sizeof(*ps));
6472-
for (i = 0; i < 3; i++)
6473-
kvm_pit_load_count(pit, i, ps->channels[i].count, 0);
6474-
mutex_unlock(&pit->pit_state.lock);
6475-
return 0;
6476-
}
6477-
6478-
static int kvm_vm_ioctl_get_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps)
6479-
{
6480-
mutex_lock(&kvm->arch.vpit->pit_state.lock);
6481-
memcpy(ps->channels, &kvm->arch.vpit->pit_state.channels,
6482-
sizeof(ps->channels));
6483-
ps->flags = kvm->arch.vpit->pit_state.flags;
6484-
mutex_unlock(&kvm->arch.vpit->pit_state.lock);
6485-
memset(&ps->reserved, 0, sizeof(ps->reserved));
6486-
return 0;
6487-
}
6488-
6489-
static int kvm_vm_ioctl_set_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps)
6490-
{
6491-
int start = 0;
6492-
int i;
6493-
u32 prev_legacy, cur_legacy;
6494-
struct kvm_pit *pit = kvm->arch.vpit;
6495-
6496-
mutex_lock(&pit->pit_state.lock);
6497-
prev_legacy = pit->pit_state.flags & KVM_PIT_FLAGS_HPET_LEGACY;
6498-
cur_legacy = ps->flags & KVM_PIT_FLAGS_HPET_LEGACY;
6499-
if (!prev_legacy && cur_legacy)
6500-
start = 1;
6501-
memcpy(&pit->pit_state.channels, &ps->channels,
6502-
sizeof(pit->pit_state.channels));
6503-
pit->pit_state.flags = ps->flags;
6504-
for (i = 0; i < 3; i++)
6505-
kvm_pit_load_count(pit, i, pit->pit_state.channels[i].count,
6506-
start && i == 0);
6507-
mutex_unlock(&pit->pit_state.lock);
6508-
return 0;
6509-
}
6510-
6511-
static int kvm_vm_ioctl_reinject(struct kvm *kvm,
6512-
struct kvm_reinject_control *control)
6513-
{
6514-
struct kvm_pit *pit = kvm->arch.vpit;
6515-
6516-
/* pit->pit_state.lock was overloaded to prevent userspace from getting
6517-
* an inconsistent state after running multiple KVM_REINJECT_CONTROL
6518-
* ioctls in parallel. Use a separate lock if that ioctl isn't rare.
6519-
*/
6520-
mutex_lock(&pit->pit_state.lock);
6521-
kvm_pit_set_reinject(pit, control->pit_reinject);
6522-
mutex_unlock(&pit->pit_state.lock);
6523-
6524-
return 0;
6525-
}
6526-
65276453
void kvm_arch_sync_dirty_log(struct kvm *kvm, struct kvm_memory_slot *memslot)
65286454
{
65296455

0 commit comments

Comments
 (0)