diff --git a/Makefile b/Makefile index b278ae0..53abeea 100644 --- a/Makefile +++ b/Makefile @@ -32,7 +32,7 @@ patch/fedora/digitalocean: patch/pre/fedora/digitalocean patch/fedora/aws: patch/pre/fedora/aws cd work/fedora/aws/linux && \ git apply ../../../../patches/use-fixed-pvm-range.patch && \ - git apply ../../../../patches/add-xsave-debug-logs.patch + git apply ../../../../patches/fix-xsave-restore.patch patch/fedora/gcp: patch/pre/fedora/gcp patch/fedora/ovh: patch/pre/fedora/ovh patch/fedora/linode: patch/pre/fedora/linode @@ -43,7 +43,7 @@ patch/rocky/digitalocean: patch/pre/rocky/digitalocean patch/rocky/aws: patch/pre/rocky/aws cd work/rocky/aws/linux && \ git apply ../../../../patches/use-fixed-pvm-range.patch && \ - git apply ../../../../patches/add-xsave-debug-logs.patch + git apply ../../../../patches/fix-xsave-restore.patch patch/rocky/gcp: patch/pre/rocky/gcp patch/rocky/equinix: patch/pre/rocky/equinix patch/rocky/ovh: patch/pre/rocky/ovh @@ -57,7 +57,7 @@ patch/alma/digitalocean: patch/pre/alma/digitalocean patch/alma/aws: patch/pre/alma/aws cd work/alma/aws/linux && \ git apply ../../../../patches/use-fixed-pvm-range.patch && \ - git apply ../../../../patches/add-xsave-debug-logs.patch + git apply ../../../../patches/fix-xsave-restore.patch patch/alma/gcp: patch/pre/alma/gcp patch/alma/equinix: patch/pre/alma/equinix patch/alma/ovh: patch/pre/alma/ovh diff --git a/patches/add-xsave-debug-logs.patch b/patches/add-xsave-debug-logs.patch deleted file mode 100644 index 03a6297..0000000 --- a/patches/add-xsave-debug-logs.patch +++ /dev/null @@ -1,78 +0,0 @@ -From: bysui -Subject: https://github.com/virt-pvm/linux/issues/7#issuecomment-2069445537 ---- -diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c -index 29413cb2f..aa819f664 100644 ---- a/arch/x86/kvm/x86.c -+++ b/arch/x86/kvm/x86.c -@@ -5517,12 +5517,20 @@ static void kvm_vcpu_ioctl_x86_get_xsave2(struct kvm_vcpu *vcpu, - */ - u64 supported_xcr0 = vcpu->arch.guest_supported_xcr0 | - XFEATURE_MASK_FPSSE; -+ union fpregs_state *ustate = (void *)state; - - if (fpstate_is_confidential(&vcpu->arch.guest_fpu)) - return; - - fpu_copy_guest_fpstate_to_uabi(&vcpu->arch.guest_fpu, state, size, - supported_xcr0, vcpu->arch.pkru); -+ -+ pr_info("during getting:\n guest xcr0: %llx, host xcr0: %llx, supported_xcr0: %llx\n", -+ vcpu->arch.xcr0, host_xcr0, supported_xcr0); -+ pr_info("guest pkru: %x, host pkru: %x\n", -+ vcpu->arch.pkru, vcpu->arch.host_pkru); -+ pr_info("xfeatures: %llx, xcomp_bv: %llx\n", -+ ustate->xsave.header.xfeatures, ustate->xsave.header.xcomp_bv); - } - - static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu, -@@ -5535,9 +5543,18 @@ static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu, - static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu, - struct kvm_xsave *guest_xsave) - { -+ union fpregs_state *ustate = (void *)guest_xsave->region; -+ - if (fpstate_is_confidential(&vcpu->arch.guest_fpu)) - return 0; - -+ pr_info("during settting:\n guest xcr0: %llx, host xcr0: %llx, supported_xcr0: %llx\n", -+ vcpu->arch.xcr0, host_xcr0, kvm_caps.supported_xcr0); -+ pr_info("guest pkru: %x, host pkru: %x\n", -+ vcpu->arch.pkru, vcpu->arch.host_pkru); -+ pr_info("xfeatures: %llx, xcomp_bv: %llx\n", -+ ustate->xsave.header.xfeatures, ustate->xsave.header.xcomp_bv); -+ - return fpu_copy_uabi_to_guest_fpstate(&vcpu->arch.guest_fpu, - guest_xsave->region, - kvm_caps.supported_xcr0, -diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c -index 271dcb2de..b2e280172 100644 ---- a/arch/x86/mm/extable.c -+++ b/arch/x86/mm/extable.c -@@ -6,6 +6,7 @@ - #include - - #include -+#include - #include - #include - #include -@@ -121,8 +122,18 @@ static bool ex_handler_sgx(const struct exception_table_entry *fixup, - static bool ex_handler_fprestore(const struct exception_table_entry *fixup, - struct pt_regs *regs) - { -+ static bool once; - regs->ip = ex_fixup_addr(fixup); - -+ if (boot_cpu_has(X86_FEATURE_XSAVE) && !once) { -+ struct xregs_state *state = (void *)regs->di; -+ -+ once = true; -+ pr_info("xcr0 is %llx\n", xgetbv(XCR_XFEATURE_ENABLED_MASK)); -+ pr_info("xfeatures: %llx, xcomp_bv: %llx\n", -+ state->header.xfeatures, state->header.xcomp_bv); -+ } -+ - WARN_ONCE(1, "Bad FPU state detected at %pB, reinitializing FPU registers.", - (void *)instruction_pointer(regs)); - diff --git a/patches/fix-xsave-restore.patch b/patches/fix-xsave-restore.patch new file mode 100644 index 0000000..a736524 --- /dev/null +++ b/patches/fix-xsave-restore.patch @@ -0,0 +1,25 @@ +From: bysui +Subject: https://github.com/virt-pvm/linux/issues/7#issuecomment-2079017654 +--- +diff --git a/arch/x86/kvm/pvm/pvm.c b/arch/x86/kvm/pvm/pvm.c +index 37e8a19bc..97babe4a7 100644 +--- a/arch/x86/kvm/pvm/pvm.c ++++ b/arch/x86/kvm/pvm/pvm.c +@@ -1176,10 +1176,14 @@ static int pvm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) + * user memory region before the VM entry. + */ + pvm->msr_vcpu_struct = data; +- if (!data) ++ if (!data) { + kvm_gpc_deactivate(&pvm->pvcs_gpc); +- else if (kvm_gpc_activate(&pvm->pvcs_gpc, data, PAGE_SIZE)) +- return 1; ++ } ++ } else if (kvm_gpc_activate(&pvm->pvcs_gpc, data, PAGE_SIZE)) { ++ if (msr_info->host_initiated) ++ kvm_make_request(KVM_REQ_GPC_REFRESH, vcpu); ++ return 1; ++ } + break; + case MSR_PVM_SUPERVISOR_RSP: + pvm->msr_supervisor_rsp = msr_info->data; diff --git a/patches/use-fixed-pvm-range.patch b/patches/use-fixed-pvm-range.patch index 7ba93de..15fceac 100644 --- a/patches/use-fixed-pvm-range.patch +++ b/patches/use-fixed-pvm-range.patch @@ -1,32 +1,93 @@ From: bysui -Subject: https://github.com/virt-pvm/linux/issues/7#issuecomment-2069445537 +Subject: https://github.com/virt-pvm/linux/issues/7#issuecomment-2079017654 --- +diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c +index adcea8ecf..8b883523c 100644 +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -719,6 +719,27 @@ static void __init x86_report_nx(void) + } + } + ++#ifdef CONFIG_X86_64 ++static void __init x86_reserve_vmalloc_range(void) ++{ ++ static struct vm_struct pvm; ++ unsigned long size = 32UL << 39; ++ ++ if (pgtable_l5_enabled()) ++ size = 32UL << 48; ++ ++ pvm.addr = (void *)(VMALLOC_END + 1 - size); ++ pvm.size = size; ++ pvm.flags = VM_ALLOC | VM_NO_GUARD; ++ ++ vm_area_add_early(&pvm); ++} ++#else ++static void __init x86_reserve_vmalloc_range(void) ++{ ++} ++#endif ++ + /* + * Determine if we were loaded by an EFI loader. If so, then we have also been + * passed the efi memmap, systab, etc., so we should use these data structures +@@ -961,6 +982,7 @@ void __init setup_arch(char **cmdline_p) + * defined and before each memory section base is used. + */ + kernel_randomize_memory(); ++ x86_reserve_vmalloc_range(); + + #ifdef CONFIG_X86_32 + /* max_low_pfn get updated here */ diff --git a/arch/x86/kvm/pvm/host_mmu.c b/arch/x86/kvm/pvm/host_mmu.c -index 35e97f4f7..f4da658b1 100644 +index a60a7c78c..3ead2b301 100644 --- a/arch/x86/kvm/pvm/host_mmu.c +++ b/arch/x86/kvm/pvm/host_mmu.c -@@ -35,8 +35,9 @@ static int __init guest_address_space_init(void) - return -1; - } +@@ -51,9 +51,8 @@ static int __init guest_address_space_init(void) + pml4_index_start = L4_PT_INDEX(PVM_GUEST_MAPPING_START); + pml4_index_end = L4_PT_INDEX(RAW_CPU_ENTRY_AREA_BASE); + +- pvm_va_range = get_vm_area_align(DEFAULT_RANGE_L5_SIZE, PT_L5_SIZE, +- VM_ALLOC|VM_NO_GUARD); +- if (!pvm_va_range) { ++ pvm_va_range = find_vm_area((void *)(VMALLOC_END + 1 - DEFAULT_RANGE_L5_SIZE)); ++ if (!pvm_va_range || pvm_va_range->size != DEFAULT_RANGE_L5_SIZE) + pml5_index_start = 0x1ff; + pml5_index_end = 0x1ff; + } else { +@@ -62,9 +61,8 @@ static int __init guest_address_space_init(void) + (u64)pvm_va_range->size); + } + } else { +- pvm_va_range = get_vm_area_align(DEFAULT_RANGE_L4_SIZE, PT_L4_SIZE, +- VM_ALLOC|VM_NO_GUARD); +- if (!pvm_va_range) ++ pvm_va_range = find_vm_area((void *)(VMALLOC_END + 1 - DEFAULT_RANGE_L4_SIZE));_vm_area_align(DEFAULT_RANGE_L4_SIZE, PT_L4_SIZE, ++ if (!pvm_va_range || pvm_va_range->size != DEFAULT_RANGE_L4_SIZE)O_GUARD); + return -1; -- pvm_va_range_l4 = get_vm_area_align(DEFAULT_RANGE_L4_SIZE, PT_L4_SIZE, -- VM_ALLOC|VM_NO_GUARD); -+ pvm_va_range_l4 = __get_vm_area_caller(DEFAULT_RANGE_L4_SIZE, VM_ALLOC|VM_NO_GUARD, -+ VMALLOC_END - DEFAULT_RANGE_L4_SIZE, VMALLOC_END, -+ __builtin_return_address(0)); - if (!pvm_va_range_l4) - return -1; + pml4_index_start = L4_PT_INDEX((u64)pvm_va_range->addr); +@@ -133,8 +131,6 @@ int __init host_mmu_init(void) + void host_mmu_destroy(void) + { +- if (pvm_va_range) +- free_vm_area(pvm_va_range); + if (host_mmu_root_pgd) + free_page((unsigned long)(void *)host_mmu_root_pgd); + if (host_mmu_la57_top_p4d) diff --git a/mm/vmalloc.c b/mm/vmalloc.c -index 6e4b95f24..0b8b2d4ed 100644 +index 6e4b95f24..64ba3bbb4 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c -@@ -2623,6 +2623,8 @@ struct vm_struct *__get_vm_area_caller(unsigned long size, unsigned long flags, - NUMA_NO_NODE, GFP_KERNEL, caller); +@@ -2681,6 +2681,8 @@ struct vm_struct *find_vm_area(const void *addr) + return va->vm; } -+ EXPORT_SYMBOL_GPL(__get_vm_area_caller); ++EXPORT_SYMBOL_GPL(find_vm_area); + /** - * get_vm_area - reserve a contiguous kernel virtual area - * @size: size of the area + * remove_vm_area - find and remove a continuous kernel virtual area + * @addr: base address