Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
c3e9434c
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
c3e9434c
编写于
8月 10, 2021
作者:
P
Paolo Bonzini
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'kvm-vmx-secctl' into HEAD
Merge common topic branch for 5.14-rc6 and 5.15 merge window.
上级
32bdc019
7b9cae02
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
115 addition
and
33 deletion
+115
-33
arch/x86/kvm/hyperv.c
arch/x86/kvm/hyperv.c
+14
-4
arch/x86/kvm/mmu/mmu.c
arch/x86/kvm/mmu/mmu.c
+1
-1
arch/x86/kvm/svm/sev.c
arch/x86/kvm/svm/sev.c
+25
-20
arch/x86/kvm/trace.h
arch/x86/kvm/trace.h
+15
-0
arch/x86/kvm/vmx/vmx.h
arch/x86/kvm/vmx/vmx.h
+1
-1
tools/testing/selftests/kvm/include/x86_64/hyperv.h
tools/testing/selftests/kvm/include/x86_64/hyperv.h
+4
-1
tools/testing/selftests/kvm/x86_64/hyperv_clock.c
tools/testing/selftests/kvm/x86_64/hyperv_clock.c
+1
-1
tools/testing/selftests/kvm/x86_64/hyperv_features.c
tools/testing/selftests/kvm/x86_64/hyperv_features.c
+38
-3
virt/kvm/kvm_main.c
virt/kvm/kvm_main.c
+16
-2
未找到文件。
arch/x86/kvm/hyperv.c
浏览文件 @
c3e9434c
...
...
@@ -2016,6 +2016,7 @@ static void kvm_hv_hypercall_set_result(struct kvm_vcpu *vcpu, u64 result)
static
int
kvm_hv_hypercall_complete
(
struct
kvm_vcpu
*
vcpu
,
u64
result
)
{
trace_kvm_hv_hypercall_done
(
result
);
kvm_hv_hypercall_set_result
(
vcpu
,
result
);
++
vcpu
->
stat
.
hypercalls
;
return
kvm_skip_emulated_instruction
(
vcpu
);
...
...
@@ -2139,6 +2140,7 @@ static bool hv_check_hypercall_access(struct kvm_vcpu_hv *hv_vcpu, u16 code)
int
kvm_hv_hypercall
(
struct
kvm_vcpu
*
vcpu
)
{
struct
kvm_vcpu_hv
*
hv_vcpu
=
to_hv_vcpu
(
vcpu
);
struct
kvm_hv_hcall
hc
;
u64
ret
=
HV_STATUS_SUCCESS
;
...
...
@@ -2173,17 +2175,25 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
hc
.
rep_idx
=
(
hc
.
param
>>
HV_HYPERCALL_REP_START_OFFSET
)
&
0xfff
;
hc
.
rep
=
!!
(
hc
.
rep_cnt
||
hc
.
rep_idx
);
if
(
hc
.
fast
&&
is_xmm_fast_hypercall
(
&
hc
))
kvm_hv_hypercall_read_xmm
(
&
hc
);
trace_kvm_hv_hypercall
(
hc
.
code
,
hc
.
fast
,
hc
.
rep_cnt
,
hc
.
rep_idx
,
hc
.
ingpa
,
hc
.
outgpa
);
if
(
unlikely
(
!
hv_check_hypercall_access
(
to_hv_vcpu
(
vcpu
)
,
hc
.
code
)))
{
if
(
unlikely
(
!
hv_check_hypercall_access
(
hv_vcpu
,
hc
.
code
)))
{
ret
=
HV_STATUS_ACCESS_DENIED
;
goto
hypercall_complete
;
}
if
(
hc
.
fast
&&
is_xmm_fast_hypercall
(
&
hc
))
{
if
(
unlikely
(
hv_vcpu
->
enforce_cpuid
&&
!
(
hv_vcpu
->
cpuid_cache
.
features_edx
&
HV_X64_HYPERCALL_XMM_INPUT_AVAILABLE
)))
{
kvm_queue_exception
(
vcpu
,
UD_VECTOR
);
return
1
;
}
kvm_hv_hypercall_read_xmm
(
&
hc
);
}
switch
(
hc
.
code
)
{
case
HVCALL_NOTIFY_LONG_SPIN_WAIT
:
if
(
unlikely
(
hc
.
rep
))
{
...
...
arch/x86/kvm/mmu/mmu.c
浏览文件 @
c3e9434c
...
...
@@ -1684,7 +1684,7 @@ static int is_empty_shadow_page(u64 *spt)
* aggregate version in order to make the slab shrinker
* faster
*/
static
inline
void
kvm_mod_used_mmu_pages
(
struct
kvm
*
kvm
,
unsigned
long
nr
)
static
inline
void
kvm_mod_used_mmu_pages
(
struct
kvm
*
kvm
,
long
nr
)
{
kvm
->
arch
.
n_used_mmu_pages
+=
nr
;
percpu_counter_add
(
&
kvm_total_used_mmu_pages
,
nr
);
...
...
arch/x86/kvm/svm/sev.c
浏览文件 @
c3e9434c
...
...
@@ -64,6 +64,7 @@ static DEFINE_MUTEX(sev_bitmap_lock);
unsigned
int
max_sev_asid
;
static
unsigned
int
min_sev_asid
;
static
unsigned
long
sev_me_mask
;
static
unsigned
int
nr_asids
;
static
unsigned
long
*
sev_asid_bitmap
;
static
unsigned
long
*
sev_reclaim_asid_bitmap
;
...
...
@@ -78,11 +79,11 @@ struct enc_region {
/* Called with the sev_bitmap_lock held, or on shutdown */
static
int
sev_flush_asids
(
int
min_asid
,
int
max_asid
)
{
int
ret
,
pos
,
error
=
0
;
int
ret
,
asid
,
error
=
0
;
/* Check if there are any ASIDs to reclaim before performing a flush */
pos
=
find_next_bit
(
sev_reclaim_asid_bitmap
,
max_asid
,
min_asid
);
if
(
pos
>=
max_asid
)
asid
=
find_next_bit
(
sev_reclaim_asid_bitmap
,
nr_asids
,
min_asid
);
if
(
asid
>
max_asid
)
return
-
EBUSY
;
/*
...
...
@@ -115,15 +116,15 @@ static bool __sev_recycle_asids(int min_asid, int max_asid)
/* The flush process will flush all reclaimable SEV and SEV-ES ASIDs */
bitmap_xor
(
sev_asid_bitmap
,
sev_asid_bitmap
,
sev_reclaim_asid_bitmap
,
max_sev_asid
);
bitmap_zero
(
sev_reclaim_asid_bitmap
,
max_sev_asid
);
nr_asids
);
bitmap_zero
(
sev_reclaim_asid_bitmap
,
nr_asids
);
return
true
;
}
static
int
sev_asid_new
(
struct
kvm_sev_info
*
sev
)
{
int
pos
,
min_asid
,
max_asid
,
ret
;
int
asid
,
min_asid
,
max_asid
,
ret
;
bool
retry
=
true
;
enum
misc_res_type
type
;
...
...
@@ -143,11 +144,11 @@ static int sev_asid_new(struct kvm_sev_info *sev)
* SEV-enabled guests must use asid from min_sev_asid to max_sev_asid.
* SEV-ES-enabled guest can use from 1 to min_sev_asid - 1.
*/
min_asid
=
sev
->
es_active
?
0
:
min_sev_asid
-
1
;
min_asid
=
sev
->
es_active
?
1
:
min_sev_asid
;
max_asid
=
sev
->
es_active
?
min_sev_asid
-
1
:
max_sev_asid
;
again:
pos
=
find_next_zero_bit
(
sev_asid_bitmap
,
max_sev_asid
,
min_asid
);
if
(
pos
>=
max_asid
)
{
asid
=
find_next_zero_bit
(
sev_asid_bitmap
,
max_asid
+
1
,
min_asid
);
if
(
asid
>
max_asid
)
{
if
(
retry
&&
__sev_recycle_asids
(
min_asid
,
max_asid
))
{
retry
=
false
;
goto
again
;
...
...
@@ -157,11 +158,11 @@ static int sev_asid_new(struct kvm_sev_info *sev)
goto
e_uncharge
;
}
__set_bit
(
pos
,
sev_asid_bitmap
);
__set_bit
(
asid
,
sev_asid_bitmap
);
mutex_unlock
(
&
sev_bitmap_lock
);
return
pos
+
1
;
return
asid
;
e_uncharge:
misc_cg_uncharge
(
type
,
sev
->
misc_cg
,
1
);
put_misc_cg
(
sev
->
misc_cg
);
...
...
@@ -179,17 +180,16 @@ static int sev_get_asid(struct kvm *kvm)
static
void
sev_asid_free
(
struct
kvm_sev_info
*
sev
)
{
struct
svm_cpu_data
*
sd
;
int
cpu
,
pos
;
int
cpu
;
enum
misc_res_type
type
;
mutex_lock
(
&
sev_bitmap_lock
);
pos
=
sev
->
asid
-
1
;
__set_bit
(
pos
,
sev_reclaim_asid_bitmap
);
__set_bit
(
sev
->
asid
,
sev_reclaim_asid_bitmap
);
for_each_possible_cpu
(
cpu
)
{
sd
=
per_cpu
(
svm_data
,
cpu
);
sd
->
sev_vmcbs
[
pos
]
=
NULL
;
sd
->
sev_vmcbs
[
sev
->
asid
]
=
NULL
;
}
mutex_unlock
(
&
sev_bitmap_lock
);
...
...
@@ -1858,12 +1858,17 @@ void __init sev_hardware_setup(void)
min_sev_asid
=
edx
;
sev_me_mask
=
1UL
<<
(
ebx
&
0x3f
);
/* Initialize SEV ASID bitmaps */
sev_asid_bitmap
=
bitmap_zalloc
(
max_sev_asid
,
GFP_KERNEL
);
/*
* Initialize SEV ASID bitmaps. Allocate space for ASID 0 in the bitmap,
* even though it's never used, so that the bitmap is indexed by the
* actual ASID.
*/
nr_asids
=
max_sev_asid
+
1
;
sev_asid_bitmap
=
bitmap_zalloc
(
nr_asids
,
GFP_KERNEL
);
if
(
!
sev_asid_bitmap
)
goto
out
;
sev_reclaim_asid_bitmap
=
bitmap_zalloc
(
max_sev_asid
,
GFP_KERNEL
);
sev_reclaim_asid_bitmap
=
bitmap_zalloc
(
nr_asids
,
GFP_KERNEL
);
if
(
!
sev_reclaim_asid_bitmap
)
{
bitmap_free
(
sev_asid_bitmap
);
sev_asid_bitmap
=
NULL
;
...
...
@@ -1908,7 +1913,7 @@ void sev_hardware_teardown(void)
return
;
/* No need to take sev_bitmap_lock, all VMs have been destroyed. */
sev_flush_asids
(
0
,
max_sev_asid
);
sev_flush_asids
(
1
,
max_sev_asid
);
bitmap_free
(
sev_asid_bitmap
);
bitmap_free
(
sev_reclaim_asid_bitmap
);
...
...
@@ -1922,7 +1927,7 @@ int sev_cpu_init(struct svm_cpu_data *sd)
if
(
!
sev_enabled
)
return
0
;
sd
->
sev_vmcbs
=
kcalloc
(
max_sev_asid
+
1
,
sizeof
(
void
*
),
GFP_KERNEL
);
sd
->
sev_vmcbs
=
kcalloc
(
nr_asids
,
sizeof
(
void
*
),
GFP_KERNEL
);
if
(
!
sd
->
sev_vmcbs
)
return
-
ENOMEM
;
...
...
arch/x86/kvm/trace.h
浏览文件 @
c3e9434c
...
...
@@ -92,6 +92,21 @@ TRACE_EVENT(kvm_hv_hypercall,
__entry
->
outgpa
)
);
TRACE_EVENT
(
kvm_hv_hypercall_done
,
TP_PROTO
(
u64
result
),
TP_ARGS
(
result
),
TP_STRUCT__entry
(
__field
(
__u64
,
result
)
),
TP_fast_assign
(
__entry
->
result
=
result
;
),
TP_printk
(
"result 0x%llx"
,
__entry
->
result
)
);
/*
* Tracepoint for Xen hypercall.
*/
...
...
arch/x86/kvm/vmx/vmx.h
浏览文件 @
c3e9434c
...
...
@@ -521,7 +521,7 @@ static inline struct vmcs *alloc_vmcs(bool shadow)
static
inline
bool
vmx_has_waitpkg
(
struct
vcpu_vmx
*
vmx
)
{
return
vmx
->
secondary_exec_control
&
return
secondary_exec_controls_get
(
vmx
)
&
SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE
;
}
...
...
tools/testing/selftests/kvm/include/x86_64/hyperv.h
浏览文件 @
c3e9434c
...
...
@@ -117,7 +117,7 @@
#define HV_X64_GUEST_DEBUGGING_AVAILABLE BIT(1)
#define HV_X64_PERF_MONITOR_AVAILABLE BIT(2)
#define HV_X64_CPU_DYNAMIC_PARTITIONING_AVAILABLE BIT(3)
#define HV_X64_HYPERCALL_
PARAMS_XMM
_AVAILABLE BIT(4)
#define HV_X64_HYPERCALL_
XMM_INPUT
_AVAILABLE BIT(4)
#define HV_X64_GUEST_IDLE_STATE_AVAILABLE BIT(5)
#define HV_FEATURE_FREQUENCY_MSRS_AVAILABLE BIT(8)
#define HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE BIT(10)
...
...
@@ -182,4 +182,7 @@
#define HV_STATUS_INVALID_CONNECTION_ID 18
#define HV_STATUS_INSUFFICIENT_BUFFERS 19
/* hypercall options */
#define HV_HYPERCALL_FAST_BIT BIT(16)
#endif
/* !SELFTEST_KVM_HYPERV_H */
tools/testing/selftests/kvm/x86_64/hyperv_clock.c
浏览文件 @
c3e9434c
...
...
@@ -215,7 +215,7 @@ int main(void)
vcpu_set_hv_cpuid
(
vm
,
VCPU_ID
);
tsc_page_gva
=
vm_vaddr_alloc_page
(
vm
);
memset
(
addr_g
p
a2hva
(
vm
,
tsc_page_gva
),
0x0
,
getpagesize
());
memset
(
addr_g
v
a2hva
(
vm
,
tsc_page_gva
),
0x0
,
getpagesize
());
TEST_ASSERT
((
addr_gva2gpa
(
vm
,
tsc_page_gva
)
&
(
getpagesize
()
-
1
))
==
0
,
"TSC page has to be page aligned
\n
"
);
vcpu_args_set
(
vm
,
VCPU_ID
,
2
,
tsc_page_gva
,
addr_gva2gpa
(
vm
,
tsc_page_gva
));
...
...
tools/testing/selftests/kvm/x86_64/hyperv_features.c
浏览文件 @
c3e9434c
...
...
@@ -47,6 +47,7 @@ static void do_wrmsr(u32 idx, u64 val)
}
static
int
nr_gp
;
static
int
nr_ud
;
static
inline
u64
hypercall
(
u64
control
,
vm_vaddr_t
input_address
,
vm_vaddr_t
output_address
)
...
...
@@ -80,6 +81,12 @@ static void guest_gp_handler(struct ex_regs *regs)
regs
->
rip
=
(
uint64_t
)
&
wrmsr_end
;
}
static
void
guest_ud_handler
(
struct
ex_regs
*
regs
)
{
nr_ud
++
;
regs
->
rip
+=
3
;
}
struct
msr_data
{
uint32_t
idx
;
bool
available
;
...
...
@@ -90,6 +97,7 @@ struct msr_data {
struct
hcall_data
{
uint64_t
control
;
uint64_t
expect
;
bool
ud_expected
;
};
static
void
guest_msr
(
struct
msr_data
*
msr
)
...
...
@@ -117,13 +125,26 @@ static void guest_msr(struct msr_data *msr)
static
void
guest_hcall
(
vm_vaddr_t
pgs_gpa
,
struct
hcall_data
*
hcall
)
{
int
i
=
0
;
u64
res
,
input
,
output
;
wrmsr
(
HV_X64_MSR_GUEST_OS_ID
,
LINUX_OS_ID
);
wrmsr
(
HV_X64_MSR_HYPERCALL
,
pgs_gpa
);
while
(
hcall
->
control
)
{
GUEST_ASSERT
(
hypercall
(
hcall
->
control
,
pgs_gpa
,
pgs_gpa
+
4096
)
==
hcall
->
expect
);
nr_ud
=
0
;
if
(
!
(
hcall
->
control
&
HV_HYPERCALL_FAST_BIT
))
{
input
=
pgs_gpa
;
output
=
pgs_gpa
+
4096
;
}
else
{
input
=
output
=
0
;
}
res
=
hypercall
(
hcall
->
control
,
input
,
output
);
if
(
hcall
->
ud_expected
)
GUEST_ASSERT
(
nr_ud
==
1
);
else
GUEST_ASSERT
(
res
==
hcall
->
expect
);
GUEST_SYNC
(
i
++
);
}
...
...
@@ -552,8 +573,18 @@ static void guest_test_hcalls_access(struct kvm_vm *vm, struct hcall_data *hcall
recomm
.
ebx
=
0xfff
;
hcall
->
expect
=
HV_STATUS_SUCCESS
;
break
;
case
17
:
/* XMM fast hypercall */
hcall
->
control
=
HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE
|
HV_HYPERCALL_FAST_BIT
;
hcall
->
ud_expected
=
true
;
break
;
case
18
:
feat
.
edx
|=
HV_X64_HYPERCALL_XMM_INPUT_AVAILABLE
;
hcall
->
ud_expected
=
false
;
hcall
->
expect
=
HV_STATUS_SUCCESS
;
break
;
case
19
:
/* END */
hcall
->
control
=
0
;
break
;
...
...
@@ -625,6 +656,10 @@ int main(void)
/* Test hypercalls */
vm
=
vm_create_default
(
VCPU_ID
,
0
,
guest_hcall
);
vm_init_descriptor_tables
(
vm
);
vcpu_init_descriptor_tables
(
vm
,
VCPU_ID
);
vm_install_exception_handler
(
vm
,
UD_VECTOR
,
guest_ud_handler
);
/* Hypercall input/output */
hcall_page
=
vm_vaddr_alloc_pages
(
vm
,
2
);
memset
(
addr_gva2hva
(
vm
,
hcall_page
),
0x0
,
2
*
getpagesize
());
...
...
virt/kvm/kvm_main.c
浏览文件 @
c3e9434c
...
...
@@ -914,6 +914,8 @@ static void kvm_destroy_vm_debugfs(struct kvm *kvm)
static
int
kvm_create_vm_debugfs
(
struct
kvm
*
kvm
,
int
fd
)
{
static
DEFINE_MUTEX
(
kvm_debugfs_lock
);
struct
dentry
*
dent
;
char
dir_name
[
ITOA_MAX_LEN
*
2
];
struct
kvm_stat_data
*
stat_data
;
const
struct
_kvm_stats_desc
*
pdesc
;
...
...
@@ -925,8 +927,20 @@ static int kvm_create_vm_debugfs(struct kvm *kvm, int fd)
return
0
;
snprintf
(
dir_name
,
sizeof
(
dir_name
),
"%d-%d"
,
task_pid_nr
(
current
),
fd
);
kvm
->
debugfs_dentry
=
debugfs_create_dir
(
dir_name
,
kvm_debugfs_dir
);
mutex_lock
(
&
kvm_debugfs_lock
);
dent
=
debugfs_lookup
(
dir_name
,
kvm_debugfs_dir
);
if
(
dent
)
{
pr_warn_ratelimited
(
"KVM: debugfs: duplicate directory %s
\n
"
,
dir_name
);
dput
(
dent
);
mutex_unlock
(
&
kvm_debugfs_lock
);
return
0
;
}
dent
=
debugfs_create_dir
(
dir_name
,
kvm_debugfs_dir
);
mutex_unlock
(
&
kvm_debugfs_lock
);
if
(
IS_ERR
(
dent
))
return
0
;
kvm
->
debugfs_dentry
=
dent
;
kvm
->
debugfs_stat_data
=
kcalloc
(
kvm_debugfs_num_entries
,
sizeof
(
*
kvm
->
debugfs_stat_data
),
GFP_KERNEL_ACCOUNT
);
...
...
@@ -5280,7 +5294,7 @@ static void kvm_uevent_notify_change(unsigned int type, struct kvm *kvm)
}
add_uevent_var
(
env
,
"PID=%d"
,
kvm
->
userspace_pid
);
if
(
!
IS_ERR_OR_NULL
(
kvm
->
debugfs_dentry
)
)
{
if
(
kvm
->
debugfs_dentry
)
{
char
*
tmp
,
*
p
=
kmalloc
(
PATH_MAX
,
GFP_KERNEL_ACCOUNT
);
if
(
p
)
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录