If you need avx2 support, --cpu Haswell-noTSX,-x2apic works on Haswell desktop/laptop chips.
The most confusing problem is that qemu's definition of "Haswell" is actually Haswell-E, -EP and -EX; Haswell itself lacks x2apic, which qemu's Haswell requires. x2apic dates back to Nehalem, but qemu's CPU definitions only include it back to Sandy Bridge, so a standard desktop or laptop Haswell CPU falls all the back to Westmere and then adds flags including avx, avx2 and xsave on top of that[0].
Advertising support for AVX and AVX2 is just a matter of setting CPUID.1:ECX.AVX and CPUID.7:EBX.AVX2, but the instructions won't actually work unless XCR0.AVX is set, and kvm_load_guest_xcr0 only sets XCR0 from the guest if the guest's XR4.OSXSAVE is set. The guest's fpu__init_cpu_xstate only sets CR4.OSXSAVE when xfeatures_mask is non-zero, and xfeatures_mask is calculated by fpu__init_system_xstate from CPUID.(EAX=0DH,ECX=0), which doesn't exist on qemu's Westmere (level=0xb), so XCR0.AVX remains unset and AVX2 instructions #UD.
The bug is probably that raid6_have_avx2 only checks that AVX2 is supported in CPUID, not that it's enabled. Checking for X86_FEATURE_OSXSAVE might work, though I'm not sure if the value checked by boot_cpu_has is stored too early for that.
I am also a little suspicious of kvm_load_guest_xcr0's CR4.OSXSAVE guard. The Intel manuals state that XSAVE, XSRSTOR, XGETBV and XSETBV require the flag to be set, but KVM won't restore a guest's existing XCR0 unless OSXSAVE is still set.
If you need avx2 support, --cpu Haswell- noTSX,- x2apic works on Haswell desktop/laptop chips.
The most confusing problem is that qemu's definition of "Haswell" is actually Haswell-E, -EP and -EX; Haswell itself lacks x2apic, which qemu's Haswell requires. x2apic dates back to Nehalem, but qemu's CPU definitions only include it back to Sandy Bridge, so a standard desktop or laptop Haswell CPU falls all the back to Westmere and then adds flags including avx, avx2 and xsave on top of that[0].
Advertising support for AVX and AVX2 is just a matter of setting CPUID.1:ECX.AVX and CPUID.7:EBX.AVX2, but the instructions won't actually work unless XCR0.AVX is set, and kvm_load_guest_xcr0 only sets XCR0 from the guest if the guest's XR4.OSXSAVE is set. The guest's fpu__init_ cpu_xstate only sets CR4.OSXSAVE when xfeatures_mask is non-zero, and xfeatures_mask is calculated by fpu__init_ system_ xstate from CPUID.( EAX=0DH, ECX=0), which doesn't exist on qemu's Westmere (level=0xb), so XCR0.AVX remains unset and AVX2 instructions #UD.
The bug is probably that raid6_have_avx2 only checks that AVX2 is supported in CPUID, not that it's enabled. Checking for X86_FEATURE_OSXSAVE might work, though I'm not sure if the value checked by boot_cpu_has is stored too early for that.
I am also a little suspicious of kvm_load_ guest_xcr0' s CR4.OSXSAVE guard. The Intel manuals state that XSAVE, XSRSTOR, XGETBV and XSETBV require the flag to be set, but KVM won't restore a guest's existing XCR0 unless OSXSAVE is still set.
[0] "-cpu Westmere, +invpcid, +erms,+ bmi2,+smep, +avx2,+ bmi1,+fsgsbase, +abm,+rdtscp, +pdpe1gb, +rdrand, +f16c,+ avx,+osxsave, +xsave, +tsc-deadline, +movbe, +pcid,+ pdcm,+xtpr, +fma,+tm2, +est,+vmx, +ds_cpl, +monitor, +dtes64, +pclmuldq, +pbe,+tm, +ht,+ss, +acpi,+ ds,+vme"