summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryan Cantrill <bryan@joyent.com>2011-04-09 13:52:14 -0700
committerBryan Cantrill <bryan@joyent.com>2011-04-09 13:52:14 -0700
commit99a4ea32a54269cac99db97e6d2a0c4fdb2288ae (patch)
treef72d90b50d9bb68c720cb1fddddf0859b3b5d13b
parent5a4d889bd6a5847bf7bb070e4691e9b82a15cd75 (diff)
downloadillumos-kvm-99a4ea32a54269cac99db97e6d2a0c4fdb2288ae.tar.gz
HVM-43 add ::kvm_gpa2qva to translate guest physical to QEMU virtual
-rw-r--r--Makefile16
-rw-r--r--kvm.h57
-rw-r--r--kvm_mdb.c242
-rw-r--r--kvm_subr.c167
-rw-r--r--kvm_x86host.h47
-rw-r--r--msr.h238
6 files changed, 450 insertions, 317 deletions
diff --git a/Makefile b/Makefile
index 3cb9980..6001ea7 100644
--- a/Makefile
+++ b/Makefile
@@ -12,16 +12,25 @@ DESTDIR=
CFLAGS += -DCONFIG_HAVE_KVM_IRQCHIP -D__KVM_HAVE_IOAPIC -DCONFIG_X86_64 -D_KERNEL -D_MACHDEP -Dx86 -DDEBUG -c -g -DCONFIG_SOLARIS -DCONFIG_KVM_MMIO -DCONFIG_KVM_APIC_ARCHITECTURE -O2 -fident -finline -fno-inline-functions -fno-builtin -fno-asm -nodefaultlibs -D__sun -O -D_ASM_INLINES -ffreestanding -Wall -Wno-unknown-pragmas -Wno-missing-braces -Wno-sign-compare -Wno-parentheses -Wno-uninitialized -Wno-implicit-function-declaration -Wno-unused -Wno-trigraphs -Wno-char-subscripts -Wno-switch -gdwarf-2 -std=gnu99 -fno-dwarf2-indirect-strings -Werror -DDIS_MEM -D_KERNEL -ffreestanding -D_SYSCALL32 -D_DDI_STRICT -Di86pc -D_MACHDEP -DOPTERON_ERRATUM_88 -DOPTERON_ERRATUM_91 -DOPTERON_ERRATUM_93 -DOPTERON_ERRATUM_95 -DOPTERON_ERRATUM_99 -DOPTERON_ERRATUM_100 -DOPTERON_ERRATUM_101 -DOPTERON_ERRATUM_108 -DOPTERON_ERRATUM_109 -DOPTERON_ERRATUM_121 -DOPTERON_ERRATUM_122 -DOPTERON_ERRATUM_123 -DOPTERON_ERRATUM_131 -DOPTERON_WORKAROUND_6336786 -DOPTERON_WORKAROUND_6323525 -DOPTERON_ERRATUM_172 -DOPTERON_ERRATUM_298 -I$(KERNEL_SOURCE)/usr/src/uts/common -nostdinc -c -DUTS_RELEASE="5.11" -DUTS_VERSION="joyent.147" -DUTS_PLATFORM="i86pc" -mno-red-zone
INCLUDEDIR= -I $(KERNEL_SOURCE)/usr/src/uts/intel -I $(KERNEL_SOURCE)/usr/src/uts/i86pc -I $(KERNEL_SOURCE)/usr/src/uts/common
+CSTYLE=$(KERNEL_SOURCE)/usr/src/tools/scripts/cstyle
-kvm: kvm.c kvm_x86.c emulate.c kvm.h kvm_x86host.h msr.h bitops.h
+all: kvm kvm.so
+
+kvm: kvm.c kvm_x86.c emulate.c kvm.h kvm_x86host.h msr.h bitops.h kvm_subr.c
$(CC) $(CFLAGS) $(INCLUDEDIR) kvm.c
$(CC) $(CFLAGS) $(INCLUDEDIR) kvm_x86.c
$(CC) $(CFLAGS) $(INCLUDEDIR) emulate.c
+ $(CC) $(CFLAGS) $(INCLUDEDIR) kvm_subr.c
$(CTFCONVERT) -i -L VERSION kvm.o
$(CTFCONVERT) -i -L VERSION kvm_x86.o
$(CTFCONVERT) -i -L VERSION emulate.o
- $(LD) -r -o kvm kvm.o kvm_x86.o emulate.o
- $(CTFMERGE) -L VERSION -o kvm kvm.o kvm_x86.o emulate.o
+ $(CTFCONVERT) -i -L VERSION kvm_subr.o
+ $(LD) -r -o kvm kvm.o kvm_x86.o emulate.o kvm_subr.o
+ $(CTFMERGE) -L VERSION -o kvm kvm.o kvm_x86.o emulate.o kvm_subr.o
+
+kvm.so: kvm_mdb.c
+ gcc -m64 -shared \
+ -fPIC $(CFLAGS) $(INCLUDEDIR) -I/usr/include -o $@ kvm_mdb.c
install: kvm
@echo "==> Installing kvm module"
@@ -30,6 +39,7 @@ install: kvm
@pfexec cp kvm.conf /usr/kernel/drv
check:
+ @$(CSTYLE) kvm_mdb.c
@./tools/xxxcheck kvm_x86.c kvm.c
load: install
diff --git a/kvm.h b/kvm.h
index 8eae127..83a6354 100644
--- a/kvm.h
+++ b/kvm.h
@@ -1902,19 +1902,13 @@ struct vcpu_vmx {
char rdtscp_enabled;
};
-static struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i)
-{
-#ifdef XXX
- smp_rmb();
-#endif /*XXX*/
- return kvm->vcpus[i];
-}
-
#define kvm_for_each_vcpu(idx, vcpup, kvm) \
for (idx = 0, vcpup = kvm_get_vcpu(kvm, idx); \
idx < kvm->online_vcpus && vcpup; /* XXX - need protection */ \
vcpup = kvm_get_vcpu(kvm, ++idx))
+extern struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i);
+
#ifdef XXX
struct kvm_irq_mask_notifier {
void (*func)(struct kvm_irq_mask_notifier *kimn, bool masked);
@@ -2060,13 +2054,8 @@ struct preempt_notifier {
void preempt_notifier_register(struct preempt_notifier *notifier);
void preempt_notifier_unregister(struct preempt_notifier *notifier);
-
-static void preempt_notifier_init(struct preempt_notifier *notifier,
- struct preempt_ops *ops)
-{
- INIT_HLIST_NODE(&notifier->link);
- notifier->ops = ops;
-}
+void preempt_notifier_init(struct preempt_notifier *notifier,
+ struct preempt_ops *ops);
#endif /*XXX*/
#endif /*CONFIG_PREEMPT_NOTIFIERS*/
@@ -2096,12 +2085,7 @@ int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx,
int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
struct kvm_io_device *dev);
-static unsigned long kvm_dirty_bitmap_bytes(struct kvm_memory_slot *memslot)
-{
- /* XXX */
- /* return ALIGN(memslot->npages, BITS_PER_LONG) / 8; */
- return ((BT_BITOUL(memslot->npages)) / 8);
-}
+extern unsigned long kvm_dirty_bitmap_bytes(struct kvm_memory_slot *memslot);
int kvm_set_memory_region(struct kvm *kvm,
struct kvm_userspace_memory_region *mem,
@@ -2241,7 +2225,6 @@ void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq,
void kvm_fire_mask_notifiers(struct kvm *kvm, int irq, bool mask);
#endif /*XXX*/
-#ifdef CONFIG_IOMMU_API
int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot);
int kvm_iommu_map_guest(struct kvm *kvm);
int kvm_iommu_unmap_guest(struct kvm *kvm);
@@ -2249,36 +2232,6 @@ int kvm_assign_device(struct kvm *kvm,
struct kvm_assigned_dev_kernel *assigned_dev);
int kvm_deassign_device(struct kvm *kvm,
struct kvm_assigned_dev_kernel *assigned_dev);
-#else /* CONFIG_IOMMU_API */
-static int kvm_iommu_map_pages(struct kvm *kvm,
- gfn_t base_gfn,
- unsigned long npages)
-{
- return 0;
-}
-
-static int kvm_iommu_map_guest(struct kvm *kvm)
-{
- return -ENODEV;
-}
-
-static int kvm_iommu_unmap_guest(struct kvm *kvm)
-{
- return 0;
-}
-
-static int kvm_assign_device(struct kvm *kvm,
- struct kvm_assigned_dev_kernel *assigned_dev)
-{
- return 0;
-}
-
-static int kvm_deassign_device(struct kvm *kvm,
- struct kvm_assigned_dev_kernel *assigned_dev)
-{
- return 0;
-}
-#endif /* CONFIG_IOMMU_API */
#define for_each_unsync_children(bitmap, idx) \
for (idx = bt_getlowbit(bitmap, 0, 512); \
diff --git a/kvm_mdb.c b/kvm_mdb.c
new file mode 100644
index 0000000..015a6b8
--- /dev/null
+++ b/kvm_mdb.c
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/errno.h>
+#include <sys/uio.h>
+#include <sys/buf.h>
+#include <sys/modctl.h>
+#include <sys/open.h>
+#include <sys/kmem.h>
+#include <sys/poll.h>
+#include <sys/conf.h>
+#include <sys/cmn_err.h>
+#include <sys/stat.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+#include <sys/atomic.h>
+#include <sys/spl.h>
+#include <sys/cpuvar.h>
+#include <sys/segments.h>
+#include <sys/mdb_modapi.h>
+
+#include "msr.h"
+#include "vmx.h"
+#include "irqflags.h"
+#include "iodev.h"
+#include "kvm_host.h"
+#include "kvm_x86host.h"
+#include "kvm.h"
+
+int
+kvm_mdb_memory_slot_init(mdb_walk_state_t *wsp)
+{
+ struct kvm_memslots *memslots;
+ struct kvm kvm;
+ uintptr_t addr;
+
+ if (wsp->walk_addr == NULL) {
+ mdb_warn("kvm_memory_slot does not support global walks");
+ return (WALK_ERR);
+ }
+
+ if (mdb_vread(&kvm, sizeof (kvm), wsp->walk_addr) == -1) {
+ mdb_warn("couldn't read kvm at %p", wsp->walk_addr);
+ return (DCMD_ERR);
+ }
+
+ addr = (uintptr_t)kvm.memslots;
+ memslots = mdb_alloc(sizeof (struct kvm_memslots), UM_SLEEP | UM_GC);
+
+ if (mdb_vread(memslots, sizeof (struct kvm_memslots), addr) == -1) {
+ mdb_warn("couldn't read memslots at %p", addr);
+ return (DCMD_ERR);
+ }
+
+ wsp->walk_addr = addr + offsetof(struct kvm_memslots, memslots);
+ wsp->walk_arg = 0;
+ wsp->walk_data = memslots;
+
+ return (WALK_NEXT);
+}
+
+int
+kvm_mdb_memory_slot_step(mdb_walk_state_t *wsp)
+{
+ struct kvm_memslots *memslots = wsp->walk_data;
+ uintptr_t ndx = (uintptr_t)wsp->walk_arg;
+
+ if (ndx >= KVM_MEMORY_SLOTS)
+ return (WALK_DONE);
+
+ wsp->walk_arg = (void *)(ndx + 1);
+
+ return (wsp->walk_callback(wsp->walk_addr +
+ ndx * sizeof (struct kvm_memory_slot), &memslots->memslots[ndx],
+ wsp->walk_cbdata));
+}
+
+int
+kvm_mdb_mem_alias_init(mdb_walk_state_t *wsp)
+{
+ struct kvm_mem_aliases *aliases;
+ struct kvm kvm;
+ uintptr_t addr;
+
+ if (wsp->walk_addr == NULL) {
+ mdb_warn("kvm_mem_alias does not support global walks");
+ return (WALK_ERR);
+ }
+
+ if (mdb_vread(&kvm, sizeof (kvm), wsp->walk_addr) == -1) {
+ mdb_warn("couldn't read kvm at %p", wsp->walk_addr);
+ return (DCMD_ERR);
+ }
+
+ addr = (uintptr_t)kvm.arch.aliases;
+ aliases = mdb_alloc(sizeof (struct kvm_mem_aliases), UM_SLEEP | UM_GC);
+
+ if (mdb_vread(aliases, sizeof (struct kvm_mem_aliases), addr) == -1) {
+ mdb_warn("couldn't read aliases at %p", addr);
+ return (DCMD_ERR);
+ }
+
+ wsp->walk_addr = addr + offsetof(struct kvm_mem_aliases, aliases);
+ wsp->walk_arg = 0;
+ wsp->walk_data = aliases;
+
+ return (WALK_NEXT);
+}
+
+int
+kvm_mdb_mem_alias_step(mdb_walk_state_t *wsp)
+{
+ struct kvm_mem_aliases *aliases = wsp->walk_data;
+ uintptr_t ndx = (uintptr_t)wsp->walk_arg;
+
+ if (ndx >= aliases->naliases)
+ return (WALK_DONE);
+
+ wsp->walk_arg = (void *)(ndx + 1);
+
+ return (wsp->walk_callback(wsp->walk_addr +
+ ndx * sizeof (struct kvm_mem_alias), &aliases->aliases[ndx],
+ wsp->walk_cbdata));
+}
+
+static int
+kvm_mdb_gpa2qva_walk_alias(uintptr_t addr,
+ const struct kvm_mem_alias *alias, uintptr_t *gfn)
+{
+ if (alias->flags & KVM_ALIAS_INVALID)
+ return (WALK_NEXT);
+
+ if (*gfn < alias->base_gfn || *gfn >= alias->base_gfn + alias->npages)
+ return (WALK_NEXT);
+
+ *gfn = alias->target_gfn + *gfn - alias->base_gfn;
+
+ return (WALK_DONE);
+}
+
+static int
+kvm_mdb_gpa2qva_walk_slot(uintptr_t addr,
+ const struct kvm_memory_slot *memslot, uintptr_t *gpa)
+{
+ uintptr_t gfn = *gpa >> PAGESHIFT;
+
+ if (gfn < memslot->base_gfn)
+ return (WALK_NEXT);
+
+ if (gfn >= memslot->base_gfn + memslot->npages)
+ return (WALK_NEXT);
+
+ mdb_printf("%p\n", memslot->userspace_addr +
+ ((gfn - memslot->base_gfn) << PAGESHIFT) + (*gpa & PAGEOFFSET));
+
+ *gpa = -1;
+
+ return (WALK_DONE);
+}
+
+static int
+kvm_mdb_gpa2qva(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+ struct kvm kvm;
+ uintptr_t gpa = addr, gfn, kaddr;
+ int i;
+
+ if (!(flags & DCMD_ADDRSPEC) || argc < 1)
+ return (DCMD_USAGE);
+
+ switch (argv[0].a_type) {
+ case MDB_TYPE_STRING:
+ kaddr = mdb_strtoull(argv[0].a_un.a_str);
+ break;
+
+ case MDB_TYPE_IMMEDIATE:
+ kaddr = argv[0].a_un.a_val;
+ break;
+
+ default:
+ return (DCMD_USAGE);
+ }
+
+ if (mdb_vread(&kvm, sizeof (kvm), kaddr) == -1) {
+ mdb_warn("couldn't read kvm at %p", kaddr);
+ return (DCMD_ERR);
+ }
+
+ gfn = gpa >> PAGESHIFT;
+
+ /*
+ * First unalias our guest PFN...
+ */
+ if (mdb_pwalk("kvm_mem_alias",
+ (mdb_walk_cb_t)kvm_mdb_gpa2qva_walk_alias, &gfn, kaddr) == -1) {
+ mdb_warn("failed to walk 'kvm_memory_slot' for %p", kaddr);
+ return (DCMD_ERR);
+ }
+
+ gpa = (gfn << PAGESHIFT) | (gpa & PAGEOFFSET);
+
+ /*
+ * Now walk memory slots looking for a match.
+ */
+ if (mdb_pwalk("kvm_memory_slot",
+ (mdb_walk_cb_t)kvm_mdb_gpa2qva_walk_slot, &gpa, kaddr) == -1) {
+ mdb_warn("failed to walk 'kvm_memory_slot' for %p", kaddr);
+ return (DCMD_ERR);
+ }
+
+ if (gpa != -1) {
+ mdb_warn("0x%p is unknown for kvm 0x%p", addr, kaddr);
+ return (DCMD_ERR);
+ }
+
+ return (DCMD_OK);
+}
+
+static const mdb_dcmd_t dcmds[] = {
+ { "kvm_gpa2qva", "?[address of kvm]", "translate a guest physical "
+ "to a QEMU virtual address", kvm_mdb_gpa2qva },
+ { NULL }
+};
+
+static const mdb_walker_t walkers[] = {
+ { "kvm_memory_slot", "walk kvm_memory_slot structures for a given kvm",
+ kvm_mdb_memory_slot_init, kvm_mdb_memory_slot_step },
+ { "kvm_mem_alias", "walk kvm_mem_alias structures for a given kvm",
+ kvm_mdb_mem_alias_init, kvm_mdb_mem_alias_step },
+ { NULL }
+};
+
+static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers };
+
+const mdb_modinfo_t *
+_mdb_init(void)
+{
+ return (&modinfo);
+}
diff --git a/kvm_subr.c b/kvm_subr.c
new file mode 100644
index 0000000..c9c646a
--- /dev/null
+++ b/kvm_subr.c
@@ -0,0 +1,167 @@
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/errno.h>
+#include <sys/uio.h>
+#include <sys/buf.h>
+#include <sys/modctl.h>
+#include <sys/open.h>
+#include <sys/kmem.h>
+#include <sys/poll.h>
+#include <sys/conf.h>
+#include <sys/cmn_err.h>
+#include <sys/stat.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+#include <sys/atomic.h>
+#include <sys/spl.h>
+#include <sys/cpuvar.h>
+#include <sys/segments.h>
+
+#include "msr.h"
+#include "vmx.h"
+#include "irqflags.h"
+#include "iodev.h"
+#include "kvm_host.h"
+#include "kvm_x86host.h"
+#include "kvm.h"
+
+unsigned long
+kvm_dirty_bitmap_bytes(struct kvm_memory_slot *memslot)
+{
+ /* XXX */
+ /* return ALIGN(memslot->npages, BITS_PER_LONG) / 8; */
+ return ((BT_BITOUL(memslot->npages)) / 8);
+}
+
+struct kvm_vcpu *
+kvm_get_vcpu(struct kvm *kvm, int i)
+{
+#ifdef XXX
+ smp_rmb();
+#endif /*XXX*/
+ return kvm->vcpus[i];
+}
+
+void
+kvm_fx_save(struct i387_fxsave_struct *image)
+{
+ __asm__("fxsave (%0)":: "r" (image));
+}
+
+void
+kvm_fx_restore(struct i387_fxsave_struct *image)
+{
+ __asm__("fxrstor (%0)":: "r" (image));
+}
+
+void
+kvm_fx_finit(void)
+{
+ __asm__("finit");
+}
+
+uint32_t
+get_rdx_init_val(void)
+{
+ return 0x600; /* P6 family */
+}
+
+void
+kvm_inject_gp(struct kvm_vcpu *vcpu, uint32_t error_code)
+{
+ kvm_queue_exception_e(vcpu, GP_VECTOR, error_code);
+}
+
+unsigned long long
+native_read_tscp(unsigned int *aux)
+{
+ unsigned long low, high;
+ __asm__ volatile(".byte 0x0f,0x01,0xf9"
+ : "=a" (low), "=d" (high), "=c" (*aux));
+ return low | ((uint64_t)high << 32);
+}
+
+unsigned long long
+native_read_msr(unsigned int msr)
+{
+ DECLARE_ARGS(val, low, high);
+
+ __asm__ volatile("rdmsr" : EAX_EDX_RET(val, low, high) : "c" (msr));
+ return EAX_EDX_VAL(val, low, high);
+}
+
+void
+native_write_msr(unsigned int msr, unsigned low, unsigned high)
+{
+ __asm__ volatile("wrmsr" : : "c" (msr),
+ "a"(low), "d" (high) : "memory");
+}
+
+unsigned long long
+__native_read_tsc(void)
+{
+ DECLARE_ARGS(val, low, high);
+
+ __asm__ volatile("rdtsc" : EAX_EDX_RET(val, low, high));
+
+ return EAX_EDX_VAL(val, low, high);
+}
+
+unsigned long long
+native_read_pmc(int counter)
+{
+ DECLARE_ARGS(val, low, high);
+
+ __asm__ volatile("rdpmc" : EAX_EDX_RET(val, low, high) : "c" (counter));
+ return EAX_EDX_VAL(val, low, high);
+}
+
+void wrmsr(unsigned msr, unsigned low, unsigned high)
+{
+ native_write_msr(msr, low, high);
+}
+
+int
+wrmsr_safe(unsigned msr, unsigned low, unsigned high)
+{
+ return (native_write_msr_safe(msr, low, high));
+}
+
+int
+rdmsrl_safe(unsigned msr, unsigned long long *p)
+{
+ int err;
+
+ *p = native_read_msr_safe(msr, &err);
+ return (err);
+}
+
+int
+rdmsr_on_cpu(unsigned int cpu, uint32_t msr_no, uint32_t *l, uint32_t *h)
+{
+ rdmsr(msr_no, *l, *h);
+ return 0;
+}
+
+int
+wrmsr_on_cpu(unsigned int cpu, uint32_t msr_no, uint32_t l, uint32_t h)
+{
+ wrmsr(msr_no, l, h);
+ return 0;
+}
+
+unsigned long read_msr(unsigned long msr)
+{
+ uint64_t value;
+
+ rdmsrl(msr, value);
+ return (value);
+}
+
+unsigned long kvm_read_tr_base(void)
+{
+ unsigned short tr;
+ __asm__("str %0" : "=g"(tr));
+ return segment_base(tr);
+}
+
diff --git a/kvm_x86host.h b/kvm_x86host.h
index dc8e268..4b65f4b 100644
--- a/kvm_x86host.h
+++ b/kvm_x86host.h
@@ -900,48 +900,15 @@ static unsigned long get_desc_base(const struct desc_struct *desc)
}
extern unsigned long segment_base(uint16_t selector);
+extern unsigned long kvm_read_tr_base(void);
-static unsigned long kvm_read_tr_base(void)
-{
- unsigned short tr;
- __asm__("str %0" : "=g"(tr));
- return segment_base(tr);
-}
-
-#ifdef CONFIG_X86_64
-static unsigned long read_msr(unsigned long msr)
-{
- uint64_t value;
-
- rdmsrl(msr, value);
- return value;
-}
-#endif
-
-static void kvm_fx_save(struct i387_fxsave_struct *image)
-{
- __asm__("fxsave (%0)":: "r" (image));
-}
+extern unsigned long read_msr(unsigned long msr);
-static void kvm_fx_restore(struct i387_fxsave_struct *image)
-{
- __asm__("fxrstor (%0)":: "r" (image));
-}
-
-static void kvm_fx_finit(void)
-{
- __asm__("finit");
-}
-
-static uint32_t get_rdx_init_val(void)
-{
- return 0x600; /* P6 family */
-}
-
-static void kvm_inject_gp(struct kvm_vcpu *vcpu, uint32_t error_code)
-{
- kvm_queue_exception_e(vcpu, GP_VECTOR, error_code);
-}
+extern void kvm_fx_save(struct i387_fxsave_struct *image);
+extern void kvm_fx_restore(struct i387_fxsave_struct *image);
+extern void kvm_fx_finit(void);
+extern uint32_t get_rdx_init_val(void);
+extern void kvm_inject_gp(struct kvm_vcpu *vcpu, uint32_t error_code);
#define TSS_IOPB_BASE_OFFSET 0x66
#define TSS_BASE_SIZE 0x68
diff --git a/msr.h b/msr.h
index 07f98df..96b4e34 100644
--- a/msr.h
+++ b/msr.h
@@ -41,13 +41,7 @@ struct msr_regs_info {
int err;
};
-static unsigned long long native_read_tscp(unsigned int *aux)
-{
- unsigned long low, high;
- __asm__ volatile(".byte 0x0f,0x01,0xf9"
- : "=a" (low), "=d" (high), "=c" (*aux));
- return low | ((uint64_t)high << 32);
-}
+extern unsigned long long native_read_tscp(unsigned int *aux);
/*
* both i386 and x86_64 returns 64-bit value in edx:eax, but gcc's "A"
@@ -67,38 +61,13 @@ static unsigned long long native_read_tscp(unsigned int *aux)
#define EAX_EDX_RET(val, low, high) "=A" (val)
#endif
-#ifndef XXX
-/* change to function, i.e., not inline. want to dtrace this */
-/* doing this for most read/write msr inlines */
-static unsigned long long native_read_msr(unsigned int msr)
-#else
-static unsigned long long native_read_msr(unsigned int msr)
-#endif /*XXX*/
-{
- DECLARE_ARGS(val, low, high);
-
- __asm__ volatile("rdmsr" : EAX_EDX_RET(val, low, high) : "c" (msr));
- return EAX_EDX_VAL(val, low, high);
-}
-
-
-extern uint64_t native_read_msr_safe(unsigned int msr,
- int *err);
+extern unsigned long long native_read_msr(unsigned int msr);
+extern uint64_t native_read_msr_safe(unsigned int msr, int *err);
extern int native_write_msr_safe(unsigned int msr,
unsigned low, unsigned high);
-
-#ifndef XXX
-static void native_write_msr(unsigned int msr,
- unsigned low, unsigned high)
-#else
-static void native_write_msr(unsigned int msr,
- unsigned low, unsigned high)
-#endif /*XXX*/
-{
- __asm__ volatile("wrmsr" : : "c" (msr), "a"(low), "d" (high) : "memory");
-}
-
+extern void native_write_msr(unsigned int msr,
+ unsigned low, unsigned high);
extern unsigned long long native_read_tsc(void);
@@ -107,22 +76,8 @@ extern int native_rdmsr_safe_regs(uint32_t regs[8]);
extern int native_wrmsr_safe_regs(uint32_t regs[8]);
#endif /*NOTNOW*/
-static unsigned long long __native_read_tsc(void)
-{
- DECLARE_ARGS(val, low, high);
-
- __asm__ volatile("rdtsc" : EAX_EDX_RET(val, low, high));
-
- return EAX_EDX_VAL(val, low, high);
-}
-
-static unsigned long long native_read_pmc(int counter)
-{
- DECLARE_ARGS(val, low, high);
-
- __asm__ volatile("rdpmc" : EAX_EDX_RET(val, low, high) : "c" (counter));
- return EAX_EDX_VAL(val, low, high);
-}
+extern unsigned long long __native_read_tsc(void);
+extern unsigned long long native_read_pmc(int counter);
#ifdef CONFIG_PARAVIRT
#include <asm/paravirt.h>
@@ -144,14 +99,7 @@ do { \
(val2) = (uint32_t)(__val >> 32); \
} while (0)
-#ifndef XXX
-static void wrmsr(unsigned msr, unsigned low, unsigned high)
-#else
-static void wrmsr(unsigned msr, unsigned low, unsigned high)
-#endif /*XXX*/
-{
- native_write_msr(msr, low, high);
-}
+extern void wrmsr(unsigned msr, unsigned low, unsigned high);
#define rdmsrl(msr, val) \
((val) = native_read_msr((msr)))
@@ -159,16 +107,9 @@ static void wrmsr(unsigned msr, unsigned low, unsigned high)
#define wrmsrl(msr, val) \
native_write_msr((msr), (uint32_t)((uint64_t)(val)), (uint32_t)((uint64_t)(val) >> 32))
-#ifndef XXX
/* see comment above for wrmsr() */
/* wrmsr with exception handling */
-static int wrmsr_safe(unsigned msr, unsigned low, unsigned high)
-#else
-static int wrmsr_safe(unsigned msr, unsigned low, unsigned high)
-#endif /*XXX*/
-{
- return native_write_msr_safe(msr, low, high);
-}
+extern int wrmsr_safe(unsigned msr, unsigned low, unsigned high);
/* rdmsr with exception handling */
#define rdmsr_safe(msr, p1, p2) \
@@ -180,75 +121,10 @@ static int wrmsr_safe(unsigned msr, unsigned low, unsigned high)
__err; \
})
-#ifndef XXX
-static int rdmsrl_safe(unsigned msr, unsigned long long *p)
-#else
-static int rdmsrl_safe(unsigned msr, unsigned long long *p)
-#endif /*XXX*/
-{
- int err;
-
- *p = native_read_msr_safe(msr, &err);
- return err;
-}
-
-#ifdef NOTNOW
-#ifndef XXX
-static int rdmsrl_amd_safe(unsigned msr, unsigned long long *p)
-#else
-static int rdmsrl_amd_safe(unsigned msr, unsigned long long *p)
-#endif /*XXX*/
-{
- uint32_t gprs[8] = { 0 };
- int err;
-
- gprs[1] = msr;
- gprs[7] = 0x9c5a203a;
-
- err = native_rdmsr_safe_regs(gprs);
-
- *p = gprs[0] | ((uint64_t)gprs[2] << 32);
-
- return err;
-}
-
-#ifndef XXX
-static int wrmsrl_amd_safe(unsigned msr, unsigned long long val)
-#else
-static int wrmsrl_amd_safe(unsigned msr, unsigned long long val)
-#endif /*XXX*/
-{
- uint32_t gprs[8] = { 0 };
-
- gprs[0] = (uint32_t)val;
- gprs[1] = msr;
- gprs[2] = val >> 32;
- gprs[7] = 0x9c5a203a;
-
- return native_wrmsr_safe_regs(gprs);
-}
-#endif /*NOTNOW*/
+extern int rdmsrl_safe(unsigned msr, unsigned long long *p);
-#ifdef NOTNOW
-#ifndef XXX
-/* wtf are native_rdmsr_safe_regs/native_wrmsr_safe_regs??? */
-/* possibly built from paravirt.c..., but we don't use them */
-static int rdmsr_safe_regs(uint32_t regs[8])
-#else
-static int rdmsr_safe_regs(uint32_t regs[8])
-#endif /*XXX*/
-{
- return native_rdmsr_safe_regs(regs);
-}
-#ifndef XXX
-static int wrmsr_safe_regs(uint32_t regs[8])
-#else
-static int wrmsr_safe_regs(uint32_t regs[8])
-#endif /*XXX*/
-{
- return native_wrmsr_safe_regs(regs);
-}
-#endif /*NOTNOW*/
+extern int rdmsrl_amd_safe(unsigned msr, unsigned long long *p);
+extern int wrmsrl_amd_safe(unsigned msr, unsigned long long val);
#define rdtscl(low) \
((low) = (uint32_t)__native_read_tsc())
@@ -285,93 +161,11 @@ do { \
struct msr *msrs_alloc(void);
void msrs_free(struct msr *msrs);
-#ifdef CONFIG_SMP
-int rdmsr_on_cpu(unsigned int cpu, uint32_t msr_no, uint32_t *l, uint32_t *h);
-int wrmsr_on_cpu(unsigned int cpu, uint32_t msr_no, uint32_t l, uint32_t h);
-#ifdef XXX
-void rdmsr_on_cpus(const struct cpumask *mask, uint32_t msr_no, struct msr *msrs);
-void wrmsr_on_cpus(const struct cpumask *mask, uint32_t msr_no, struct msr *msrs);
-#endif /*XXX*/
-int rdmsr_safe_on_cpu(unsigned int cpu, uint32_t msr_no, uint32_t *l, uint32_t *h);
-int wrmsr_safe_on_cpu(unsigned int cpu, uint32_t msr_no, uint32_t l, uint32_t h);
-#ifdef XXX
-int rdmsr_safe_regs_on_cpu(unsigned int cpu, uint32_t regs[8]);
-int wrmsr_safe_regs_on_cpu(unsigned int cpu, uint32_t regs[8]);
-#endif /*XXX*/
-#else /* CONFIG_SMP */
-#ifndef XXX
-static int rdmsr_on_cpu(unsigned int cpu, uint32_t msr_no, uint32_t *l, uint32_t *h)
-#else
-static int rdmsr_on_cpu(unsigned int cpu, uint32_t msr_no, uint32_t *l, uint32_t *h)
-#endif /*XXX*/
-{
- rdmsr(msr_no, *l, *h);
- return 0;
-}
+extern int rdmsr_on_cpu(unsigned int cpu,
+ uint32_t msr_no, uint32_t *l, uint32_t *h);
+extern int wrmsr_on_cpu(unsigned int cpu,
+ uint32_t msr_no, uint32_t l, uint32_t h);
-#ifndef XXX
-static int wrmsr_on_cpu(unsigned int cpu, uint32_t msr_no, uint32_t l, uint32_t h)
-#else
-static int wrmsr_on_cpu(unsigned int cpu, uint32_t msr_no, uint32_t l, uint32_t h)
-#endif /*XXX*/
-{
- wrmsr(msr_no, l, h);
- return 0;
-}
-#ifdef XXX
-static void rdmsr_on_cpus(const struct cpumask *m, uint32_t msr_no,
- struct msr *msrs)
-{
- rdmsr_on_cpu(0, msr_no, &(msrs[0].l), &(msrs[0].h));
-}
-
-static void wrmsr_on_cpus(const struct cpumask *m, uint32_t msr_no,
- struct msr *msrs)
-{
- wrmsr_on_cpu(0, msr_no, msrs[0].l, msrs[0].h);
-}
-#endif /*XXX*/
-
-#ifndef XXX
-static int rdmsr_safe_on_cpu(unsigned int cpu, uint32_t msr_no,
- uint32_t *l, uint32_t *h)
-#else
-static int rdmsr_safe_on_cpu(unsigned int cpu, uint32_t msr_no,
- uint32_t *l, uint32_t *h)
-#endif /*XXX*/
-{
- return rdmsr_safe(msr_no, l, h);
-}
-
-#ifndef XXX
-static int wrmsr_safe_on_cpu(unsigned int cpu, uint32_t msr_no, uint32_t l, uint32_t h)
-#else
-static int wrmsr_safe_on_cpu(unsigned int cpu, uint32_t msr_no, uint32_t l, uint32_t h)
-#endif /*XXX*/
-{
- return wrmsr_safe(msr_no, l, h);
-}
-
-#ifdef NOTNOW
-#ifndef XXX
-static int rdmsr_safe_regs_on_cpu(unsigned int cpu, uint32_t regs[8])
-#else
-static int rdmsr_safe_regs_on_cpu(unsigned int cpu, uint32_t regs[8])
-#endif /*XXX*/
-{
- return rdmsr_safe_regs(regs);
-}
-
-#ifndef XXX
-static int wrmsr_safe_regs_on_cpu(unsigned int cpu, uint32_t regs[8])
-#else
-static int wrmsr_safe_regs_on_cpu(unsigned int cpu, uint32_t regs[8])
-#endif /*XXX*/
-{
- return wrmsr_safe_regs(regs);
-}
-#endif /*NOTNOW*/
-#endif /* CONFIG_SMP */
#endif /* _KERNEL */
#endif /* __ASSEMBLY__ */
#endif /* _ASM_X86_MSR_H */