Skip to content

drivers: hv: Support for SNP Secure AVIC#130

Merged
hargar19 merged 6 commits into
microsoft:project/hcl-dev/6.18from
Brian-Perkins:snp_savic_dev
Apr 29, 2026
Merged

drivers: hv: Support for SNP Secure AVIC#130
hargar19 merged 6 commits into
microsoft:project/hcl-dev/6.18from
Brian-Perkins:snp_savic_dev

Conversation

@Brian-Perkins
Copy link
Copy Markdown
Contributor

No description provided.

tiala and others added 6 commits April 28, 2026 22:56
When Secure AVIC is enabled, VMBus driver should
call x2apic Secure AVIC interface to allow Hyper-V
to inject VMBus message interrupt.

Reviewed-by: Michael Kelley <mhklinux@outlook.com>
Reviewed-by: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
Signed-off-by: Tianyu Lan <tiala@microsoft.com>
When Secure AVIC is enabled, call Secure AVIC
function to allow Hyper-V to inject STIMER0 interrupt.

Reviewed-by: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
Reviewed-by: Michael Kelley <mhklinux@outlook.com>
Signed-off-by: Tianyu Lan <tiala@microsoft.com>
When Secure AVIC is available, the AMD x2apic Secure
AVIC driver will be selected. In that case, have hv_apic_init()
return immediately without doing anything.

Reviewed-by: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
Reviewed-by: Michael Kelley <mhklinux@outlook.com>
Signed-off-by: Tianyu Lan <tiala@microsoft.com>
Hyper-V doesn't support auto-eoi with Secure AVIC.
So set the HV_DEPRECATING_AEOI_RECOMMENDED flag
to force writing the EOI register after handling an interrupt.

Reviewed-by: Michael Kelley <mhklinux@outlook.com>
Reviewed-by: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
Signed-off-by: Tianyu Lan <tiala@microsoft.com>
Secure AVIC provides backing page to aid the
guest in limiting which interrupt vectors can
be injected into the guest. Hyper-V has specific
hvcall to set backing page and call it in
Secure AVIC driver.

Signed-off-by: Tianyu Lan <tiala@microsoft.com>
Signed-off-by: Roman Kisel <romank@linux.microsoft.com>
Signed-off-by: Tianyu Lan <tiala@microsoft.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Hyper-V guest/kernel plumbing to support AMD SEV-SNP Secure AVIC, primarily to accelerate interrupt delivery/handling for isolated VMs (SNP, plus some refactoring shared with TDX) and to expose required backing-page details to MSHV/VTL userspace.

Changes:

  • Introduces new Hyper-V register/message structures and a hypercall path to configure the Secure AVIC backing page.
  • Extends mshv_vtl to allocate/manage a Secure AVIC backing page and adds an ioctl to retrieve its PFN for VTL0.
  • Refactors/extends in-kernel interrupt/ICR handling to cover both TDX and SNP fast paths, and wires up vector enabling for CoCo interrupt injection.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
