Message ID | 20190619162140.133674-7-liran.alon@oracle.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | : target/i386: kvm: Add support for save and restore of nested state | expand |
On 6/19/2019 9:21 AM, Liran Alon wrote: > Improve the KVM_{GET,SET}_NESTED_STATE structs by detailing the format > of VMX nested state data in a struct. > > In order to avoid changing the ioctl values of > KVM_{GET,SET}_NESTED_STATE, there is a need to preserve > sizeof(struct kvm_nested_state). This is done by defining the data > struct as "data.vmx[0]". It was the most elegant way I found to > preserve struct size while still keeping struct readable and easy to > maintain. It does have a misfortunate side-effect that now it has to be > accessed as "data.vmx[0]" rather than just "data.vmx". > > Because we are already modifying these structs, I also modified the > following: > * Define the "format" field values as macros. > * Rename vmcs_pa to vmcs12_pa for better readability. > > Signed-off-by: Liran Alon <liran.alon@oracle.com> > --- > linux-headers/asm-x86/kvm.h | 33 ++++++++++++++++++++++----------- > 1 file changed, 22 insertions(+), 11 deletions(-) > > diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h > index 7a0e64ccd6ff..6e7dd792e448 100644 > --- a/linux-headers/asm-x86/kvm.h > +++ b/linux-headers/asm-x86/kvm.h > @@ -383,16 +383,26 @@ struct kvm_sync_regs { > #define KVM_X86_QUIRK_LAPIC_MMIO_HOLE (1 << 2) > #define KVM_X86_QUIRK_OUT_7E_INC_RIP (1 << 3) > > +#define KVM_STATE_NESTED_FORMAT_VMX 0 > +#define KVM_STATE_NESTED_FORMAT_SVM 1 > + > #define KVM_STATE_NESTED_GUEST_MODE 0x00000001 > #define KVM_STATE_NESTED_RUN_PENDING 0x00000002 > #define KVM_STATE_NESTED_EVMCS 0x00000004 > > +#define KVM_STATE_NESTED_VMX_VMCS_SIZE 0x1000 > + > #define KVM_STATE_NESTED_SMM_GUEST_MODE 0x00000001 > #define KVM_STATE_NESTED_SMM_VMXON 0x00000002 > > -struct kvm_vmx_nested_state { > +struct kvm_vmx_nested_state_data { > + __u8 vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE]; > + __u8 shadow_vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE]; > +}; > + > +struct kvm_vmx_nested_state_hdr { > __u64 vmxon_pa; > - __u64 vmcs_pa; > + __u64 vmcs12_pa; > > struct { > __u16 flags; > @@ -401,24 +411,25 @@ struct kvm_vmx_nested_state { > > /* for KVM_CAP_NESTED_STATE */ > struct kvm_nested_state { > - /* KVM_STATE_* flags */ > __u16 flags; > - > - /* 0 for VMX, 1 for SVM. */ > __u16 format; > - > - /* 128 for SVM, 128 + VMCS size for VMX. */ > __u32 size; > > union { > - /* VMXON, VMCS */ > - struct kvm_vmx_nested_state vmx; > + struct kvm_vmx_nested_state_hdr vmx; > > /* Pad the header to 128 bytes. */ > __u8 pad[120]; > - }; > + } hdr; > > - __u8 data[0]; > + /* > + * Define data region as 0 bytes to preserve backwards-compatability > + * to old definition of kvm_nested_state in order to avoid changing > + * KVM_{GET,PUT}_NESTED_STATE ioctl values. > + */ > + union { > + struct kvm_vmx_nested_state_data vmx[0]; > + } data; > }; > > #endif /* _ASM_X86_KVM_H */ Reviewed-by: Maran Wilson <maran.wilson@oracle.com> Thanks, -Maran
diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h index 7a0e64ccd6ff..6e7dd792e448 100644 --- a/linux-headers/asm-x86/kvm.h +++ b/linux-headers/asm-x86/kvm.h @@ -383,16 +383,26 @@ struct kvm_sync_regs { #define KVM_X86_QUIRK_LAPIC_MMIO_HOLE (1 << 2) #define KVM_X86_QUIRK_OUT_7E_INC_RIP (1 << 3) +#define KVM_STATE_NESTED_FORMAT_VMX 0 +#define KVM_STATE_NESTED_FORMAT_SVM 1 + #define KVM_STATE_NESTED_GUEST_MODE 0x00000001 #define KVM_STATE_NESTED_RUN_PENDING 0x00000002 #define KVM_STATE_NESTED_EVMCS 0x00000004 +#define KVM_STATE_NESTED_VMX_VMCS_SIZE 0x1000 + #define KVM_STATE_NESTED_SMM_GUEST_MODE 0x00000001 #define KVM_STATE_NESTED_SMM_VMXON 0x00000002 -struct kvm_vmx_nested_state { +struct kvm_vmx_nested_state_data { + __u8 vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE]; + __u8 shadow_vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE]; +}; + +struct kvm_vmx_nested_state_hdr { __u64 vmxon_pa; - __u64 vmcs_pa; + __u64 vmcs12_pa; struct { __u16 flags; @@ -401,24 +411,25 @@ struct kvm_vmx_nested_state { /* for KVM_CAP_NESTED_STATE */ struct kvm_nested_state { - /* KVM_STATE_* flags */ __u16 flags; - - /* 0 for VMX, 1 for SVM. */ __u16 format; - - /* 128 for SVM, 128 + VMCS size for VMX. */ __u32 size; union { - /* VMXON, VMCS */ - struct kvm_vmx_nested_state vmx; + struct kvm_vmx_nested_state_hdr vmx; /* Pad the header to 128 bytes. */ __u8 pad[120]; - }; + } hdr; - __u8 data[0]; + /* + * Define data region as 0 bytes to preserve backwards-compatability + * to old definition of kvm_nested_state in order to avoid changing + * KVM_{GET,PUT}_NESTED_STATE ioctl values. + */ + union { + struct kvm_vmx_nested_state_data vmx[0]; + } data; }; #endif /* _ASM_X86_KVM_H */
Improve the KVM_{GET,SET}_NESTED_STATE structs by detailing the format of VMX nested state data in a struct. In order to avoid changing the ioctl values of KVM_{GET,SET}_NESTED_STATE, there is a need to preserve sizeof(struct kvm_nested_state). This is done by defining the data struct as "data.vmx[0]". It was the most elegant way I found to preserve struct size while still keeping struct readable and easy to maintain. It does have a misfortunate side-effect that now it has to be accessed as "data.vmx[0]" rather than just "data.vmx". Because we are already modifying these structs, I also modified the following: * Define the "format" field values as macros. * Rename vmcs_pa to vmcs12_pa for better readability. Signed-off-by: Liran Alon <liran.alon@oracle.com> --- linux-headers/asm-x86/kvm.h | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-)