Hi. I have a quite particular issue which I try to solve via QEMU/KVM.
Background: I have a Linux based appliance running a commercial firewall product. The vendor bases the Linux version on RHEL5 2.6.18-92. The vendor then backports features as needed for their product and userspace and maintains security fixes. The firewall itself utilizes modules which are non-open source. As such building your own kernel, even with the same version is not possible as the firewall product would cease operating. The backported kernel API identifies as kvm-kmod-2.6.30.1 when loading. As far as userspace the appliance ships with QEMU: # ./qemu-system-x86_64 -version QEMU emulator version 1.2.0, Copyright (c) 2003-2008 Fabrice Bellard The appliance bases on an Intel ATOM C2558 (https://ark.intel.com/products/77983/Intel-Atom-Processor-C2558-2M-Cache-2_40-GHz). The vendor has written implementations for utilizing the AES-NI engine. However, the kernel itself seems too old to even detect this CPU capability; # grep -e vendor_id -e model -e flags /proc/cpuinfo vendor_id : GenuineIntel model : 77 model name : Intel(R) Atom(TM) CPU C2558 @ 2.40GHz flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm syscall nx rdtscp lm constant_tsc pni monitor ds_cpl vmx est tm2 cx16 xtpr popcnt lahf_lm misalignsse As you can see the flags from the CPUID are not populated correctly. More particularly the aes (and others) flag is absent. Just as a proof that the vendor did not disable the capability the output from CPUID is as following: feature information (1/ecx): PNI/SSE3: Prescott New Instructions = true PCLMULDQ instruction = true 64-bit debug store = true MONITOR/MWAIT = true CPL-qualified debug store = true VMX: virtual machine extensions = true SMX: safer mode extensions = false Enhanced Intel SpeedStep Technology = true thermal monitor 2 = true SSSE3 extensions = true context ID: adaptive or shared L1 data = false FMA instruction = false CMPXCHG16B instruction = true xTPR disable = true perfmon and debug = true process context identifiers = false direct cache access = false SSE4.1 extensions = true SSE4.2 extensions = true extended xAPIC support = false MOVBE instruction = true POPCNT instruction = true time stamp counter deadline = true AES instruction = true XSAVE/XSTOR states = false OS-enabled XSAVE/XSTOR = false AVX: advanced vector extensions = false F16C half-precision convert instruction = false RDRAND instruction = true hypervisor guest status = false As you can see the flags for AES is clearly exposed / enabled. I also know that the vendor's provided proprietary VPN module utilizes AES-NI. Therefore I know it's usable in the current kernel configuration, although custom code to manually identify the presence and utilize these instruction sets. The vendor does not provide any kernel API module for accelerating AES via hardware. /proc/crypto is just having a generic x86_64 optimization for AES encryption / decryption; # grep aes /proc/crypto name : aes driver : aes-generic module : aes_generic name : aes driver : aes-x86_64 module : aes_x86_64 Issue which I try to solve: I am trying to set up an openvpn custom service on the box. But as the module for AES acceleration via the Linux crypto API is not present/available and I cannot compile it due to the kernel module source issue acceleration via AES-NI is unavailable. Unfortunately the CPU is quite slow encrypting/decrypting traffic without it. It pushes ~80Mbit/s where I'd be looking at ~300-400Mbit/s. I thought I would then do a workaround setting up a small virtual machine using the KVM infrastructure as it was provided and run the OpenVPN inside the guest machine with appropriate kernel crypto API support. However, as the kernel version 2.6.18 which it bases on does not properly identify the CPU capabilities (as seen in /proc/cpuinfo) I have not been able to get qemu to expose the AES flag to the guest despite that it's present. The guest boots perfectly, but it seems limited to the flags which the host has identified and written into the /proc/cpuinfo. The only exception is if I do -cpu host, this will cause the kernel to panic on boot on the guest. Tried multiple distributions all with the same result. But doing for instance -cpu core2duo,+aes should still work (however does not include the aes flag to the guest). As the hardware seems AES-NI capable it would in my opinion work if I could force the ECX register to a certain value on the guest machine. As machine instructions would be present even though the host is unaware of it no issue/crash would arise. I have looked at boot parameters for the kernel, and there is a reverse feature (clearcpuid=BITNUM). However no force add capability, just remove. My limitations in this scenario would be; - Kernel is static. I can work with what I have from the vendor. Otherwise I will be breaking the main firewall product running on it via the proprietary modules. If it's possible but requires an updated kernel KVM API this could unfortunately not be accommodated. - Userland does not have a compiler. It comes with QEMU 1.2.0. The userspace bases on RHEL5 i686 (however kernel is x86_64 and they ship a qemu x86_64 statically compiled binary). I can probably set up a build box based on RHEL5 and do a static build of a newer qemu binary if a potential workaround exists in a newer version. Any input on this would be great. Thanks. /Mikael