aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kvm/i8254.c7
-rw-r--r--arch/x86/kvm/i8254.h1
-rw-r--r--arch/x86/kvm/x86.c48
3 files changed, 56 insertions, 0 deletions
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
index c7435093bbee..8642f9d1206a 100644
--- a/arch/x86/kvm/i8254.c
+++ b/arch/x86/kvm/i8254.c
@@ -288,6 +288,13 @@ static void pit_load_count(struct kvm *kvm, int channel, u32 val)
288 } 288 }
289} 289}
290 290
291void kvm_pit_load_count(struct kvm *kvm, int channel, u32 val)
292{
293 mutex_lock(&kvm->arch.vpit->pit_state.lock);
294 pit_load_count(kvm, channel, val);
295 mutex_unlock(&kvm->arch.vpit->pit_state.lock);
296}
297
291static void pit_ioport_write(struct kvm_io_device *this, 298static void pit_ioport_write(struct kvm_io_device *this,
292 gpa_t addr, int len, const void *data) 299 gpa_t addr, int len, const void *data)
293{ 300{
diff --git a/arch/x86/kvm/i8254.h b/arch/x86/kvm/i8254.h
index d77d6b795a1f..fe09eced7783 100644
--- a/arch/x86/kvm/i8254.h
+++ b/arch/x86/kvm/i8254.h
@@ -55,6 +55,7 @@ struct kvm_pit {
55 55
56void kvm_inject_pit_timer_irqs(struct kvm_vcpu *vcpu); 56void kvm_inject_pit_timer_irqs(struct kvm_vcpu *vcpu);
57void kvm_pit_timer_intr_post(struct kvm_vcpu *vcpu, int vec); 57void kvm_pit_timer_intr_post(struct kvm_vcpu *vcpu, int vec);
58void kvm_pit_load_count(struct kvm *kvm, int channel, u32 val);
58struct kvm_pit *kvm_create_pit(struct kvm *kvm); 59struct kvm_pit *kvm_create_pit(struct kvm *kvm);
59void kvm_free_pit(struct kvm *kvm); 60void kvm_free_pit(struct kvm *kvm);
60 61
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index c33a4578132c..621a8e362fe7 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1504,6 +1504,23 @@ static int kvm_vm_ioctl_set_irqchip(struct kvm *kvm, struct kvm_irqchip *chip)
1504 return r; 1504 return r;
1505} 1505}
1506 1506
1507static int kvm_vm_ioctl_get_pit(struct kvm *kvm, struct kvm_pit_state *ps)
1508{
1509 int r = 0;
1510
1511 memcpy(ps, &kvm->arch.vpit->pit_state, sizeof(struct kvm_pit_state));
1512 return r;
1513}
1514
1515static int kvm_vm_ioctl_set_pit(struct kvm *kvm, struct kvm_pit_state *ps)
1516{
1517 int r = 0;
1518
1519 memcpy(&kvm->arch.vpit->pit_state, ps, sizeof(struct kvm_pit_state));
1520 kvm_pit_load_count(kvm, 0, ps->channels[0].count);
1521 return r;
1522}
1523
1507/* 1524/*
1508 * Get (and clear) the dirty memory log for a memory slot. 1525 * Get (and clear) the dirty memory log for a memory slot.
1509 */ 1526 */
@@ -1657,6 +1674,37 @@ long kvm_arch_vm_ioctl(struct file *filp,
1657 r = 0; 1674 r = 0;
1658 break; 1675 break;
1659 } 1676 }
1677 case KVM_GET_PIT: {
1678 struct kvm_pit_state ps;
1679 r = -EFAULT;
1680 if (copy_from_user(&ps, argp, sizeof ps))
1681 goto out;
1682 r = -ENXIO;
1683 if (!kvm->arch.vpit)
1684 goto out;
1685 r = kvm_vm_ioctl_get_pit(kvm, &ps);
1686 if (r)
1687 goto out;
1688 r = -EFAULT;
1689 if (copy_to_user(argp, &ps, sizeof ps))
1690 goto out;
1691 r = 0;
1692 break;
1693 }
1694 case KVM_SET_PIT: {
1695 struct kvm_pit_state ps;
1696 r = -EFAULT;
1697 if (copy_from_user(&ps, argp, sizeof ps))
1698 goto out;
1699 r = -ENXIO;
1700 if (!kvm->arch.vpit)
1701 goto out;
1702 r = kvm_vm_ioctl_set_pit(kvm, &ps);
1703 if (r)
1704 goto out;
1705 r = 0;
1706 break;
1707 }
1660 default: 1708 default:
1661 ; 1709 ;
1662 } 1710 }