Skip to content

Commit a981b57

Browse files
committed
drivers: mshv_vtl: Support Secure AVIC
1 parent 43b0a71 commit a981b57

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
@@ -162,6 +162,9 @@ struct mshv_vtl_per_cpu {
162162
u64 l1_msr_sfmask;
163163
u64 l1_msr_tsc_aux;
164164
#endif
165+
#if defined(CONFIG_X86_64) && defined(CONFIG_SEV_GUEST)
166+
struct page *secure_avic_page;
167+
#endif
165168
};
166169

167170
static struct mutex mshv_vtl_poll_file_lock;
@@ -191,18 +194,28 @@ static struct page *mshv_vtl_cpu_reg_page(int cpu)
191194
return *per_cpu_ptr(&mshv_vtl_per_cpu.reg_page, cpu);
192195
}
193196

194-
#if defined(CONFIG_X86_64) && defined(CONFIG_INTEL_TDX_GUEST)
195197

196198
static struct page *tdx_apic_page(int cpu)
197199
{
200+
#if defined(CONFIG_X86_64) && defined(CONFIG_INTEL_TDX_GUEST)
198201
return *per_cpu_ptr(&mshv_vtl_per_cpu.tdx_apic_page, cpu);
202+
#else
203+
(void)cpu;
204+
return NULL;
205+
#endif
199206
}
200207

201208
static struct page *tdx_this_apic_page(void)
202209
{
210+
#if defined(CONFIG_X86_64) && defined(CONFIG_INTEL_TDX_GUEST)
203211
return *this_cpu_ptr(&mshv_vtl_per_cpu.tdx_apic_page);
212+
#else
213+
return NULL;
214+
#endif
204215
}
205216

217+
#if defined(CONFIG_X86_64) && defined(CONFIG_INTEL_TDX_GUEST)
218+
206219
/*
207220
* For ICR emulation on TDX, we need a fast way to map APICIDs to CPUIDs.
208221
* Instead of iterating through all CPUs for each target in the ICR destination field
@@ -236,6 +249,26 @@ static int mshv_tdx_set_cpumask_from_apicid(int apicid, struct cpumask *cpu_mask
236249
}
237250
#endif
238251

252+
static struct page *snp_secure_avic_page(int cpu)
253+
{
254+
#if defined(CONFIG_X86_64) && 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;
259+
#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+
239272
static long __mshv_vtl_ioctl_check_extension(u32 arg)
240273
{
241274
switch (arg) {
@@ -619,12 +652,34 @@ static int mshv_vtl_alloc_context(unsigned int cpu)
619652
mshv_write_tdx_apic_page(page_to_phys(tdx_apic_page));
620653
#endif
621654
} else if (hv_isolation_type_snp()) {
622-
#ifdef CONFIG_X86_64
655+
#if defined(CONFIG_X86_64) && defined(CONFIG_SEV_GUEST)
623656
int ret;
624657

625658
ret = mshv_configure_vmsa_page(0, &per_cpu->vmsa_page);
626659
if (ret < 0)
627660
return ret;
661+
662+
if (cc_platform_has(CC_ATTR_SNP_SECURE_AVIC)) {
663+
struct page *page = alloc_page(GFP_KERNEL | __GFP_ZERO);
664+
void *secure_avic_page;
665+
666+
if (!page)
667+
return -ENOMEM;
668+
secure_avic_page = page_address(page);
669+
670+
/* VMPL 2 for the VTL0 */
671+
ret = rmpadjust((unsigned long)secure_avic_page,
672+
RMP_PG_SIZE_4K, 2 | RMPADJUST_ENABLE_READ | RMPADJUST_ENABLE_WRITE);
673+
if (ret) {
674+
pr_err("failed to adjust RMP for the secure AVIC page: %d\n", ret);
675+
free_page((u64)page);
676+
return -EINVAL;
677+
}
678+
pr_info("VTL0 secure AVIC page allocated, CPU %d\n", cpu);
679+
680+
x2apic_savic_init_backing_page(secure_avic_page);
681+
per_cpu->secure_avic_page = secure_avic_page;
682+
}
628683
#endif
629684
} else if (mshv_vsm_capabilities.intercept_page_available)
630685
mshv_vtl_configure_reg_page(per_cpu);
@@ -1933,7 +1988,7 @@ mshv_vtl_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
19331988

19341989
static vm_fault_t mshv_vtl_fault(struct vm_fault *vmf)
19351990
{
1936-
struct page *page;
1991+
struct page *page = NULL;
19371992
int cpu = vmf->pgoff & MSHV_PG_OFF_CPU_MASK;
19381993
int real_off = vmf->pgoff >> MSHV_REAL_OFF_SHIFT;
19391994

@@ -1965,18 +2020,16 @@ static vm_fault_t mshv_vtl_fault(struct vm_fault *vmf)
19652020
if (!hv_isolation_type_snp())
19662021
return VM_FAULT_SIGBUS;
19672022
page = *per_cpu_ptr(&mshv_vtl_per_cpu.vmsa_page, cpu);
1968-
#ifdef CONFIG_INTEL_TDX_GUEST
19692023
} else if (real_off == MSHV_APIC_PAGE_OFFSET) {
1970-
if (!hv_isolation_type_tdx())
1971-
return VM_FAULT_SIGBUS;
1972-
1973-
page = tdx_apic_page(cpu);
1974-
#endif
2024+
page = mshv_apic_page(cpu);
19752025
#endif
19762026
} else {
19772027
return VM_FAULT_NOPAGE;
19782028
}
19792029

2030+
if (!page)
2031+
return VM_FAULT_SIGBUS;
2032+
19802033
get_page(page);
19812034
vmf->page = page;
19822035

0 commit comments

Comments
 (0)