2011-11-23 16:30:32 +02:00
/*
* Kernel - based Virtual Machine driver for Linux
* cpuid support routines
*
* derived from arch / x86 / kvm / x86 . c
*
* Copyright 2011 Red Hat , Inc . and / or its affiliates .
* Copyright IBM Corporation , 2008
*
* This work is licensed under the terms of the GNU GPL , version 2. See
* the COPYING file in the top - level directory .
*
*/
# include <linux/kvm_host.h>
2016-07-13 20:19:00 -04:00
# include <linux/export.h>
2011-12-14 17:58:18 +01:00
# include <linux/vmalloc.h>
# include <linux/uaccess.h>
2017-02-05 12:07:04 +01:00
# include <linux/sched/stat.h>
2016-11-07 14:03:20 +08:00
# include <asm/processor.h>
2011-11-23 16:30:32 +02:00
# include <asm/user.h>
2015-04-28 08:41:33 +02:00
# include <asm/fpu/xstate.h>
2011-11-23 16:30:32 +02:00
# include "cpuid.h"
# include "lapic.h"
# include "mmu.h"
# include "trace.h"
2015-06-19 13:54:23 +02:00
# include "pmu.h"
2011-11-23 16:30:32 +02:00
2014-12-03 14:38:01 +01:00
static u32 xstate_required_size ( u64 xstate_bv , bool compacted )
2013-10-02 16:06:16 +02:00
{
int feature_bit = 0 ;
u32 ret = XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET ;
2015-09-02 16:31:26 -07:00
xstate_bv & = XFEATURE_MASK_EXTEND ;
2013-10-02 16:06:16 +02:00
while ( xstate_bv ) {
if ( xstate_bv & 0x1 ) {
2014-12-03 14:38:01 +01:00
u32 eax , ebx , ecx , edx , offset ;
2013-10-02 16:06:16 +02:00
cpuid_count ( 0xD , feature_bit , & eax , & ebx , & ecx , & edx ) ;
2014-12-03 14:38:01 +01:00
offset = compacted ? ret : ebx ;
ret = max ( ret , offset + eax ) ;
2013-10-02 16:06:16 +02:00
}
xstate_bv > > = 1 ;
feature_bit + + ;
}
return ret ;
}
2016-03-08 09:52:13 +01:00
bool kvm_mpx_supported ( void )
{
return ( ( host_xcr0 & ( XFEATURE_MASK_BNDREGS | XFEATURE_MASK_BNDCSR ) )
& & kvm_x86_ops - > mpx_supported ( ) ) ;
}
EXPORT_SYMBOL_GPL ( kvm_mpx_supported ) ;
2014-02-24 12:15:16 +01:00
u64 kvm_supported_xcr0 ( void )
{
u64 xcr0 = KVM_SUPPORTED_XCR0 & host_xcr0 ;
2016-03-08 09:52:13 +01:00
if ( ! kvm_mpx_supported ( ) )
2015-09-02 16:31:26 -07:00
xcr0 & = ~ ( XFEATURE_MASK_BNDREGS | XFEATURE_MASK_BNDCSR ) ;
2014-02-24 12:15:16 +01:00
return xcr0 ;
}
2014-12-03 14:34:47 +01:00
# define F(x) bit(X86_FEATURE_##x)
2018-02-01 22:59:42 +01:00
/* For scattered features from cpufeatures.h; we currently expose none */
2016-11-07 14:03:20 +08:00
# define KF(x) bit(KVM_CPUID_BIT_##x)
2014-09-16 15:10:03 +03:00
int kvm_update_cpuid ( struct kvm_vcpu * vcpu )
2011-11-23 16:30:32 +02:00
{
struct kvm_cpuid_entry2 * best ;
struct kvm_lapic * apic = vcpu - > arch . apic ;
best = kvm_find_cpuid_entry ( vcpu , 1 , 0 ) ;
if ( ! best )
2014-09-16 15:10:03 +03:00
return 0 ;
2011-11-23 16:30:32 +02:00
/* Update OSXSAVE bit */
2016-04-04 22:25:02 +02:00
if ( boot_cpu_has ( X86_FEATURE_XSAVE ) & & best - > function = = 0x1 ) {
2014-12-03 14:34:47 +01:00
best - > ecx & = ~ F ( OSXSAVE ) ;
2011-11-23 16:30:32 +02:00
if ( kvm_read_cr4_bits ( vcpu , X86_CR4_OSXSAVE ) )
2014-12-03 14:34:47 +01:00
best - > ecx | = F ( OSXSAVE ) ;
2011-11-23 16:30:32 +02:00
}
2016-11-09 09:50:11 -08:00
best - > edx & = ~ F ( APIC ) ;
if ( vcpu - > arch . apic_base & MSR_IA32_APICBASE_ENABLE )
best - > edx | = F ( APIC ) ;
2011-11-23 16:30:32 +02:00
if ( apic ) {
2014-12-03 14:34:47 +01:00
if ( best - > ecx & F ( TSC_DEADLINE_TIMER ) )
2011-11-23 16:30:32 +02:00
apic - > lapic_timer . timer_mode_mask = 3 < < 17 ;
else
apic - > lapic_timer . timer_mode_mask = 1 < < 17 ;
}
2011-11-10 14:57:22 +02:00
2016-03-22 16:51:21 +08:00
best = kvm_find_cpuid_entry ( vcpu , 7 , 0 ) ;
if ( best ) {
/* Update OSPKE bit */
if ( boot_cpu_has ( X86_FEATURE_PKU ) & & best - > function = = 0x7 ) {
best - > ecx & = ~ F ( OSPKE ) ;
if ( kvm_read_cr4_bits ( vcpu , X86_CR4_PKE ) )
best - > ecx | = F ( OSPKE ) ;
}
}
2013-10-02 16:06:15 +02:00
best = kvm_find_cpuid_entry ( vcpu , 0xD , 0 ) ;
2013-10-02 16:06:16 +02:00
if ( ! best ) {
2013-10-02 16:06:15 +02:00
vcpu - > arch . guest_supported_xcr0 = 0 ;
2013-10-02 16:06:16 +02:00
vcpu - > arch . guest_xstate_size = XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET ;
} else {
2013-10-02 16:06:15 +02:00
vcpu - > arch . guest_supported_xcr0 =
( best - > eax | ( ( u64 ) best - > edx < < 32 ) ) &
2014-02-24 12:15:16 +01:00
kvm_supported_xcr0 ( ) ;
2014-02-21 17:39:02 +00:00
vcpu - > arch . guest_xstate_size = best - > ebx =
2014-12-03 14:38:01 +01:00
xstate_required_size ( vcpu - > arch . xcr0 , false ) ;
2013-10-02 16:06:16 +02:00
}
2013-10-02 16:06:15 +02:00
2014-12-03 14:38:01 +01:00
best = kvm_find_cpuid_entry ( vcpu , 0xD , 1 ) ;
if ( best & & ( best - > eax & ( F ( XSAVES ) | F ( XSAVEC ) ) ) )
best - > ebx = xstate_required_size ( vcpu - > arch . xcr0 , true ) ;
2014-09-16 15:10:03 +03:00
/*
2017-08-24 20:27:56 +08:00
* The existing code assumes virtual address is 48 - bit or 57 - bit in the
* canonical address checks ; exit if it is ever changed .
2014-09-16 15:10:03 +03:00
*/
best = kvm_find_cpuid_entry ( vcpu , 0x80000008 , 0 ) ;
2017-08-24 20:27:56 +08:00
if ( best ) {
int vaddr_bits = ( best - > eax & 0xff00 ) > > 8 ;
if ( vaddr_bits ! = 48 & & vaddr_bits ! = 57 & & vaddr_bits ! = 0 )
return - EINVAL ;
}
2014-09-16 15:10:03 +03:00
2018-03-12 04:53:03 -07:00
best = kvm_find_cpuid_entry ( vcpu , KVM_CPUID_FEATURES , 0 ) ;
if ( kvm_hlt_in_guest ( vcpu - > kvm ) & & best & &
( best - > eax & ( 1 < < KVM_FEATURE_PV_UNHALT ) ) )
best - > eax & = ~ ( 1 < < KVM_FEATURE_PV_UNHALT ) ;
2015-03-29 23:56:12 +03:00
/* Update physical-address width */
vcpu - > arch . maxphyaddr = cpuid_query_maxphyaddr ( vcpu ) ;
2017-08-24 20:27:55 +08:00
kvm_mmu_reset_context ( vcpu ) ;
2015-03-29 23:56:12 +03:00
2015-06-19 13:44:45 +02:00
kvm_pmu_refresh ( vcpu ) ;
2014-09-16 15:10:03 +03:00
return 0 ;
2011-11-23 16:30:32 +02:00
}
static int is_efer_nx ( void )
{
unsigned long long efer = 0 ;
rdmsrl_safe ( MSR_EFER , & efer ) ;
return efer & EFER_NX ;
}
static void cpuid_fix_nx_cap ( struct kvm_vcpu * vcpu )
{
int i ;
struct kvm_cpuid_entry2 * e , * entry ;
entry = NULL ;
for ( i = 0 ; i < vcpu - > arch . cpuid_nent ; + + i ) {
e = & vcpu - > arch . cpuid_entries [ i ] ;
if ( e - > function = = 0x80000001 ) {
entry = e ;
break ;
}
}
2014-12-03 14:34:47 +01:00
if ( entry & & ( entry - > edx & F ( NX ) ) & & ! is_efer_nx ( ) ) {
entry - > edx & = ~ F ( NX ) ;
2011-11-23 16:30:32 +02:00
printk ( KERN_INFO " kvm: guest NX capability removed \n " ) ;
}
}
2015-03-29 23:56:12 +03:00
int cpuid_query_maxphyaddr ( struct kvm_vcpu * vcpu )
{
struct kvm_cpuid_entry2 * best ;
best = kvm_find_cpuid_entry ( vcpu , 0x80000000 , 0 ) ;
if ( ! best | | best - > eax < 0x80000008 )
goto not_found ;
best = kvm_find_cpuid_entry ( vcpu , 0x80000008 , 0 ) ;
if ( best )
return best - > eax & 0xff ;
not_found :
return 36 ;
}
EXPORT_SYMBOL_GPL ( cpuid_query_maxphyaddr ) ;
2011-11-23 16:30:32 +02:00
/* when an old userspace process fills a new kernel module */
int kvm_vcpu_ioctl_set_cpuid ( struct kvm_vcpu * vcpu ,
struct kvm_cpuid * cpuid ,
struct kvm_cpuid_entry __user * entries )
{
int r , i ;
2016-06-01 14:09:19 +02:00
struct kvm_cpuid_entry * cpuid_entries = NULL ;
2011-11-23 16:30:32 +02:00
r = - E2BIG ;
if ( cpuid - > nent > KVM_MAX_CPUID_ENTRIES )
goto out ;
r = - ENOMEM ;
2016-06-01 14:09:19 +02:00
if ( cpuid - > nent ) {
treewide: Use array_size() in vmalloc()
The vmalloc() function has no 2-factor argument form, so multiplication
factors need to be wrapped in array_size(). This patch replaces cases of:
vmalloc(a * b)
with:
vmalloc(array_size(a, b))
as well as handling cases of:
vmalloc(a * b * c)
with:
vmalloc(array3_size(a, b, c))
This does, however, attempt to ignore constant size factors like:
vmalloc(4 * 1024)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
type TYPE;
expression THING, E;
@@
(
vmalloc(
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
vmalloc(
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression COUNT;
typedef u8;
typedef __u8;
@@
(
vmalloc(
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
vmalloc(
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
vmalloc(
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
vmalloc(
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
vmalloc(
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
vmalloc(
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
vmalloc(
- sizeof(char) * COUNT
+ COUNT
, ...)
|
vmalloc(
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
vmalloc(
- sizeof(TYPE) * (COUNT_ID)
+ array_size(COUNT_ID, sizeof(TYPE))
, ...)
|
vmalloc(
- sizeof(TYPE) * COUNT_ID
+ array_size(COUNT_ID, sizeof(TYPE))
, ...)
|
vmalloc(
- sizeof(TYPE) * (COUNT_CONST)
+ array_size(COUNT_CONST, sizeof(TYPE))
, ...)
|
vmalloc(
- sizeof(TYPE) * COUNT_CONST
+ array_size(COUNT_CONST, sizeof(TYPE))
, ...)
|
vmalloc(
- sizeof(THING) * (COUNT_ID)
+ array_size(COUNT_ID, sizeof(THING))
, ...)
|
vmalloc(
- sizeof(THING) * COUNT_ID
+ array_size(COUNT_ID, sizeof(THING))
, ...)
|
vmalloc(
- sizeof(THING) * (COUNT_CONST)
+ array_size(COUNT_CONST, sizeof(THING))
, ...)
|
vmalloc(
- sizeof(THING) * COUNT_CONST
+ array_size(COUNT_CONST, sizeof(THING))
, ...)
)
// 2-factor product, only identifiers.
@@
identifier SIZE, COUNT;
@@
vmalloc(
- SIZE * COUNT
+ array_size(COUNT, SIZE)
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
vmalloc(
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
vmalloc(
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
vmalloc(
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
vmalloc(
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
vmalloc(
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
vmalloc(
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
vmalloc(
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
vmalloc(
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
vmalloc(
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
vmalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
vmalloc(
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
vmalloc(
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
vmalloc(
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
vmalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
identifier STRIDE, SIZE, COUNT;
@@
(
vmalloc(
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
vmalloc(
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
vmalloc(
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
vmalloc(
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
vmalloc(
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
vmalloc(
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
vmalloc(
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
vmalloc(
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products
// when they're not all constants...
@@
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
vmalloc(C1 * C2 * C3, ...)
|
vmalloc(
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants.
@@
expression E1, E2;
constant C1, C2;
@@
(
vmalloc(C1 * C2, ...)
|
vmalloc(
- E1 * E2
+ array_size(E1, E2)
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-12 14:27:11 -07:00
cpuid_entries =
vmalloc ( array_size ( sizeof ( struct kvm_cpuid_entry ) ,
cpuid - > nent ) ) ;
2016-06-01 14:09:19 +02:00
if ( ! cpuid_entries )
goto out ;
r = - EFAULT ;
if ( copy_from_user ( cpuid_entries , entries ,
cpuid - > nent * sizeof ( struct kvm_cpuid_entry ) ) )
goto out ;
}
2011-11-23 16:30:32 +02:00
for ( i = 0 ; i < cpuid - > nent ; i + + ) {
vcpu - > arch . cpuid_entries [ i ] . function = cpuid_entries [ i ] . function ;
vcpu - > arch . cpuid_entries [ i ] . eax = cpuid_entries [ i ] . eax ;
vcpu - > arch . cpuid_entries [ i ] . ebx = cpuid_entries [ i ] . ebx ;
vcpu - > arch . cpuid_entries [ i ] . ecx = cpuid_entries [ i ] . ecx ;
vcpu - > arch . cpuid_entries [ i ] . edx = cpuid_entries [ i ] . edx ;
vcpu - > arch . cpuid_entries [ i ] . index = 0 ;
vcpu - > arch . cpuid_entries [ i ] . flags = 0 ;
vcpu - > arch . cpuid_entries [ i ] . padding [ 0 ] = 0 ;
vcpu - > arch . cpuid_entries [ i ] . padding [ 1 ] = 0 ;
vcpu - > arch . cpuid_entries [ i ] . padding [ 2 ] = 0 ;
}
vcpu - > arch . cpuid_nent = cpuid - > nent ;
cpuid_fix_nx_cap ( vcpu ) ;
kvm_apic_set_version ( vcpu ) ;
kvm_x86_ops - > cpuid_update ( vcpu ) ;
2014-09-16 15:10:03 +03:00
r = kvm_update_cpuid ( vcpu ) ;
2011-11-23 16:30:32 +02:00
out :
2016-06-01 14:09:19 +02:00
vfree ( cpuid_entries ) ;
2011-11-23 16:30:32 +02:00
return r ;
}
int kvm_vcpu_ioctl_set_cpuid2 ( struct kvm_vcpu * vcpu ,
struct kvm_cpuid2 * cpuid ,
struct kvm_cpuid_entry2 __user * entries )
{
int r ;
r = - E2BIG ;
if ( cpuid - > nent > KVM_MAX_CPUID_ENTRIES )
goto out ;
r = - EFAULT ;
if ( copy_from_user ( & vcpu - > arch . cpuid_entries , entries ,
cpuid - > nent * sizeof ( struct kvm_cpuid_entry2 ) ) )
goto out ;
vcpu - > arch . cpuid_nent = cpuid - > nent ;
kvm_apic_set_version ( vcpu ) ;
kvm_x86_ops - > cpuid_update ( vcpu ) ;
2014-09-16 15:10:03 +03:00
r = kvm_update_cpuid ( vcpu ) ;
2011-11-23 16:30:32 +02:00
out :
return r ;
}
int kvm_vcpu_ioctl_get_cpuid2 ( struct kvm_vcpu * vcpu ,
struct kvm_cpuid2 * cpuid ,
struct kvm_cpuid_entry2 __user * entries )
{
int r ;
r = - E2BIG ;
if ( cpuid - > nent < vcpu - > arch . cpuid_nent )
goto out ;
r = - EFAULT ;
if ( copy_to_user ( entries , & vcpu - > arch . cpuid_entries ,
vcpu - > arch . cpuid_nent * sizeof ( struct kvm_cpuid_entry2 ) ) )
goto out ;
return 0 ;
out :
cpuid - > nent = vcpu - > arch . cpuid_nent ;
return r ;
}
static void cpuid_mask ( u32 * word , int wordnum )
{
* word & = boot_cpu_data . x86_capability [ wordnum ] ;
}
static void do_cpuid_1_ent ( struct kvm_cpuid_entry2 * entry , u32 function ,
u32 index )
{
entry - > function = function ;
entry - > index = index ;
cpuid_count ( entry - > function , entry - > index ,
& entry - > eax , & entry - > ebx , & entry - > ecx , & entry - > edx ) ;
entry - > flags = 0 ;
}
2013-09-22 16:44:50 +02:00
static int __do_cpuid_ent_emulated ( struct kvm_cpuid_entry2 * entry ,
u32 func , u32 index , int * nent , int maxnent )
{
2013-10-29 12:54:56 +01:00
switch ( func ) {
case 0 :
2016-07-12 11:04:26 +02:00
entry - > eax = 7 ;
2013-10-29 12:54:56 +01:00
+ + * nent ;
break ;
case 1 :
entry - > ecx = F ( MOVBE ) ;
+ + * nent ;
break ;
2016-07-12 11:04:26 +02:00
case 7 :
entry - > flags | = KVM_CPUID_FLAG_SIGNIFCANT_INDEX ;
if ( index = = 0 )
entry - > ecx = F ( RDPID ) ;
+ + * nent ;
2013-10-29 12:54:56 +01:00
default :
break ;
}
entry - > function = func ;
entry - > index = index ;
2013-09-22 16:44:50 +02:00
return 0 ;
}
static inline int __do_cpuid_ent ( struct kvm_cpuid_entry2 * entry , u32 function ,
u32 index , int * nent , int maxnent )
2011-11-23 16:30:32 +02:00
{
2011-11-28 11:20:29 +02:00
int r ;
2011-11-23 16:30:32 +02:00
unsigned f_nx = is_efer_nx ( ) ? F ( NX ) : 0 ;
# ifdef CONFIG_X86_64
unsigned f_gbpages = ( kvm_x86_ops - > get_lpage_level ( ) = = PT_PDPE_LEVEL )
? F ( GBPAGES ) : 0 ;
unsigned f_lm = F ( LM ) ;
# else
unsigned f_gbpages = 0 ;
unsigned f_lm = 0 ;
# endif
unsigned f_rdtscp = kvm_x86_ops - > rdtscp_supported ( ) ? F ( RDTSCP ) : 0 ;
2012-07-02 01:18:48 +00:00
unsigned f_invpcid = kvm_x86_ops - > invpcid_supported ( ) ? F ( INVPCID ) : 0 ;
2016-03-08 09:52:13 +01:00
unsigned f_mpx = kvm_mpx_supported ( ) ? F ( MPX ) : 0 ;
2014-12-02 19:21:30 +08:00
unsigned f_xsaves = kvm_x86_ops - > xsaves_supported ( ) ? F ( XSAVES ) : 0 ;
2016-07-12 10:36:41 +02:00
unsigned f_umip = kvm_x86_ops - > umip_emulated ( ) ? F ( UMIP ) : 0 ;
2011-11-23 16:30:32 +02:00
/* cpuid 1.edx */
2016-03-22 16:51:14 +08:00
const u32 kvm_cpuid_1_edx_x86_features =
2011-11-23 16:30:32 +02:00
F ( FPU ) | F ( VME ) | F ( DE ) | F ( PSE ) |
F ( TSC ) | F ( MSR ) | F ( PAE ) | F ( MCE ) |
F ( CX8 ) | F ( APIC ) | 0 /* Reserved */ | F ( SEP ) |
F ( MTRR ) | F ( PGE ) | F ( MCA ) | F ( CMOV ) |
2014-02-27 08:31:30 -08:00
F ( PAT ) | F ( PSE36 ) | 0 /* PSN */ | F ( CLFLUSH ) |
2011-11-23 16:30:32 +02:00
0 /* Reserved, DS, ACPI */ | F ( MMX ) |
F ( FXSR ) | F ( XMM ) | F ( XMM2 ) | F ( SELFSNOOP ) |
0 /* HTT, TM, Reserved, PBE */ ;
/* cpuid 0x80000001.edx */
2016-03-22 16:51:14 +08:00
const u32 kvm_cpuid_8000_0001_edx_x86_features =
2011-11-23 16:30:32 +02:00
F ( FPU ) | F ( VME ) | F ( DE ) | F ( PSE ) |
F ( TSC ) | F ( MSR ) | F ( PAE ) | F ( MCE ) |
F ( CX8 ) | F ( APIC ) | 0 /* Reserved */ | F ( SYSCALL ) |
F ( MTRR ) | F ( PGE ) | F ( MCA ) | F ( CMOV ) |
F ( PAT ) | F ( PSE36 ) | 0 /* Reserved */ |
f_nx | 0 /* Reserved */ | F ( MMXEXT ) | F ( MMX ) |
F ( FXSR ) | F ( FXSR_OPT ) | f_gbpages | f_rdtscp |
0 /* Reserved */ | f_lm | F ( 3 DNOWEXT ) | F ( 3 DNOW ) ;
/* cpuid 1.ecx */
2016-03-22 16:51:14 +08:00
const u32 kvm_cpuid_1_ecx_x86_features =
2014-05-07 16:52:13 -04:00
/* NOTE: MONITOR (and MWAIT) are emulated as NOP,
* but * not * advertised to guests via CPUID ! */
2011-11-23 16:30:32 +02:00
F ( XMM3 ) | F ( PCLMULQDQ ) | 0 /* DTES64, MONITOR */ |
0 /* DS-CPL, VMX, SMX, EST */ |
0 /* TM2 */ | F ( SSSE3 ) | 0 /* CNXT-ID */ | 0 /* Reserved */ |
2011-11-28 03:55:19 -08:00
F ( FMA ) | F ( CX16 ) | 0 /* xTPR Update, PDCM */ |
2012-07-02 01:18:48 +00:00
F ( PCID ) | 0 /* Reserved, DCA */ | F ( XMM4_1 ) |
2011-11-23 16:30:32 +02:00
F ( XMM4_2 ) | F ( X2APIC ) | F ( MOVBE ) | F ( POPCNT ) |
0 /* Reserved*/ | F ( AES ) | F ( XSAVE ) | 0 /* OSXSAVE */ | F ( AVX ) |
F ( F16C ) | F ( RDRAND ) ;
/* cpuid 0x80000001.ecx */
2016-03-22 16:51:14 +08:00
const u32 kvm_cpuid_8000_0001_ecx_x86_features =
2011-11-23 16:30:32 +02:00
F ( LAHF_LM ) | F ( CMP_LEGACY ) | 0 /*SVM*/ | 0 /* ExtApicSpace */ |
F ( CR8_LEGACY ) | F ( ABM ) | F ( SSE4A ) | F ( MISALIGNSSE ) |
2012-01-09 14:00:35 -05:00
F ( 3 DNOWPREFETCH ) | F ( OSVW ) | 0 /* IBS */ | F ( XOP ) |
2018-01-29 11:39:44 -05:00
0 /* SKINIT, WDT, LWP */ | F ( FMA4 ) | F ( TBM ) |
2018-02-05 13:24:52 -06:00
F ( TOPOEXT ) | F ( PERFCTR_CORE ) ;
2011-11-23 16:30:32 +02:00
2018-02-01 22:59:43 +01:00
/* cpuid 0x80000008.ebx */
const u32 kvm_cpuid_8000_0008_ebx_x86_features =
2018-06-01 10:59:20 -04:00
F ( AMD_IBPB ) | F ( AMD_IBRS ) | F ( AMD_SSBD ) | F ( VIRT_SSBD ) |
F ( AMD_SSB_NO ) ;
2018-02-01 22:59:43 +01:00
2011-11-23 16:30:32 +02:00
/* cpuid 0xC0000001.edx */
2016-03-22 16:51:14 +08:00
const u32 kvm_cpuid_C000_0001_edx_x86_features =
2011-11-23 16:30:32 +02:00
F ( XSTORE ) | F ( XSTORE_EN ) | F ( XCRYPT ) | F ( XCRYPT_EN ) |
F ( ACE2 ) | F ( ACE2_EN ) | F ( PHE ) | F ( PHE_EN ) |
F ( PMM ) | F ( PMM_EN ) ;
/* cpuid 7.0.ebx */
2016-03-22 16:51:14 +08:00
const u32 kvm_cpuid_7_0_ebx_x86_features =
2012-02-28 05:15:46 +00:00
F ( FSGSBASE ) | F ( BMI1 ) | F ( HLE ) | F ( AVX2 ) | F ( SMEP ) |
2014-02-24 10:58:09 +00:00
F ( BMI2 ) | F ( ERMS ) | f_invpcid | F ( RTM ) | f_mpx | F ( RDSEED ) |
2016-12-14 10:42:29 +08:00
F ( ADX ) | F ( SMAP ) | F ( AVX512IFMA ) | F ( AVX512F ) | F ( AVX512PF ) |
F ( AVX512ER ) | F ( AVX512CD ) | F ( CLFLUSHOPT ) | F ( CLWB ) | F ( AVX512DQ ) |
F ( SHA_NI ) | F ( AVX512BW ) | F ( AVX512VL ) ;
2011-11-23 16:30:32 +02:00
2014-11-21 18:13:26 +01:00
/* cpuid 0xD.1.eax */
2016-03-22 16:51:14 +08:00
const u32 kvm_cpuid_D_1_eax_x86_features =
2014-12-02 19:21:30 +08:00
F ( XSAVEOPT ) | F ( XSAVEC ) | F ( XGETBV1 ) | f_xsaves ;
2014-11-21 18:13:26 +01:00
2016-03-22 16:51:21 +08:00
/* cpuid 7.0.ecx*/
2016-12-14 10:42:29 +08:00
const u32 kvm_cpuid_7_0_ecx_x86_features =
2016-07-12 10:36:41 +02:00
F ( AVX512VBMI ) | F ( LA57 ) | F ( PKU ) | 0 /*OSPKE*/ |
2017-11-22 15:27:29 +08:00
F ( AVX512_VPOPCNTDQ ) | F ( UMIP ) | F ( AVX512_VBMI2 ) | F ( GFNI ) |
F ( VAES ) | F ( VPCLMULQDQ ) | F ( AVX512_VNNI ) | F ( AVX512_BITALG ) ;
2016-03-22 16:51:21 +08:00
2016-11-07 14:03:20 +08:00
/* cpuid 7.0.edx*/
const u32 kvm_cpuid_7_0_edx_x86_features =
2018-05-21 17:54:49 -04:00
F ( AVX512_4VNNIW ) | F ( AVX512_4FMAPS ) | F ( SPEC_CTRL ) |
F ( SPEC_CTRL_SSBD ) | F ( ARCH_CAPABILITIES ) ;
2016-11-07 14:03:20 +08:00
2011-11-23 16:30:32 +02:00
/* all calls to cpuid_count() should be made on the same cpu */
get_cpu ( ) ;
2011-11-28 11:20:29 +02:00
r = - E2BIG ;
if ( * nent > = maxnent )
goto out ;
2011-11-23 16:30:32 +02:00
do_cpuid_1_ent ( entry , function , index ) ;
+ + * nent ;
switch ( function ) {
case 0 :
entry - > eax = min ( entry - > eax , ( u32 ) 0xd ) ;
break ;
case 1 :
2016-03-22 16:51:14 +08:00
entry - > edx & = kvm_cpuid_1_edx_x86_features ;
cpuid_mask ( & entry - > edx , CPUID_1_EDX ) ;
entry - > ecx & = kvm_cpuid_1_ecx_x86_features ;
cpuid_mask ( & entry - > ecx , CPUID_1_ECX ) ;
2011-11-23 16:30:32 +02:00
/* we support x2apic emulation even if host does not support
* it since we emulate x2apic in software */
entry - > ecx | = F ( X2APIC ) ;
break ;
/* function 2 entries are STATEFUL. That is, repeated cpuid commands
* may return different values . This forces us to get_cpu ( ) before
* issuing the first command , and also to emulate this annoying behavior
* in kvm_emulate_cpuid ( ) using KVM_CPUID_FLAG_STATE_READ_NEXT */
case 2 : {
int t , times = entry - > eax & 0xff ;
entry - > flags | = KVM_CPUID_FLAG_STATEFUL_FUNC ;
entry - > flags | = KVM_CPUID_FLAG_STATE_READ_NEXT ;
2011-11-28 11:20:29 +02:00
for ( t = 1 ; t < times ; + + t ) {
if ( * nent > = maxnent )
goto out ;
2011-11-23 16:30:32 +02:00
do_cpuid_1_ent ( & entry [ t ] , function , 0 ) ;
entry [ t ] . flags | = KVM_CPUID_FLAG_STATEFUL_FUNC ;
+ + * nent ;
}
break ;
}
/* function 4 has additional index. */
case 4 : {
int i , cache_type ;
entry - > flags | = KVM_CPUID_FLAG_SIGNIFCANT_INDEX ;
/* read more entries until cache_type is zero */
2011-11-28 11:20:29 +02:00
for ( i = 1 ; ; + + i ) {
if ( * nent > = maxnent )
goto out ;
2011-11-23 16:30:32 +02:00
cache_type = entry [ i - 1 ] . eax & 0x1f ;
if ( ! cache_type )
break ;
do_cpuid_1_ent ( & entry [ i ] , function , i ) ;
entry [ i ] . flags | =
KVM_CPUID_FLAG_SIGNIFCANT_INDEX ;
+ + * nent ;
}
break ;
}
2015-05-24 17:22:38 +02:00
case 6 : /* Thermal management */
entry - > eax = 0x4 ; /* allow ARAT */
entry - > ebx = 0 ;
entry - > ecx = 0 ;
entry - > edx = 0 ;
break ;
2011-11-23 16:30:32 +02:00
case 7 : {
entry - > flags | = KVM_CPUID_FLAG_SIGNIFCANT_INDEX ;
2012-06-28 15:20:58 +08:00
/* Mask ebx against host capability word 9 */
2011-11-23 16:30:32 +02:00
if ( index = = 0 ) {
2016-03-22 16:51:14 +08:00
entry - > ebx & = kvm_cpuid_7_0_ebx_x86_features ;
cpuid_mask ( & entry - > ebx , CPUID_7_0_EBX ) ;
2012-11-29 12:42:50 -08:00
// TSC_ADJUST is emulated
entry - > ebx | = F ( TSC_ADJUST ) ;
2016-03-22 16:51:21 +08:00
entry - > ecx & = kvm_cpuid_7_0_ecx_x86_features ;
cpuid_mask ( & entry - > ecx , CPUID_7_ECX ) ;
2016-07-12 10:36:41 +02:00
entry - > ecx | = f_umip ;
2016-03-22 16:51:21 +08:00
/* PKU is not yet implemented for shadow paging. */
2017-08-24 11:59:31 +02:00
if ( ! tdp_enabled | | ! boot_cpu_has ( X86_FEATURE_OSPKE ) )
2016-03-22 16:51:21 +08:00
entry - > ecx & = ~ F ( PKU ) ;
2016-11-07 14:03:20 +08:00
entry - > edx & = kvm_cpuid_7_0_edx_x86_features ;
2018-02-01 22:59:42 +01:00
cpuid_mask ( & entry - > edx , CPUID_7_EDX ) ;
2018-05-09 14:29:35 -07:00
/*
* We emulate ARCH_CAPABILITIES in software even
* if the host doesn ' t support it .
*/
entry - > edx | = F ( ARCH_CAPABILITIES ) ;
2016-03-22 16:51:21 +08:00
} else {
2011-11-23 16:30:32 +02:00
entry - > ebx = 0 ;
2016-03-22 16:51:21 +08:00
entry - > ecx = 0 ;
2016-11-07 14:03:20 +08:00
entry - > edx = 0 ;
2016-03-22 16:51:21 +08:00
}
2011-11-23 16:30:32 +02:00
entry - > eax = 0 ;
break ;
}
case 9 :
break ;
2011-11-10 14:57:28 +02:00
case 0xa : { /* Architectural Performance Monitoring */
struct x86_pmu_capability cap ;
union cpuid10_eax eax ;
union cpuid10_edx edx ;
perf_get_x86_pmu_capability ( & cap ) ;
/*
* Only support guest architectural pmu on a host
* with architectural pmu .
*/
if ( ! cap . version )
memset ( & cap , 0 , sizeof ( cap ) ) ;
eax . split . version_id = min ( cap . version , 2 ) ;
eax . split . num_counters = cap . num_counters_gp ;
eax . split . bit_width = cap . bit_width_gp ;
eax . split . mask_length = cap . events_mask_len ;
edx . split . num_counters_fixed = cap . num_counters_fixed ;
edx . split . bit_width_fixed = cap . bit_width_fixed ;
edx . split . reserved = 0 ;
entry - > eax = eax . full ;
entry - > ebx = cap . events_mask ;
entry - > ecx = 0 ;
entry - > edx = edx . full ;
break ;
}
2011-11-23 16:30:32 +02:00
/* function 0xb has additional index. */
case 0xb : {
int i , level_type ;
entry - > flags | = KVM_CPUID_FLAG_SIGNIFCANT_INDEX ;
/* read more entries until level_type is zero */
2011-11-28 11:20:29 +02:00
for ( i = 1 ; ; + + i ) {
if ( * nent > = maxnent )
goto out ;
2011-11-23 16:30:32 +02:00
level_type = entry [ i - 1 ] . ecx & 0xff00 ;
if ( ! level_type )
break ;
do_cpuid_1_ent ( & entry [ i ] , function , i ) ;
entry [ i ] . flags | =
KVM_CPUID_FLAG_SIGNIFCANT_INDEX ;
+ + * nent ;
}
break ;
}
case 0xd : {
int idx , i ;
2014-02-24 12:15:16 +01:00
u64 supported = kvm_supported_xcr0 ( ) ;
2011-11-23 16:30:32 +02:00
2014-02-24 12:15:16 +01:00
entry - > eax & = supported ;
2014-12-04 18:30:41 +01:00
entry - > ebx = xstate_required_size ( supported , false ) ;
entry - > ecx = entry - > ebx ;
2014-02-24 12:15:16 +01:00
entry - > edx & = supported > > 32 ;
2011-11-23 16:30:32 +02:00
entry - > flags | = KVM_CPUID_FLAG_SIGNIFCANT_INDEX ;
2014-11-21 18:13:26 +01:00
if ( ! supported )
break ;
2011-11-28 11:20:29 +02:00
for ( idx = 1 , i = 1 ; idx < 64 ; + + idx ) {
2014-02-24 12:15:16 +01:00
u64 mask = ( ( u64 ) 1 < < idx ) ;
2011-11-28 11:20:29 +02:00
if ( * nent > = maxnent )
goto out ;
2011-11-23 16:30:32 +02:00
do_cpuid_1_ent ( & entry [ i ] , function , idx ) ;
2014-12-03 14:38:01 +01:00
if ( idx = = 1 ) {
2016-03-22 16:51:14 +08:00
entry [ i ] . eax & = kvm_cpuid_D_1_eax_x86_features ;
2016-03-21 12:33:00 +01:00
cpuid_mask ( & entry [ i ] . eax , CPUID_D_1_EAX ) ;
2014-12-03 14:38:01 +01:00
entry [ i ] . ebx = 0 ;
if ( entry [ i ] . eax & ( F ( XSAVES ) | F ( XSAVEC ) ) )
entry [ i ] . ebx =
xstate_required_size ( supported ,
true ) ;
2014-12-04 15:11:11 +01:00
} else {
if ( entry [ i ] . eax = = 0 | | ! ( supported & mask ) )
continue ;
if ( WARN_ON_ONCE ( entry [ i ] . ecx & 1 ) )
continue ;
}
entry [ i ] . ecx = 0 ;
entry [ i ] . edx = 0 ;
2011-11-23 16:30:32 +02:00
entry [ i ] . flags | =
KVM_CPUID_FLAG_SIGNIFCANT_INDEX ;
+ + * nent ;
+ + i ;
}
break ;
}
case KVM_CPUID_SIGNATURE : {
2012-08-30 01:30:13 +02:00
static const char signature [ 12 ] = " KVMKVMKVM \0 \0 " ;
const u32 * sigptr = ( const u32 * ) signature ;
2012-05-02 17:55:56 +03:00
entry - > eax = KVM_CPUID_FEATURES ;
2011-11-23 16:30:32 +02:00
entry - > ebx = sigptr [ 0 ] ;
entry - > ecx = sigptr [ 1 ] ;
entry - > edx = sigptr [ 2 ] ;
break ;
}
case KVM_CPUID_FEATURES :
entry - > eax = ( 1 < < KVM_FEATURE_CLOCKSOURCE ) |
( 1 < < KVM_FEATURE_NOP_IO_DELAY ) |
( 1 < < KVM_FEATURE_CLOCKSOURCE2 ) |
( 1 < < KVM_FEATURE_ASYNC_PF ) |
2012-06-24 19:25:07 +03:00
( 1 < < KVM_FEATURE_PV_EOI ) |
2013-08-26 14:18:34 +05:30
( 1 < < KVM_FEATURE_CLOCKSOURCE_STABLE_BIT ) |
2017-12-12 17:33:04 -08:00
( 1 < < KVM_FEATURE_PV_UNHALT ) |
2018-02-01 22:16:21 +01:00
( 1 < < KVM_FEATURE_PV_TLB_FLUSH ) |
( 1 < < KVM_FEATURE_ASYNC_PF_VMEXIT ) ;
2011-11-23 16:30:32 +02:00
if ( sched_info_on ( ) )
entry - > eax | = ( 1 < < KVM_FEATURE_STEAL_TIME ) ;
entry - > ebx = 0 ;
entry - > ecx = 0 ;
entry - > edx = 0 ;
break ;
case 0x80000000 :
2017-12-04 10:57:25 -06:00
entry - > eax = min ( entry - > eax , 0x8000001f ) ;
2011-11-23 16:30:32 +02:00
break ;
case 0x80000001 :
2016-03-22 16:51:14 +08:00
entry - > edx & = kvm_cpuid_8000_0001_edx_x86_features ;
cpuid_mask ( & entry - > edx , CPUID_8000_0001_EDX ) ;
entry - > ecx & = kvm_cpuid_8000_0001_ecx_x86_features ;
cpuid_mask ( & entry - > ecx , CPUID_8000_0001_ECX ) ;
2011-11-23 16:30:32 +02:00
break ;
2014-04-26 22:30:23 -03:00
case 0x80000007 : /* Advanced power management */
/* invariant TSC is CPUID.80000007H:EDX[8] */
entry - > edx & = ( 1 < < 8 ) ;
/* mask against host */
entry - > edx & = boot_cpu_data . x86_power ;
entry - > eax = entry - > ebx = entry - > ecx = 0 ;
break ;
2011-11-23 16:30:32 +02:00
case 0x80000008 : {
unsigned g_phys_as = ( entry - > eax > > 16 ) & 0xff ;
unsigned virt_as = max ( ( entry - > eax > > 8 ) & 0xff , 48U ) ;
unsigned phys_as = entry - > eax & 0xff ;
if ( ! g_phys_as )
g_phys_as = phys_as ;
entry - > eax = g_phys_as | ( virt_as < < 8 ) ;
2018-02-01 22:59:43 +01:00
entry - > edx = 0 ;
2018-05-10 22:06:39 +02:00
/*
* IBRS , IBPB and VIRT_SSBD aren ' t necessarily present in
* hardware cpuid
*/
2018-05-02 18:15:14 +02:00
if ( boot_cpu_has ( X86_FEATURE_AMD_IBPB ) )
entry - > ebx | = F ( AMD_IBPB ) ;
if ( boot_cpu_has ( X86_FEATURE_AMD_IBRS ) )
entry - > ebx | = F ( AMD_IBRS ) ;
2018-05-10 22:06:39 +02:00
if ( boot_cpu_has ( X86_FEATURE_VIRT_SSBD ) )
entry - > ebx | = F ( VIRT_SSBD ) ;
2018-02-01 22:59:43 +01:00
entry - > ebx & = kvm_cpuid_8000_0008_ebx_x86_features ;
cpuid_mask ( & entry - > ebx , CPUID_8000_0008_EBX ) ;
2018-06-01 10:59:20 -04:00
/*
* The preference is to use SPEC CTRL MSR instead of the
* VIRT_SPEC MSR .
*/
if ( boot_cpu_has ( X86_FEATURE_LS_CFG_SSBD ) & &
! boot_cpu_has ( X86_FEATURE_AMD_SSBD ) )
2018-05-10 22:06:39 +02:00
entry - > ebx | = F ( VIRT_SSBD ) ;
2011-11-23 16:30:32 +02:00
break ;
}
case 0x80000019 :
entry - > ecx = entry - > edx = 0 ;
break ;
case 0x8000001a :
break ;
case 0x8000001d :
break ;
/*Add support for Centaur's CPUID instruction*/
case 0xC0000000 :
/*Just support up to 0xC0000004 now*/
entry - > eax = min ( entry - > eax , 0xC0000004 ) ;
break ;
case 0xC0000001 :
2016-03-22 16:51:14 +08:00
entry - > edx & = kvm_cpuid_C000_0001_edx_x86_features ;
cpuid_mask ( & entry - > edx , CPUID_C000_0001_EDX ) ;
2011-11-23 16:30:32 +02:00
break ;
case 3 : /* Processor serial number */
case 5 : /* MONITOR/MWAIT */
case 0xC0000002 :
case 0xC0000003 :
case 0xC0000004 :
default :
entry - > eax = entry - > ebx = entry - > ecx = entry - > edx = 0 ;
break ;
}
kvm_x86_ops - > set_supported_cpuid ( function , entry ) ;
2011-11-28 11:20:29 +02:00
r = 0 ;
out :
2011-11-23 16:30:32 +02:00
put_cpu ( ) ;
2011-11-28 11:20:29 +02:00
return r ;
2011-11-23 16:30:32 +02:00
}
2013-09-22 16:44:50 +02:00
static int do_cpuid_ent ( struct kvm_cpuid_entry2 * entry , u32 func ,
u32 idx , int * nent , int maxnent , unsigned int type )
{
if ( type = = KVM_GET_EMULATED_CPUID )
return __do_cpuid_ent_emulated ( entry , func , idx , nent , maxnent ) ;
return __do_cpuid_ent ( entry , func , idx , nent , maxnent ) ;
}
2011-11-23 16:30:32 +02:00
# undef F
2011-11-28 11:20:29 +02:00
struct kvm_cpuid_param {
u32 func ;
u32 idx ;
bool has_leaf_count ;
2012-08-30 01:30:13 +02:00
bool ( * qualifier ) ( const struct kvm_cpuid_param * param ) ;
2011-11-28 11:20:29 +02:00
} ;
2012-08-30 01:30:13 +02:00
static bool is_centaur_cpu ( const struct kvm_cpuid_param * param )
2011-11-28 11:20:29 +02:00
{
return boot_cpu_data . x86_vendor = = X86_VENDOR_CENTAUR ;
}
2013-09-22 16:44:50 +02:00
static bool sanity_check_entries ( struct kvm_cpuid_entry2 __user * entries ,
__u32 num_entries , unsigned int ioctl_type )
{
int i ;
2013-11-06 15:46:02 +01:00
__u32 pad [ 3 ] ;
2013-09-22 16:44:50 +02:00
if ( ioctl_type ! = KVM_GET_EMULATED_CPUID )
return false ;
/*
* We want to make sure that - > padding is being passed clean from
* userspace in case we want to use it for something in the future .
*
* Sadly , this wasn ' t enforced for KVM_GET_SUPPORTED_CPUID and so we
* have to give ourselves satisfied only with the emulated side . / me
* sheds a tear .
*/
for ( i = 0 ; i < num_entries ; i + + ) {
2013-11-06 15:46:02 +01:00
if ( copy_from_user ( pad , entries [ i ] . padding , sizeof ( pad ) ) )
return true ;
if ( pad [ 0 ] | | pad [ 1 ] | | pad [ 2 ] )
2013-09-22 16:44:50 +02:00
return true ;
}
return false ;
}
int kvm_dev_ioctl_get_cpuid ( struct kvm_cpuid2 * cpuid ,
struct kvm_cpuid_entry2 __user * entries ,
unsigned int type )
2011-11-23 16:30:32 +02:00
{
struct kvm_cpuid_entry2 * cpuid_entries ;
2011-11-28 11:20:29 +02:00
int limit , nent = 0 , r = - E2BIG , i ;
2011-11-23 16:30:32 +02:00
u32 func ;
2012-08-30 01:30:13 +02:00
static const struct kvm_cpuid_param param [ ] = {
2011-11-28 11:20:29 +02:00
{ . func = 0 , . has_leaf_count = true } ,
{ . func = 0x80000000 , . has_leaf_count = true } ,
{ . func = 0xC0000000 , . qualifier = is_centaur_cpu , . has_leaf_count = true } ,
{ . func = KVM_CPUID_SIGNATURE } ,
{ . func = KVM_CPUID_FEATURES } ,
} ;
2011-11-23 16:30:32 +02:00
if ( cpuid - > nent < 1 )
goto out ;
if ( cpuid - > nent > KVM_MAX_CPUID_ENTRIES )
cpuid - > nent = KVM_MAX_CPUID_ENTRIES ;
2013-09-22 16:44:50 +02:00
if ( sanity_check_entries ( entries , cpuid - > nent , type ) )
return - EINVAL ;
2011-11-23 16:30:32 +02:00
r = - ENOMEM ;
2013-10-29 12:54:56 +01:00
cpuid_entries = vzalloc ( sizeof ( struct kvm_cpuid_entry2 ) * cpuid - > nent ) ;
2011-11-23 16:30:32 +02:00
if ( ! cpuid_entries )
goto out ;
2011-11-28 11:20:29 +02:00
r = 0 ;
for ( i = 0 ; i < ARRAY_SIZE ( param ) ; i + + ) {
2012-08-30 01:30:13 +02:00
const struct kvm_cpuid_param * ent = & param [ i ] ;
2011-11-23 16:30:32 +02:00
2011-11-28 11:20:29 +02:00
if ( ent - > qualifier & & ! ent - > qualifier ( ent ) )
continue ;
2011-11-23 16:30:32 +02:00
2011-11-28 11:20:29 +02:00
r = do_cpuid_ent ( & cpuid_entries [ nent ] , ent - > func , ent - > idx ,
2013-09-22 16:44:50 +02:00
& nent , cpuid - > nent , type ) ;
2011-11-23 16:30:32 +02:00
2011-11-28 11:20:29 +02:00
if ( r )
2011-11-23 16:30:32 +02:00
goto out_free ;
2011-11-28 11:20:29 +02:00
if ( ! ent - > has_leaf_count )
continue ;
2011-11-23 16:30:32 +02:00
limit = cpuid_entries [ nent - 1 ] . eax ;
2011-11-28 11:20:29 +02:00
for ( func = ent - > func + 1 ; func < = limit & & nent < cpuid - > nent & & r = = 0 ; + + func )
r = do_cpuid_ent ( & cpuid_entries [ nent ] , func , ent - > idx ,
2013-09-22 16:44:50 +02:00
& nent , cpuid - > nent , type ) ;
2011-11-23 16:30:32 +02:00
2011-11-28 11:20:29 +02:00
if ( r )
2011-11-23 16:30:32 +02:00
goto out_free ;
}
r = - EFAULT ;
if ( copy_to_user ( entries , cpuid_entries ,
nent * sizeof ( struct kvm_cpuid_entry2 ) ) )
goto out_free ;
cpuid - > nent = nent ;
r = 0 ;
out_free :
vfree ( cpuid_entries ) ;
out :
return r ;
}
static int move_to_next_stateful_cpuid_entry ( struct kvm_vcpu * vcpu , int i )
{
struct kvm_cpuid_entry2 * e = & vcpu - > arch . cpuid_entries [ i ] ;
2017-06-08 01:22:07 -07:00
struct kvm_cpuid_entry2 * ej ;
int j = i ;
int nent = vcpu - > arch . cpuid_nent ;
2011-11-23 16:30:32 +02:00
e - > flags & = ~ KVM_CPUID_FLAG_STATE_READ_NEXT ;
/* when no next entry is found, the current entry[i] is reselected */
2017-06-08 01:22:07 -07:00
do {
j = ( j + 1 ) % nent ;
ej = & vcpu - > arch . cpuid_entries [ j ] ;
} while ( ej - > function ! = e - > function ) ;
ej - > flags | = KVM_CPUID_FLAG_STATE_READ_NEXT ;
return j ;
2011-11-23 16:30:32 +02:00
}
/* find an entry with matching function, matching index (if needed), and that
* should be read next ( if it ' s stateful ) */
static int is_matching_cpuid_entry ( struct kvm_cpuid_entry2 * e ,
u32 function , u32 index )
{
if ( e - > function ! = function )
return 0 ;
if ( ( e - > flags & KVM_CPUID_FLAG_SIGNIFCANT_INDEX ) & & e - > index ! = index )
return 0 ;
if ( ( e - > flags & KVM_CPUID_FLAG_STATEFUL_FUNC ) & &
! ( e - > flags & KVM_CPUID_FLAG_STATE_READ_NEXT ) )
return 0 ;
return 1 ;
}
struct kvm_cpuid_entry2 * kvm_find_cpuid_entry ( struct kvm_vcpu * vcpu ,
u32 function , u32 index )
{
int i ;
struct kvm_cpuid_entry2 * best = NULL ;
for ( i = 0 ; i < vcpu - > arch . cpuid_nent ; + + i ) {
struct kvm_cpuid_entry2 * e ;
e = & vcpu - > arch . cpuid_entries [ i ] ;
if ( is_matching_cpuid_entry ( e , function , index ) ) {
if ( e - > flags & KVM_CPUID_FLAG_STATEFUL_FUNC )
move_to_next_stateful_cpuid_entry ( vcpu , i ) ;
best = e ;
break ;
}
}
return best ;
}
EXPORT_SYMBOL_GPL ( kvm_find_cpuid_entry ) ;
/*
* If no match is found , check whether we exceed the vCPU ' s limit
* and return the content of the highest valid _standard_ leaf instead .
* This is to satisfy the CPUID specification .
*/
static struct kvm_cpuid_entry2 * check_cpuid_limit ( struct kvm_vcpu * vcpu ,
u32 function , u32 index )
{
struct kvm_cpuid_entry2 * maxlevel ;
maxlevel = kvm_find_cpuid_entry ( vcpu , function & 0x80000000 , 0 ) ;
if ( ! maxlevel | | maxlevel - > eax > = function )
return NULL ;
if ( function & 0x80000000 ) {
maxlevel = kvm_find_cpuid_entry ( vcpu , 0 , 0 ) ;
if ( ! maxlevel )
return NULL ;
}
return kvm_find_cpuid_entry ( vcpu , maxlevel - > eax , index ) ;
}
2017-08-24 20:27:52 +08:00
bool kvm_cpuid ( struct kvm_vcpu * vcpu , u32 * eax , u32 * ebx ,
u32 * ecx , u32 * edx , bool check_limit )
2011-11-23 16:30:32 +02:00
{
2012-06-07 14:07:48 +03:00
u32 function = * eax , index = * ecx ;
2011-11-23 16:30:32 +02:00
struct kvm_cpuid_entry2 * best ;
2017-08-24 20:27:52 +08:00
bool entry_found = true ;
2011-11-23 16:30:32 +02:00
best = kvm_find_cpuid_entry ( vcpu , function , index ) ;
2017-08-24 20:27:52 +08:00
if ( ! best ) {
entry_found = false ;
if ( ! check_limit )
goto out ;
2011-11-23 16:30:32 +02:00
best = check_cpuid_limit ( vcpu , function , index ) ;
2017-08-24 20:27:52 +08:00
}
2011-11-23 16:30:32 +02:00
2017-08-24 20:27:52 +08:00
out :
2011-11-23 16:30:32 +02:00
if ( best ) {
2012-06-07 14:07:48 +03:00
* eax = best - > eax ;
* ebx = best - > ebx ;
* ecx = best - > ecx ;
* edx = best - > edx ;
} else
* eax = * ebx = * ecx = * edx = 0 ;
2017-08-24 20:27:52 +08:00
trace_kvm_cpuid ( function , * eax , * ebx , * ecx , * edx , entry_found ) ;
return entry_found ;
2012-06-07 14:07:48 +03:00
}
2012-12-05 15:26:19 +01:00
EXPORT_SYMBOL_GPL ( kvm_cpuid ) ;
2012-06-07 14:07:48 +03:00
2016-11-29 12:40:37 -08:00
int kvm_emulate_cpuid ( struct kvm_vcpu * vcpu )
2012-06-07 14:07:48 +03:00
{
2016-11-07 08:55:49 +08:00
u32 eax , ebx , ecx , edx ;
2012-06-07 14:07:48 +03:00
2017-03-20 01:16:28 -07:00
if ( cpuid_fault_enabled ( vcpu ) & & ! kvm_require_cpl ( vcpu , 0 ) )
return 1 ;
2016-11-07 08:55:49 +08:00
eax = kvm_register_read ( vcpu , VCPU_REGS_RAX ) ;
2012-06-07 14:07:48 +03:00
ecx = kvm_register_read ( vcpu , VCPU_REGS_RCX ) ;
2017-08-24 20:27:52 +08:00
kvm_cpuid ( vcpu , & eax , & ebx , & ecx , & edx , true ) ;
2012-06-07 14:07:48 +03:00
kvm_register_write ( vcpu , VCPU_REGS_RAX , eax ) ;
kvm_register_write ( vcpu , VCPU_REGS_RBX , ebx ) ;
kvm_register_write ( vcpu , VCPU_REGS_RCX , ecx ) ;
kvm_register_write ( vcpu , VCPU_REGS_RDX , edx ) ;
KVM: x86: Add kvm_skip_emulated_instruction and use it.
kvm_skip_emulated_instruction calls both
kvm_x86_ops->skip_emulated_instruction and kvm_vcpu_check_singlestep,
skipping the emulated instruction and generating a trap if necessary.
Replacing skip_emulated_instruction calls with
kvm_skip_emulated_instruction is straightforward, except for:
- ICEBP, which is already inside a trap, so avoid triggering another trap.
- Instructions that can trigger exits to userspace, such as the IO insns,
MOVs to CR8, and HALT. If kvm_skip_emulated_instruction does trigger a
KVM_GUESTDBG_SINGLESTEP exit, and the handling code for
IN/OUT/MOV CR8/HALT also triggers an exit to userspace, the latter will
take precedence. The singlestep will be triggered again on the next
instruction, which is the current behavior.
- Task switch instructions which would require additional handling (e.g.
the task switch bit) and are instead left alone.
- Cases where VMLAUNCH/VMRESUME do not proceed to the next instruction,
which do not trigger singlestep traps as mentioned previously.
Signed-off-by: Kyle Huey <khuey@kylehuey.com>
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
2016-11-29 12:40:40 -08:00
return kvm_skip_emulated_instruction ( vcpu ) ;
2011-11-23 16:30:32 +02:00
}
EXPORT_SYMBOL_GPL ( kvm_emulate_cpuid ) ;