@@ -165,6 +165,9 @@ struct mshv_vtl_per_cpu {
165
165
bool urn_registered ;
166
166
struct user_return_notifier mshv_urn ;
167
167
#endif
168
+ #if defined(CONFIG_X86_64 ) && defined(CONFIG_SEV_GUEST )
169
+ struct page * secure_avic_page ;
170
+ #endif
168
171
};
169
172
170
173
static struct mutex mshv_vtl_poll_file_lock ;
@@ -194,13 +197,20 @@ static struct page *mshv_vtl_cpu_reg_page(int cpu)
194
197
return * per_cpu_ptr (& mshv_vtl_per_cpu .reg_page , cpu );
195
198
}
196
199
197
- #if defined(CONFIG_X86_64 ) && defined( CONFIG_INTEL_TDX_GUEST )
200
+ #if defined(CONFIG_X86_64 )
198
201
199
202
static struct page * tdx_apic_page (int cpu )
200
203
{
204
+ #if defined(CONFIG_INTEL_TDX_GUEST )
201
205
return * per_cpu_ptr (& mshv_vtl_per_cpu .tdx_apic_page , cpu );
206
+ #else
207
+ (void )cpu ;
208
+ return NULL ;
209
+ #endif
202
210
}
203
211
212
+ #if defined(CONFIG_INTEL_TDX_GUEST )
213
+
204
214
static struct page * tdx_this_apic_page (void )
205
215
{
206
216
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
237
247
238
248
return - EINVAL ;
239
249
}
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 ;
240
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
+
272
+ #endif /* defined(CONFIG_X86_64) */
241
273
242
274
static long __mshv_vtl_ioctl_check_extension (u32 arg )
243
275
{
@@ -623,12 +655,35 @@ static int mshv_vtl_alloc_context(unsigned int cpu)
623
655
mshv_write_tdx_apic_page (page_to_phys (tdx_apic_page ));
624
656
#endif
625
657
} else if (hv_isolation_type_snp ()) {
626
- #ifdef CONFIG_X86_64
658
+ #if defined( CONFIG_X86_64 ) && defined( CONFIG_SEV_GUEST )
627
659
int ret ;
628
660
629
661
ret = mshv_configure_vmsa_page (0 , & per_cpu -> vmsa_page );
630
662
if (ret < 0 )
631
663
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
+ }
632
687
#endif
633
688
} else if (mshv_vsm_capabilities .intercept_page_available )
634
689
mshv_vtl_configure_reg_page (per_cpu );
@@ -1899,7 +1954,7 @@ mshv_vtl_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
1899
1954
1900
1955
static vm_fault_t mshv_vtl_fault (struct vm_fault * vmf )
1901
1956
{
1902
- struct page * page ;
1957
+ struct page * page = NULL ;
1903
1958
int cpu = vmf -> pgoff & MSHV_PG_OFF_CPU_MASK ;
1904
1959
int real_off = vmf -> pgoff >> MSHV_REAL_OFF_SHIFT ;
1905
1960
@@ -1931,18 +1986,16 @@ static vm_fault_t mshv_vtl_fault(struct vm_fault *vmf)
1931
1986
if (!hv_isolation_type_snp ())
1932
1987
return VM_FAULT_SIGBUS ;
1933
1988
page = * per_cpu_ptr (& mshv_vtl_per_cpu .vmsa_page , cpu );
1934
- #ifdef CONFIG_INTEL_TDX_GUEST
1935
1989
} 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 );
1941
1991
#endif
1942
1992
} else {
1943
1993
return VM_FAULT_NOPAGE ;
1944
1994
}
1945
1995
1996
+ if (!page )
1997
+ return VM_FAULT_SIGBUS ;
1998
+
1946
1999
get_page (page );
1947
2000
vmf -> page = page ;
1948
2001
0 commit comments