2007-10-10 17:16:19 +02:00
/*
* Kernel - based Virtual Machine driver for Linux
*
* derived from drivers / kvm / kvm_main . c
*
* Copyright ( C ) 2006 Qumranet , Inc .
*
* Authors :
* Avi Kivity < avi @ qumranet . com >
* Yaniv Kamay < yaniv @ qumranet . com >
*
* This work is licensed under the terms of the GNU GPL , version 2. See
* the COPYING file in the top - level directory .
*
*/
KVM: Portability: split kvm_vcpu_ioctl
This patch splits kvm_vcpu_ioctl into archtecture independent parts, and
x86 specific parts which go to kvm_arch_vcpu_ioctl in x86.c.
Common ioctls for all architectures are:
KVM_RUN, KVM_GET/SET_(S-)REGS, KVM_TRANSLATE, KVM_INTERRUPT,
KVM_DEBUG_GUEST, KVM_SET_SIGNAL_MASK, KVM_GET/SET_FPU
Note that some PPC chips don't have an FPU, so we might need an #ifdef
around KVM_GET/SET_FPU one day.
x86 specific ioctls are:
KVM_GET/SET_LAPIC, KVM_SET_CPUID, KVM_GET/SET_MSRS
An interresting aspect is vcpu_load/vcpu_put. We now have a common
vcpu_load/put which does the preemption stuff, and an architecture
specific kvm_arch_vcpu_load/put. In the x86 case, this one calls the
vmx/svm function defined in kvm_x86_ops.
Signed-off-by: Carsten Otte <cotte@de.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
2007-10-11 19:16:52 +02:00
# include "kvm.h"
2007-10-10 17:16:19 +02:00
# include "x86.h"
KVM: Portability: split kvm_vcpu_ioctl
This patch splits kvm_vcpu_ioctl into archtecture independent parts, and
x86 specific parts which go to kvm_arch_vcpu_ioctl in x86.c.
Common ioctls for all architectures are:
KVM_RUN, KVM_GET/SET_(S-)REGS, KVM_TRANSLATE, KVM_INTERRUPT,
KVM_DEBUG_GUEST, KVM_SET_SIGNAL_MASK, KVM_GET/SET_FPU
Note that some PPC chips don't have an FPU, so we might need an #ifdef
around KVM_GET/SET_FPU one day.
x86 specific ioctls are:
KVM_GET/SET_LAPIC, KVM_SET_CPUID, KVM_GET/SET_MSRS
An interresting aspect is vcpu_load/vcpu_put. We now have a common
vcpu_load/put which does the preemption stuff, and an architecture
specific kvm_arch_vcpu_load/put. In the x86 case, this one calls the
vmx/svm function defined in kvm_x86_ops.
Signed-off-by: Carsten Otte <cotte@de.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
2007-10-11 19:16:52 +02:00
# include "irq.h"
# include <linux/kvm.h>
# include <linux/fs.h>
# include <linux/vmalloc.h>
2007-10-10 17:16:19 +02:00
# include <asm/uaccess.h>
KVM: Portability: split kvm_vcpu_ioctl
This patch splits kvm_vcpu_ioctl into archtecture independent parts, and
x86 specific parts which go to kvm_arch_vcpu_ioctl in x86.c.
Common ioctls for all architectures are:
KVM_RUN, KVM_GET/SET_(S-)REGS, KVM_TRANSLATE, KVM_INTERRUPT,
KVM_DEBUG_GUEST, KVM_SET_SIGNAL_MASK, KVM_GET/SET_FPU
Note that some PPC chips don't have an FPU, so we might need an #ifdef
around KVM_GET/SET_FPU one day.
x86 specific ioctls are:
KVM_GET/SET_LAPIC, KVM_SET_CPUID, KVM_GET/SET_MSRS
An interresting aspect is vcpu_load/vcpu_put. We now have a common
vcpu_load/put which does the preemption stuff, and an architecture
specific kvm_arch_vcpu_load/put. In the x86 case, this one calls the
vmx/svm function defined in kvm_x86_ops.
Signed-off-by: Carsten Otte <cotte@de.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
2007-10-11 19:16:52 +02:00
# define MAX_IO_MSRS 256
2007-10-10 17:16:19 +02:00
/*
* List of msr numbers which we expose to userspace through KVM_GET_MSRS
* and KVM_SET_MSRS , and KVM_GET_MSR_INDEX_LIST .
*
* This list is modified at module load time to reflect the
* capabilities of the host cpu .
*/
static u32 msrs_to_save [ ] = {
MSR_IA32_SYSENTER_CS , MSR_IA32_SYSENTER_ESP , MSR_IA32_SYSENTER_EIP ,
MSR_K6_STAR ,
# ifdef CONFIG_X86_64
MSR_CSTAR , MSR_KERNEL_GS_BASE , MSR_SYSCALL_MASK , MSR_LSTAR ,
# endif
MSR_IA32_TIME_STAMP_COUNTER ,
} ;
static unsigned num_msrs_to_save ;
static u32 emulated_msrs [ ] = {
MSR_IA32_MISC_ENABLE ,
} ;
KVM: Portability: split kvm_vcpu_ioctl
This patch splits kvm_vcpu_ioctl into archtecture independent parts, and
x86 specific parts which go to kvm_arch_vcpu_ioctl in x86.c.
Common ioctls for all architectures are:
KVM_RUN, KVM_GET/SET_(S-)REGS, KVM_TRANSLATE, KVM_INTERRUPT,
KVM_DEBUG_GUEST, KVM_SET_SIGNAL_MASK, KVM_GET/SET_FPU
Note that some PPC chips don't have an FPU, so we might need an #ifdef
around KVM_GET/SET_FPU one day.
x86 specific ioctls are:
KVM_GET/SET_LAPIC, KVM_SET_CPUID, KVM_GET/SET_MSRS
An interresting aspect is vcpu_load/vcpu_put. We now have a common
vcpu_load/put which does the preemption stuff, and an architecture
specific kvm_arch_vcpu_load/put. In the x86 case, this one calls the
vmx/svm function defined in kvm_x86_ops.
Signed-off-by: Carsten Otte <cotte@de.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
2007-10-11 19:16:52 +02:00
/*
* Adapt set_msr ( ) to msr_io ( ) ' s calling convention
*/
static int do_set_msr ( struct kvm_vcpu * vcpu , unsigned index , u64 * data )
{
return kvm_set_msr ( vcpu , index , * data ) ;
}
/*
* Read or write a bunch of msrs . All parameters are kernel addresses .
*
* @ return number of msrs set successfully .
*/
static int __msr_io ( struct kvm_vcpu * vcpu , struct kvm_msrs * msrs ,
struct kvm_msr_entry * entries ,
int ( * do_msr ) ( struct kvm_vcpu * vcpu ,
unsigned index , u64 * data ) )
{
int i ;
vcpu_load ( vcpu ) ;
for ( i = 0 ; i < msrs - > nmsrs ; + + i )
if ( do_msr ( vcpu , entries [ i ] . index , & entries [ i ] . data ) )
break ;
vcpu_put ( vcpu ) ;
return i ;
}
/*
* Read or write a bunch of msrs . Parameters are user addresses .
*
* @ return number of msrs set successfully .
*/
static int msr_io ( struct kvm_vcpu * vcpu , struct kvm_msrs __user * user_msrs ,
int ( * do_msr ) ( struct kvm_vcpu * vcpu ,
unsigned index , u64 * data ) ,
int writeback )
{
struct kvm_msrs msrs ;
struct kvm_msr_entry * entries ;
int r , n ;
unsigned size ;
r = - EFAULT ;
if ( copy_from_user ( & msrs , user_msrs , sizeof msrs ) )
goto out ;
r = - E2BIG ;
if ( msrs . nmsrs > = MAX_IO_MSRS )
goto out ;
r = - ENOMEM ;
size = sizeof ( struct kvm_msr_entry ) * msrs . nmsrs ;
entries = vmalloc ( size ) ;
if ( ! entries )
goto out ;
r = - EFAULT ;
if ( copy_from_user ( entries , user_msrs - > entries , size ) )
goto out_free ;
r = n = __msr_io ( vcpu , & msrs , entries , do_msr ) ;
if ( r < 0 )
goto out_free ;
r = - EFAULT ;
if ( writeback & & copy_to_user ( user_msrs - > entries , entries , size ) )
goto out_free ;
r = n ;
out_free :
vfree ( entries ) ;
out :
return r ;
}
2007-10-10 17:16:19 +02:00
long kvm_arch_dev_ioctl ( struct file * filp ,
unsigned int ioctl , unsigned long arg )
{
void __user * argp = ( void __user * ) arg ;
long r ;
switch ( ioctl ) {
case KVM_GET_MSR_INDEX_LIST : {
struct kvm_msr_list __user * user_msr_list = argp ;
struct kvm_msr_list msr_list ;
unsigned n ;
r = - EFAULT ;
if ( copy_from_user ( & msr_list , user_msr_list , sizeof msr_list ) )
goto out ;
n = msr_list . nmsrs ;
msr_list . nmsrs = num_msrs_to_save + ARRAY_SIZE ( emulated_msrs ) ;
if ( copy_to_user ( user_msr_list , & msr_list , sizeof msr_list ) )
goto out ;
r = - E2BIG ;
if ( n < num_msrs_to_save )
goto out ;
r = - EFAULT ;
if ( copy_to_user ( user_msr_list - > indices , & msrs_to_save ,
num_msrs_to_save * sizeof ( u32 ) ) )
goto out ;
if ( copy_to_user ( user_msr_list - > indices
+ num_msrs_to_save * sizeof ( u32 ) ,
& emulated_msrs ,
ARRAY_SIZE ( emulated_msrs ) * sizeof ( u32 ) ) )
goto out ;
r = 0 ;
break ;
}
default :
r = - EINVAL ;
}
out :
return r ;
}
KVM: Portability: split kvm_vcpu_ioctl
This patch splits kvm_vcpu_ioctl into archtecture independent parts, and
x86 specific parts which go to kvm_arch_vcpu_ioctl in x86.c.
Common ioctls for all architectures are:
KVM_RUN, KVM_GET/SET_(S-)REGS, KVM_TRANSLATE, KVM_INTERRUPT,
KVM_DEBUG_GUEST, KVM_SET_SIGNAL_MASK, KVM_GET/SET_FPU
Note that some PPC chips don't have an FPU, so we might need an #ifdef
around KVM_GET/SET_FPU one day.
x86 specific ioctls are:
KVM_GET/SET_LAPIC, KVM_SET_CPUID, KVM_GET/SET_MSRS
An interresting aspect is vcpu_load/vcpu_put. We now have a common
vcpu_load/put which does the preemption stuff, and an architecture
specific kvm_arch_vcpu_load/put. In the x86 case, this one calls the
vmx/svm function defined in kvm_x86_ops.
Signed-off-by: Carsten Otte <cotte@de.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
2007-10-11 19:16:52 +02:00
void kvm_arch_vcpu_load ( struct kvm_vcpu * vcpu , int cpu )
{
kvm_x86_ops - > vcpu_load ( vcpu , cpu ) ;
}
void kvm_arch_vcpu_put ( struct kvm_vcpu * vcpu )
{
kvm_x86_ops - > vcpu_put ( vcpu ) ;
}
static void cpuid_fix_nx_cap ( struct kvm_vcpu * vcpu )
{
u64 efer ;
int i ;
struct kvm_cpuid_entry * e , * entry ;
rdmsrl ( MSR_EFER , efer ) ;
entry = NULL ;
for ( i = 0 ; i < vcpu - > cpuid_nent ; + + i ) {
e = & vcpu - > cpuid_entries [ i ] ;
if ( e - > function = = 0x80000001 ) {
entry = e ;
break ;
}
}
if ( entry & & ( entry - > edx & ( 1 < < 20 ) ) & & ! ( efer & EFER_NX ) ) {
entry - > edx & = ~ ( 1 < < 20 ) ;
printk ( KERN_INFO " kvm: guest NX capability removed \n " ) ;
}
}
static int kvm_vcpu_ioctl_set_cpuid ( struct kvm_vcpu * vcpu ,
struct kvm_cpuid * cpuid ,
struct kvm_cpuid_entry __user * entries )
{
int r ;
r = - E2BIG ;
if ( cpuid - > nent > KVM_MAX_CPUID_ENTRIES )
goto out ;
r = - EFAULT ;
if ( copy_from_user ( & vcpu - > cpuid_entries , entries ,
cpuid - > nent * sizeof ( struct kvm_cpuid_entry ) ) )
goto out ;
vcpu - > cpuid_nent = cpuid - > nent ;
cpuid_fix_nx_cap ( vcpu ) ;
return 0 ;
out :
return r ;
}
static int kvm_vcpu_ioctl_get_lapic ( struct kvm_vcpu * vcpu ,
struct kvm_lapic_state * s )
{
vcpu_load ( vcpu ) ;
memcpy ( s - > regs , vcpu - > apic - > regs , sizeof * s ) ;
vcpu_put ( vcpu ) ;
return 0 ;
}
static int kvm_vcpu_ioctl_set_lapic ( struct kvm_vcpu * vcpu ,
struct kvm_lapic_state * s )
{
vcpu_load ( vcpu ) ;
memcpy ( vcpu - > apic - > regs , s - > regs , sizeof * s ) ;
kvm_apic_post_state_restore ( vcpu ) ;
vcpu_put ( vcpu ) ;
return 0 ;
}
long kvm_arch_vcpu_ioctl ( struct file * filp ,
unsigned int ioctl , unsigned long arg )
{
struct kvm_vcpu * vcpu = filp - > private_data ;
void __user * argp = ( void __user * ) arg ;
int r ;
switch ( ioctl ) {
case KVM_GET_LAPIC : {
struct kvm_lapic_state lapic ;
memset ( & lapic , 0 , sizeof lapic ) ;
r = kvm_vcpu_ioctl_get_lapic ( vcpu , & lapic ) ;
if ( r )
goto out ;
r = - EFAULT ;
if ( copy_to_user ( argp , & lapic , sizeof lapic ) )
goto out ;
r = 0 ;
break ;
}
case KVM_SET_LAPIC : {
struct kvm_lapic_state lapic ;
r = - EFAULT ;
if ( copy_from_user ( & lapic , argp , sizeof lapic ) )
goto out ;
r = kvm_vcpu_ioctl_set_lapic ( vcpu , & lapic ) ; ;
if ( r )
goto out ;
r = 0 ;
break ;
}
case KVM_SET_CPUID : {
struct kvm_cpuid __user * cpuid_arg = argp ;
struct kvm_cpuid cpuid ;
r = - EFAULT ;
if ( copy_from_user ( & cpuid , cpuid_arg , sizeof cpuid ) )
goto out ;
r = kvm_vcpu_ioctl_set_cpuid ( vcpu , & cpuid , cpuid_arg - > entries ) ;
if ( r )
goto out ;
break ;
}
case KVM_GET_MSRS :
r = msr_io ( vcpu , argp , kvm_get_msr , 1 ) ;
break ;
case KVM_SET_MSRS :
r = msr_io ( vcpu , argp , do_set_msr , 0 ) ;
break ;
default :
r = - EINVAL ;
}
out :
return r ;
}
2007-10-10 17:16:19 +02:00
static __init void kvm_init_msr_list ( void )
{
u32 dummy [ 2 ] ;
unsigned i , j ;
for ( i = j = 0 ; i < ARRAY_SIZE ( msrs_to_save ) ; i + + ) {
if ( rdmsr_safe ( msrs_to_save [ i ] , & dummy [ 0 ] , & dummy [ 1 ] ) < 0 )
continue ;
if ( j < i )
msrs_to_save [ j ] = msrs_to_save [ i ] ;
j + + ;
}
num_msrs_to_save = j ;
}
__init void kvm_arch_init ( void )
{
kvm_init_msr_list ( ) ;
}