From mboxrd@z Thu Jan 1 00:00:00 1970 From: Marcelo Tosatti Subject: [patch 4/4] KVM: allow direct access to PMTimer port Date: Sat, 24 May 2008 20:43:46 -0300 Message-ID: <20080525000036.710955693@localhost.localdomain> References: <20080524234342.983197667@localhost.localdomain> Cc: kvm-devel , Len Brown To: Avi Kivity , Chris Wright Return-path: Received: from mx1.redhat.com ([66.187.233.31]:37686 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752933AbYEYAJS (ORCPT ); Sat, 24 May 2008 20:09:18 -0400 Content-Disposition: inline; filename=kvm-open-pmtmr Sender: kvm-owner@vger.kernel.org List-ID: There's not much point in exiting for pmtimer reads, since it runs at a fixed clock rate and its start value is undefined. The KVM-specific ioctl to read the counter from userspace is not nice though. Ideas? CC: Len Brown diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index baf9607..f7e44d8 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -24,6 +24,7 @@ #include #include #include +#include #include @@ -424,6 +425,10 @@ static __init int svm_hardware_setup(void) iopm_va = page_address(iopm_pages); memset(iopm_va, 0xff, PAGE_SIZE * (1 << IOPM_ALLOC_ORDER)); clear_bit(0x80, iopm_va); /* allow direct access to PC debug port */ + if (pmtmr_ioport) + for (r = 0; r < 4; r++) + clear_bit(pmtmr_ioport+r, iopm_va); + iopm_base = page_to_pfn(iopm_pages) << PAGE_SHIFT; if (boot_cpu_has(X86_FEATURE_NX)) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index aaa99ed..4f77fd7 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -3261,6 +3262,10 @@ static int __init vmx_init(void) va = kmap(vmx_io_bitmap_a); memset(va, 0xff, PAGE_SIZE); clear_bit(0x80, va); + if (pmtmr_ioport) + for (r = 0; r < 4; r++) + clear_bit(pmtmr_ioport+r, va); + kunmap(vmx_io_bitmap_a); va = kmap(vmx_io_bitmap_b); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index e537005..9769f52 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -790,6 +791,7 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_PIT: case KVM_CAP_NOP_IO_DELAY: case KVM_CAP_MP_STATE: + case KVM_CAP_GET_PMTIMER: r = 1; break; case KVM_CAP_VAPIC: @@ -1678,6 +1680,18 @@ long kvm_arch_vm_ioctl(struct file *filp, r = 0; break; } + case KVM_GET_PMTIMER: { + struct kvm_pmtimer pmtmr; + r = -ENODEV; + if (!pmtmr_ioport) + goto out; + pmtmr.val = inl(pmtmr_ioport); + r = -EFAULT; + if (copy_to_user(argp, &pmtmr, sizeof pmtmr)) + goto out; + r = 0; + break; + } default: ; } diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c index 7b46faf..d3d4294 100644 --- a/drivers/clocksource/acpi_pm.c +++ b/drivers/clocksource/acpi_pm.c @@ -29,6 +29,7 @@ * in arch/i386/kernel/acpi/boot.c */ u32 pmtmr_ioport __read_mostly; +EXPORT_SYMBOL(pmtmr_ioport); static inline u32 read_pmtmr(void) { diff --git a/include/linux/kvm.h b/include/linux/kvm.h index a281afe..3672890 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -247,6 +247,10 @@ struct kvm_mp_state { __u32 mp_state; }; +struct kvm_pmtimer { + __u32 val; +}; + struct kvm_s390_psw { __u64 mask; __u64 addr; @@ -346,6 +350,7 @@ struct kvm_trace_rec { #define KVM_CAP_NOP_IO_DELAY 12 #define KVM_CAP_PV_MMU 13 #define KVM_CAP_MP_STATE 14 +#define KVM_CAP_GET_PMTIMER 15 /* * ioctls for VM fds @@ -371,6 +376,7 @@ struct kvm_trace_rec { #define KVM_CREATE_PIT _IO(KVMIO, 0x64) #define KVM_GET_PIT _IOWR(KVMIO, 0x65, struct kvm_pit_state) #define KVM_SET_PIT _IOR(KVMIO, 0x66, struct kvm_pit_state) +#define KVM_GET_PMTIMER _IOR(KVMIO, 0x67, struct kvm_pmtimer) /* * ioctls for vcpu fds --