* paravirtualization, the appropriate feature bit should be checked.
*/
#define KVM_CPUID_FEATURES 0x40000001
+#define KVM_FEATURE_CLOCKSOURCE 0
+#define KVM_FEATURE_NOP_IO_DELAY 1
+#define KVM_FEATURE_MMU_OP 2
+
+#define MSR_KVM_WALL_CLOCK 0x11
+#define MSR_KVM_SYSTEM_TIME 0x12
+
+#define KVM_MAX_MMU_OP_BATCH 32
+
+/* Operations for KVM_HC_MMU_OP */
+#define KVM_MMU_OP_WRITE_PTE 1
+#define KVM_MMU_OP_FLUSH_TLB 2
+#define KVM_MMU_OP_RELEASE_PT 3
+
+/* Payload for KVM_HC_MMU_OP */
+struct kvm_mmu_op_header {
+ __u32 op;
+ __u32 pad;
+};
+
+struct kvm_mmu_op_write_pte {
+ struct kvm_mmu_op_header header;
+ __u64 pte_phys;
+ __u64 pte_val;
+};
+
+struct kvm_mmu_op_flush_tlb {
+ struct kvm_mmu_op_header header;
+};
+
+struct kvm_mmu_op_release_pt {
+ struct kvm_mmu_op_header header;
+ __u64 pt_phys;
+};
#ifdef __KERNEL__
#include <asm/processor.h>
+extern void kvmclock_init(void);
+
+
/* This instruction is vmcall. On non-VT architectures, it will generate a
* trap that we will then rewrite to the appropriate instruction.
*/
long ret;
asm volatile(KVM_HYPERCALL
: "=a"(ret)
- : "a"(nr));
+ : "a"(nr)
+ : "memory");
return ret;
}
long ret;
asm volatile(KVM_HYPERCALL
: "=a"(ret)
- : "a"(nr), "b"(p1));
+ : "a"(nr), "b"(p1)
+ : "memory");
return ret;
}
long ret;
asm volatile(KVM_HYPERCALL
: "=a"(ret)
- : "a"(nr), "b"(p1), "c"(p2));
+ : "a"(nr), "b"(p1), "c"(p2)
+ : "memory");
return ret;
}
long ret;
asm volatile(KVM_HYPERCALL
: "=a"(ret)
- : "a"(nr), "b"(p1), "c"(p2), "d"(p3));
+ : "a"(nr), "b"(p1), "c"(p2), "d"(p3)
+ : "memory");
return ret;
}
long ret;
asm volatile(KVM_HYPERCALL
: "=a"(ret)
- : "a"(nr), "b"(p1), "c"(p2), "d"(p3), "S"(p4));
+ : "a"(nr), "b"(p1), "c"(p2), "d"(p3), "S"(p4)
+ : "memory");
return ret;
}