Skip to content

Commit 47325a6

Browse files
committed
hv: mshv_vtl: Support for Secure AVIC
1 parent 8cd472a commit 47325a6

File tree

4 files changed

+71
-12
lines changed

4 files changed

+71
-12
lines changed

arch/x86/include/asm/apic.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ static inline u64 native_x2apic_icr_read(void)
245245
extern void x2apic_savic_update_vector(unsigned int cpu,
246246
unsigned int vector,
247247
bool set);
248+
extern void x2apic_savic_init_backing_page(void *backing_page);
248249
#else
249250
static inline void x2apic_savic_update_vector(unsigned int cpu,
250251
unsigned int vector, bool set) { }

arch/x86/include/asm/sev.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,12 @@ struct rmp_state {
109109
u32 asid;
110110
} __packed;
111111

112-
#define RMPADJUST_VMSA_PAGE_BIT BIT(16)
112+
/* Target VMPL takes the first byte */
113+
#define RMPADJUST_ENABLE_READ BIT(8)
114+
#define RMPADJUST_ENABLE_WRITE BIT(9)
115+
#define RMPADJUST_USER_EXECUTE BIT(10)
116+
#define RMPADJUST_KERNEL_EXECUTE BIT(11)
117+
#define RMPADJUST_VMSA_PAGE_BIT BIT(16)
113118

114119
/* SNP Guest message request */
115120
struct snp_req_data {

arch/x86/kernel/apic/x2apic_savic.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ void x2apic_savic_update_vector(unsigned int cpu, unsigned int vector, bool set)
362362
test_and_clear_bit(VEC_POS(vector), reg);
363363
}
364364

365-
static void init_backing_page(void *backing_page)
365+
void x2apic_savic_init_backing_page(void *backing_page)
366366
{
367367
u32 hv_apic_id;
368368
u32 apic_id;
@@ -412,7 +412,7 @@ static void x2apic_savic_setup(void)
412412
return;
413413

414414
backing_page = this_cpu_read(apic_backing_page);
415-
init_backing_page(backing_page);
415+
x2apic_savic_init_backing_page(backing_page);
416416
gpa = __pa(backing_page);
417417
gfn = gpa >> PAGE_SHIFT;
418418

drivers/hv/mshv_vtl_main.c

Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,9 @@ struct mshv_vtl_per_cpu {
165165
bool urn_registered;
166166
struct user_return_notifier mshv_urn;
167167
#endif
168+
#if defined(CONFIG_X86_64) && defined(CONFIG_SEV_GUEST)
169+
struct page *secure_avic_page;
170+
#endif
168171
};
169172

170173
static struct mutex mshv_vtl_poll_file_lock;
@@ -194,13 +197,20 @@ static struct page *mshv_vtl_cpu_reg_page(int cpu)
194197
return *per_cpu_ptr(&mshv_vtl_per_cpu.reg_page, cpu);
195198
}
196199

197-
#if defined(CONFIG_X86_64) && defined(CONFIG_INTEL_TDX_GUEST)
200+
#if defined(CONFIG_X86_64)
198201

199202
static struct page *tdx_apic_page(int cpu)
200203
{
204+
#if defined(CONFIG_INTEL_TDX_GUEST)
201205
return *per_cpu_ptr(&mshv_vtl_per_cpu.tdx_apic_page, cpu);
206+
#else
207+
(void)cpu;
208+
return NULL;
209+
#endif
202210
}
203211

