[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-discuss] Override ECX for guest
From: |
Mikael |
Subject: |
[Qemu-discuss] Override ECX for guest |
Date: |
Thu, 26 Jan 2017 10:49:42 +0100 (CET) |
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
- [Qemu-discuss] Override ECX for guest,
Mikael <=