ba49296236
Currently x86 is the only architecture that uses kvm_guest_init(). With PowerPC we're getting a second user, but the signature is different there and we don't need to export it, as it uses the normal kernel init framework. So let's move the x86 specific definition of that function over to the x86 specfic header file. Signed-off-by: Alexander Graf <agraf@suse.de> Signed-off-by: Avi Kivity <avi@redhat.com>
170 lines
4.1 KiB
C
170 lines
4.1 KiB
C
#ifndef _ASM_X86_KVM_PARA_H
|
|
#define _ASM_X86_KVM_PARA_H
|
|
|
|
#include <linux/types.h>
|
|
#include <asm/hyperv.h>
|
|
|
|
/* This CPUID returns the signature 'KVMKVMKVM' in ebx, ecx, and edx. It
|
|
* should be used to determine that a VM is running under KVM.
|
|
*/
|
|
#define KVM_CPUID_SIGNATURE 0x40000000
|
|
|
|
/* This CPUID returns a feature bitmap in eax. Before enabling a particular
|
|
* 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
|
|
/* This indicates that the new set of kvmclock msrs
|
|
* are available. The use of 0x11 and 0x12 is deprecated
|
|
*/
|
|
#define KVM_FEATURE_CLOCKSOURCE2 3
|
|
|
|
/* The last 8 bits are used to indicate how to interpret the flags field
|
|
* in pvclock structure. If no bits are set, all flags are ignored.
|
|
*/
|
|
#define KVM_FEATURE_CLOCKSOURCE_STABLE_BIT 24
|
|
|
|
#define MSR_KVM_WALL_CLOCK 0x11
|
|
#define MSR_KVM_SYSTEM_TIME 0x12
|
|
|
|
/* Custom MSRs falls in the range 0x4b564d00-0x4b564dff */
|
|
#define MSR_KVM_WALL_CLOCK_NEW 0x4b564d00
|
|
#define MSR_KVM_SYSTEM_TIME_NEW 0x4b564d01
|
|
|
|
#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.
|
|
*/
|
|
#define KVM_HYPERCALL ".byte 0x0f,0x01,0xc1"
|
|
|
|
/* For KVM hypercalls, a three-byte sequence of either the vmrun or the vmmrun
|
|
* instruction. The hypervisor may replace it with something else but only the
|
|
* instructions are guaranteed to be supported.
|
|
*
|
|
* Up to four arguments may be passed in rbx, rcx, rdx, and rsi respectively.
|
|
* The hypercall number should be placed in rax and the return value will be
|
|
* placed in rax. No other registers will be clobbered unless explicited
|
|
* noted by the particular hypercall.
|
|
*/
|
|
|
|
static inline long kvm_hypercall0(unsigned int nr)
|
|
{
|
|
long ret;
|
|
asm volatile(KVM_HYPERCALL
|
|
: "=a"(ret)
|
|
: "a"(nr)
|
|
: "memory");
|
|
return ret;
|
|
}
|
|
|
|
static inline long kvm_hypercall1(unsigned int nr, unsigned long p1)
|
|
{
|
|
long ret;
|
|
asm volatile(KVM_HYPERCALL
|
|
: "=a"(ret)
|
|
: "a"(nr), "b"(p1)
|
|
: "memory");
|
|
return ret;
|
|
}
|
|
|
|
static inline long kvm_hypercall2(unsigned int nr, unsigned long p1,
|
|
unsigned long p2)
|
|
{
|
|
long ret;
|
|
asm volatile(KVM_HYPERCALL
|
|
: "=a"(ret)
|
|
: "a"(nr), "b"(p1), "c"(p2)
|
|
: "memory");
|
|
return ret;
|
|
}
|
|
|
|
static inline long kvm_hypercall3(unsigned int nr, unsigned long p1,
|
|
unsigned long p2, unsigned long p3)
|
|
{
|
|
long ret;
|
|
asm volatile(KVM_HYPERCALL
|
|
: "=a"(ret)
|
|
: "a"(nr), "b"(p1), "c"(p2), "d"(p3)
|
|
: "memory");
|
|
return ret;
|
|
}
|
|
|
|
static inline long kvm_hypercall4(unsigned int nr, unsigned long p1,
|
|
unsigned long p2, unsigned long p3,
|
|
unsigned long p4)
|
|
{
|
|
long ret;
|
|
asm volatile(KVM_HYPERCALL
|
|
: "=a"(ret)
|
|
: "a"(nr), "b"(p1), "c"(p2), "d"(p3), "S"(p4)
|
|
: "memory");
|
|
return ret;
|
|
}
|
|
|
|
static inline int kvm_para_available(void)
|
|
{
|
|
unsigned int eax, ebx, ecx, edx;
|
|
char signature[13];
|
|
|
|
cpuid(KVM_CPUID_SIGNATURE, &eax, &ebx, &ecx, &edx);
|
|
memcpy(signature + 0, &ebx, 4);
|
|
memcpy(signature + 4, &ecx, 4);
|
|
memcpy(signature + 8, &edx, 4);
|
|
signature[12] = 0;
|
|
|
|
if (strcmp(signature, "KVMKVMKVM") == 0)
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static inline unsigned int kvm_arch_para_features(void)
|
|
{
|
|
return cpuid_eax(KVM_CPUID_FEATURES);
|
|
}
|
|
|
|
#ifdef CONFIG_KVM_GUEST
|
|
void __init kvm_guest_init(void);
|
|
#else
|
|
#define kvm_guest_init() do { } while (0)
|
|
#endif
|
|
|
|
#endif /* __KERNEL__ */
|
|
|
|
#endif /* _ASM_X86_KVM_PARA_H */
|