Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/x86/coco/tdx/tdx-shared.c
26489 views
1
#include <asm/tdx.h>
2
#include <asm/pgtable.h>
3
4
static unsigned long try_accept_one(phys_addr_t start, unsigned long len,
5
enum pg_level pg_level)
6
{
7
unsigned long accept_size = page_level_size(pg_level);
8
struct tdx_module_args args = {};
9
u8 page_size;
10
11
if (!IS_ALIGNED(start, accept_size))
12
return 0;
13
14
if (len < accept_size)
15
return 0;
16
17
/*
18
* Pass the page physical address to the TDX module to accept the
19
* pending, private page.
20
*
21
* Bits 2:0 of RCX encode page size: 0 - 4K, 1 - 2M, 2 - 1G.
22
*/
23
switch (pg_level) {
24
case PG_LEVEL_4K:
25
page_size = TDX_PS_4K;
26
break;
27
case PG_LEVEL_2M:
28
page_size = TDX_PS_2M;
29
break;
30
case PG_LEVEL_1G:
31
page_size = TDX_PS_1G;
32
break;
33
default:
34
return 0;
35
}
36
37
args.rcx = start | page_size;
38
if (__tdcall(TDG_MEM_PAGE_ACCEPT, &args))
39
return 0;
40
41
return accept_size;
42
}
43
44
bool tdx_accept_memory(phys_addr_t start, phys_addr_t end)
45
{
46
/*
47
* For shared->private conversion, accept the page using
48
* TDG_MEM_PAGE_ACCEPT TDX module call.
49
*/
50
while (start < end) {
51
unsigned long len = end - start;
52
unsigned long accept_size;
53
54
/*
55
* Try larger accepts first. It gives chance to VMM to keep
56
* 1G/2M Secure EPT entries where possible and speeds up
57
* process by cutting number of hypercalls (if successful).
58
*/
59
60
accept_size = try_accept_one(start, len, PG_LEVEL_1G);
61
if (!accept_size)
62
accept_size = try_accept_one(start, len, PG_LEVEL_2M);
63
if (!accept_size)
64
accept_size = try_accept_one(start, len, PG_LEVEL_4K);
65
if (!accept_size)
66
return false;
67
start += accept_size;
68
}
69
70
return true;
71
}
72
73
noinstr u64 __tdx_hypercall(struct tdx_module_args *args)
74
{
75
/*
76
* For TDVMCALL explicitly set RCX to the bitmap of shared registers.
77
* The caller isn't expected to set @args->rcx anyway.
78
*/
79
args->rcx = TDVMCALL_EXPOSE_REGS_MASK;
80
81
/*
82
* Failure of __tdcall_saved_ret() indicates a failure of the TDVMCALL
83
* mechanism itself and that something has gone horribly wrong with
84
* the TDX module. __tdx_hypercall_failed() never returns.
85
*/
86
if (__tdcall_saved_ret(TDG_VP_VMCALL, args))
87
__tdx_hypercall_failed();
88
89
/* TDVMCALL leaf return code is in R10 */
90
return args->r10;
91
}
92
93