include/uapi/linux/mshv.h Adds new VTL ioctl for Secure AVIC PFN retrieval.
include/hyperv/hvhdk.h Adds x64 exception intercept message definitions used by SNP intercept handling.
include/hyperv/hvgdk_mini.h Adds new VP register IDs and hypercall input struct/union for setting Secure AVIC GPA.
include/asm-generic/mshyperv.h Declares hv_enable_coco_interrupt() hook used by SynIC enable/disable.
drivers/hv/mshv_vtl_main.c Allocates Secure AVIC page for SNP, adds fast-path exit/intercept handling, adds ioctl and generic APIC-page plumbing.
drivers/hv/hv_common.c Adds weak stub/export for hv_enable_coco_interrupt().
drivers/hv/hv.c Calls hv_enable_coco_interrupt() when enabling/disabling SynIC regs.
arch/x86/kernel/cpu/mshyperv.c Sets Hyper-V hint to recommend deprecating AEOI when Secure AVIC is present.
arch/x86/kernel/apic/x2apic_savic.c Initializes backing page and routes SNP+Hyper-V through new hv_set_savic_backing_page().
arch/x86/include/asm/svm.h Adds VMCB control bits used by SNP exit handling.
arch/x86/include/asm/sev.h Adds RMPADJUST permission bit defines used for Secure AVIC page permissions.
arch/x86/include/asm/mshyperv.h Adds hv_vp_early_input_arg and declares hv_set_savic_backing_page().
arch/x86/include/asm/apic.h Exposes x2apic_savic_init_backing_page() for reuse by mshv_vtl.
arch/x86/hyperv/ivm.c Implements hv_set_savic_backing_page() via HVCALL_SET_VP_REGISTERS.
arch/x86/hyperv/hv_init.c Allocates/decrypts per-CPU early input pages and updates APIC vectors for direct stimer injection.
arch/x86/hyperv/hv_apic.c Implements hv_enable_coco_interrupt() and skips hv-apic init when Secure AVIC is enabled.
Microsoft/hcl-x64.config Updates HCL kernel config snapshot to match new expectations/options.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread include/hyperv/hvhdk.h
Comment on lines +768 to +792
__u16 exception_vector;
union hv_x64_exception_info exception_info;
__u8 instruction_byte_count;
__u32 error_code;
__u64 exception_parameter;
__u64 reserved;
__u8 instruction_bytes[16];
struct hv_x64_segment_register ds_segment;
struct hv_x64_segment_register ss_segment;
__u64 rax;
__u64 rcx;
__u64 rdx;
__u64 rbx;
__u64 rsp;
__u64 rbp;
__u64 rsi;
__u64 rdi;
__u64 r8;
__u64 r9;
__u64 r10;
__u64 r11;
__u64 r12;
__u64 r13;
__u64 r14;
__u64 r15;
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new exception-intercept struct mixes __u* types with the surrounding code in this header, which consistently uses u8/u16/u32/u64. For consistency (and to avoid subtle header-style issues), switch these fields to u16/u8/u32/u64 like the existing intercept message structs.

Suggested change
__u16 exception_vector;
union hv_x64_exception_info exception_info;
__u8 instruction_byte_count;
__u32 error_code;
__u64 exception_parameter;
__u64 reserved;
__u8 instruction_bytes[16];
struct hv_x64_segment_register ds_segment;
struct hv_x64_segment_register ss_segment;
__u64 rax;
__u64 rcx;
__u64 rdx;
__u64 rbx;
__u64 rsp;
__u64 rbp;
__u64 rsi;
__u64 rdi;
__u64 r8;
__u64 r9;
__u64 r10;
__u64 r11;
__u64 r12;
__u64 r13;
__u64 r14;
__u64 r15;
u16 exception_vector;
union hv_x64_exception_info exception_info;
u8 instruction_byte_count;
u32 error_code;
u64 exception_parameter;
u64 reserved;
u8 instruction_bytes[16];
struct hv_x64_segment_register ds_segment;
struct hv_x64_segment_register ss_segment;
u64 rax;
u64 rcx;
u64 rdx;
u64 rbx;
u64 rsp;
u64 rbp;
u64 rsi;
u64 rdi;
u64 r8;
u64 r9;
u64 r10;
u64 r11;
u64 r12;
u64 r13;
u64 r14;
u64 r15;

Copilot uses AI. Check for mistakes.
Comment on lines +1075 to +1087
snp_secure_avic_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
if (!snp_secure_avic_page)
return -ENOMEM;

/* VMPL 2 for the VTL0 */
ret = rmpadjust((unsigned long)page_address(snp_secure_avic_page),
RMP_PG_SIZE_4K,
2 | RMPADJUST_ENABLE_READ | RMPADJUST_ENABLE_WRITE);
if (ret) {
pr_err("failed to adjust RMP for the secure AVIC page: %d\n", ret);
__free_page(snp_secure_avic_page);
return -EINVAL;
}
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the SNP allocation path, failures after per_cpu->run and/or per_cpu->vmsa_page have been allocated (e.g. alloc_page() failure or rmpadjust() failure for the secure AVIC page) return immediately without freeing the already-allocated pages. Add a cleanup path (e.g. goto err) that frees per_cpu->run, per_cpu->vmsa_page, and any partially-initialized snp_secure_avic_page before returning an error.