212+
#if defined(CONFIG_INTEL_TDX_GUEST)
213+
204214
static struct page *tdx_this_apic_page(void)
205215
{
206216
return *this_cpu_ptr(&mshv_vtl_per_cpu.tdx_apic_page);
@@ -237,7 +247,29 @@ static int mshv_tdx_set_cpumask_from_apicid(int apicid, struct cpumask *cpu_mask
237247

238248
return -EINVAL;
239249
}
250+
#endif /* defined(CONFIG_INTEL_TDX_GUEST) */
251+
252+
static struct page *snp_secure_avic_page(int cpu)
253+
{
254+
#if defined(CONFIG_SEV_GUEST)
255+
return *per_cpu_ptr(&mshv_vtl_per_cpu.secure_avic_page, cpu);
256+
#else
257+
(void)cpu;
258+
return NULL;
240259
#endif
260+
}
261+
262+
static struct page* mshv_apic_page(int cpu)
263+
{
264+
if (hv_isolation_type_tdx())
265+
return tdx_apic_page(cpu);
266+
else if (hv_isolation_type_snp())
267+
return snp_secure_avic_page(cpu);
268+
269+
return NULL;
270+
}
271+
272+
#endif /* defined(CONFIG_X86_64) */
241273

242274
static long __mshv_vtl_ioctl_check_extension(u32 arg)
243275
{
@@ -623,12 +655,35 @@ static int mshv_vtl_alloc_context(unsigned int cpu)
623655
mshv_write_tdx_apic_page(page_to_phys(tdx_apic_page));
624656
#endif
625657
} else if (hv_isolation_type_snp()) {
626-
#ifdef CONFIG_X86_64
658+
#if defined(CONFIG_X86_64) && defined(CONFIG_SEV_GUEST)
627659
int ret;
628660

629661
ret = mshv_configure_vmsa_page(0, &per_cpu->vmsa_page);
630662
if (ret < 0)
631663
return ret;
664+
665+
if (cc_platform_has(CC_ATTR_SNP_SECURE_AVIC)) {
666+
struct page *page = alloc_page(GFP_KERNEL | __GFP_ZERO);
667+
void *secure_avic_page;
668+
669+
if (!page)
670+
return -ENOMEM;
671+
secure_avic_page = page_address(page);
672+
673+
/* VMPL 2 for the VTL0 */
674+
ret = rmpadjust((unsigned long)secure_avic_page,
675+
RMP_PG_SIZE_4K, 2 | RMPADJUST_ENABLE_READ | RMPADJUST_ENABLE_WRITE);
676+
if (ret) {
677+
pr_err("failed to adjust RMP for the secure AVIC page: %d\n", ret);
678+
free_page((u64)page);
679+
return -EINVAL;
680+
}
681+
pr_debug("VTL0 secure AVIC page allocated, CPU %d\n", cpu);
682+
683+
/* is the environment quiet enough to capture a consistent state? */
684+
x2apic_savic_init_backing_page(secure_avic_page);
685+
per_cpu->secure_avic_page = secure_avic_page;
686+
}
632687
#endif
633688
} else if (mshv_vsm_capabilities.intercept_page_available)
634689
mshv_vtl_configure_reg_page(per_cpu);
@@ -1899,7 +1954,7 @@ mshv_vtl_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
18991954

19001955
static vm_fault_t mshv_vtl_fault(struct vm_fault *vmf)
19011956
{
1902-
struct page *page;
1957+
struct page *page = NULL;
19031958
int cpu = vmf->pgoff & MSHV_PG_OFF_CPU_MASK;
19041959
int real_off = vmf->pgoff >> MSHV_REAL_OFF_SHIFT;
19051960

@@ -1931,18 +1986,16 @@ static vm_fault_t mshv_vtl_fault(struct vm_fault *vmf)
19311986
if (!hv_isolation_type_snp())
19321987
return VM_FAULT_SIGBUS;
19331988
page = *per_cpu_ptr(&mshv_vtl_per_cpu.vmsa_page, cpu);
1934-
#ifdef CONFIG_INTEL_TDX_GUEST
19351989
} else if (real_off == MSHV_APIC_PAGE_OFFSET) {
1936-
if (!hv_isolation_type_tdx())
1937-
return VM_FAULT_SIGBUS;
1938-
1939-
page = tdx_apic_page(cpu);
1940-
#endif
1990+
page = mshv_apic_page(cpu);
19411991
#endif
19421992
} else {
19431993
return VM_FAULT_NOPAGE;
19441994
}
19451995

1996+
if (!page)
1997+
return VM_FAULT_SIGBUS;
1998+
19461999
get_page(page);
19472000
vmf->page = page;
19482001

0 commit comments

Comments
 (0)