[Top][All Lists]

[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)


I have a quite particular issue which I try to solve via QEMU/KVM.


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- 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 

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 

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 

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. 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]