Copilot uses AI. Check for mistakes.
* the APIC backing page is mapped in NPT.
*/
res = savic_register_gpa(gpa);
if (hv_isolation_type_snp())
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

savic_setup() now calls hv_isolation_type_snp() / hv_set_savic_backing_page() without guarding for CONFIG_HYPERV. CONFIG_AMD_SECURE_AVIC only depends on AMD_MEM_ENCRYPT, so a build with Secure AVIC enabled but Hyper-V disabled will end up with unresolved Hyper-V symbols. Gate the Hyper-V path with IS_ENABLED(CONFIG_HYPERV) (or provide stubs) so non-Hyper-V kernels still build and use savic_register_gpa().

Suggested change
if (hv_isolation_type_snp())
if (IS_ENABLED(CONFIG_HYPERV) && hv_isolation_type_snp())

Copilot uses AI. Check for mistakes.
Comment thread arch/x86/hyperv/ivm.c
Comment on lines +296 to +306
u64 control = HV_HYPERCALL_REP_COMP_1 | HVCALL_SET_VP_REGISTERS;
struct hv_set_vp_registers_input *input =
(struct hv_set_vp_registers_input *)
((u8 *)hv_vp_early_input_arg + smp_processor_id() * PAGE_SIZE);
union hv_x64_register_sev_gpa_page value;
unsigned long flags;
int retry = 5;
u64 ret;

local_irq_save(flags);

Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hv_set_savic_backing_page() indexes hv_vp_early_input_arg using smp_processor_id() while only IRQs are disabled. This can trigger smp_processor_id() debug warnings / CPU migration issues on preemptible kernels. Use raw_smp_processor_id() or bracket with get_cpu()/put_cpu() (or preempt_disable()/preempt_enable()) to make the CPU ID stable for the duration of the access.

Copilot uses AI. Check for mistakes.
Comment on lines 1149 to +1151

#define HV_X64_REGISTER_VSM_VP_STATUS 0x000D0003
#define HV_X64_VTL_MASK GENMASK(3, 0)
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HV_X64_REGISTER_VSM_VP_STATUS and HV_X64_VTL_MASK are defined unconditionally here, but are also defined (with #ifndef guards) in arch/x86/include/asm/mshyperv.h. If both headers are included, this can produce macro redefinition warnings. Add #ifndef guards here as well (or remove one of the definitions) to keep the definitions single-sourced.

Suggested change
#define HV_X64_REGISTER_VSM_VP_STATUS 0x000D0003
#define HV_X64_VTL_MASK GENMASK(3, 0)
#ifndef HV_X64_REGISTER_VSM_VP_STATUS
#define HV_X64_REGISTER_VSM_VP_STATUS 0x000D0003
#endif
#ifndef HV_X64_VTL_MASK
#define HV_X64_VTL_MASK GENMASK(3, 0)
#endif

Copilot uses AI. Check for mistakes.
Comment on lines +1379 to +1384
u64 u64;
struct {
u64 enabled:1;
u64 reserved:11;
u64 pagenumber:52;
};
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

union hv_x64_register_sev_gpa_page uses a member named u64 u64; and an anonymous bitfield struct. This is hard to read and easy to misuse. Consider renaming the raw member to something like as_u64 and naming/packing the bitfield struct explicitly to make the layout and intent clearer.

Suggested change
u64 u64;
struct {
u64 enabled:1;
u64 reserved:11;
u64 pagenumber:52;
};
u64 as_u64;
struct {
u64 enabled:1;
u64 reserved:11;
u64 pagenumber:52;
} bits __packed;

Copilot uses AI. Check for mistakes.
@hargar19 hargar19 merged commit d2de677 into microsoft:project/hcl-dev/6.18 Apr 29, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants