Library mcertikos.virt.intel.VVMCSIntroCode

***********************************************************************
*                                                                     *
*            The CertiKOS Certified Kit Operating System              *
*                                                                     *
*                   The FLINT Group, Yale University                  *
*                                                                     *
*  Copyright The FLINT Group, Yale University.  All rights reserved.  *
*  This file is distributed under the terms of the Yale University    *
*  Non-Commercial License Agreement.                                  *
*                                                                     *
*********************************************************************** 

Require Import Coqlib.
Require Import Maps.
Require Import AST.
Require Import Integers.
Require Import Floats.
Require Import Values.
Require Import MemoryX.
Require Import EventsX.
Require Import Globalenvs.
Require Import Locations.
Require Import Smallstep.
Require Import ClightBigstep.
Require Import Cop.
Require Import compcert.lib.Integers.
Require Import ZArith.Zwf.
Require Import RealParams.
Require Import LoopProof.
Require Import VCGen.
Require Import liblayers.compcertx.Stencil.
Require Import liblayers.compcertx.MakeProgram.
Require Import liblayers.compat.CompatLayers.
Require Import liblayers.compat.CompatGenSem.
Require Import CompatClightSem.
Require Import PrimSemantics.
Require Import Clight.
Require Import CDataTypes.
Require Import Ctypes.
Require Import CLemmas.
Require Import AbstractDataType.
Require Import VMCSInitGenSpec.
Require Import ObjVMCS.
Require Import VVMCSIntroCSource.

Hint Resolve Int.unsigned_range_2.
Hint Resolve CLemmas.Z_lor_range_lo.
Hint Resolve Z_lor_range.

Function unsigned64 (x : int64) : Z64 :=
  VZ64 (Int64.unsigned x).

Function unpack64 (x: Z64): Z :=
  match x with
  | VZ64 zz
  end.

Function repr64 (x : Z64) : int64 :=
  Int64.repr (unpack64 x).

Lemma unsigned64_repr: x: Z64,
    0 unpack64(x) Int64.max_unsigned
    unsigned64 (repr64 x) = x.
Proof.
  unfold repr64, unpack64, unsigned64.
  intros. destruct x. rewrite Int64.unsigned_repr; auto.
Qed.

Print Int64.repr_unsigned.

Lemma repr64_unsigned: x: int64,
    repr64 (unsigned64 x) = x.
Proof.
  unfold repr64, unpack64, unsigned64.
  apply Int64.repr_unsigned.
Qed.

Module VMCSINTROCODE.

  Section WithPrimitives.

    Context `{real_params: RealParams}.
    Context {memb} `{Hmemx: Mem.MemoryModelX memb}.
    Context `{Hmwd: UseMemWithData memb}.

    Let mem := mwd (cdata RData).

    Context `{Hstencil: Stencil}.
    Context `{make_program_ops: !MakeProgramOps Clight.function type Clight.fundef type}.
    Context `{Hmake_program: !MakeProgram Clight.function type Clight.fundef type}.

    Local Open Scope Z_scope.

    Section VMXSETTSCOFFSET.

      Let L: compatlayer (cdata RData) :=
        vmcs_writez64 gensem vmcs_writez64_spec.

      Local Instance: ExternalCallsOps mem := CompatExternalCalls.compatlayer_extcall_ops L.

      Local Instance: CompilerConfigOps mem := CompatExternalCalls.compatlayer_compiler_config_ops L.

      Local Open Scope Z_scope.

      Section VMXSetTscOffsetBody.

        Context `{Hwb: WritableBlockOps}.

        Variable (sc: stencil).

        Variables (ge: genv)
                  (STENCIL_MATCHES: stencil_matches sc ge).

vmcs_writez64
        Variable bvmcs_writez64: block.
        Hypothesis hvmcs_writez64_1 : Genv.find_symbol ge vmcs_writez64 = Some bvmcs_writez64.
        Hypothesis hvmcs_writez64_2 : Genv.find_funct_ptr ge bvmcs_writez64 =
                                     let arg_type := (Tcons tuint (Tcons tulong Tnil)) in
                                     let ret_type := tvoid in
                                     let cal_conv := cc_default in
                                     Some (External (EF_external
                                                       vmcs_writez64
                                                       (signature_of_type arg_type ret_type cal_conv))
                                                    arg_type ret_type cal_conv).

        Lemma vmx_set_tsc_offset_body_correct:
           m d env le tsc_offset,
            env = PTree.empty _
            PTree.get ttsc_offset le = Some (Vlong tsc_offset) →
            vmx_set_tsc_offset_spec (unsigned64 tsc_offset) d = Some
             le´,
              exec_stmt ge env le ((m, d): mem) vmx_set_tsc_offset_body E0 le´ (m, )
                        Out_normal.
        Proof.
          generalize max_unsigned64_val; intro muval.
          intros; subst.
          unfold vmx_set_tsc_offset_body.
          functional inversion H1; subst.
          esplit.
          repeat vcgenfull; try discriminate.
        Qed.

      End VMXSetTscOffsetBody.

      Theorem vmx_set_tsc_offset__code_correct:
        spec_le
          (vmx_set_tsc_offset vmx_set_tsc_offset_spec_low)
          (vmx_set_tsc_offset f_vmx_set_tsc_offset L).
      Proof.
        set ( := L) in ×. unfold L in ×.
        fbigstep_pre .
        fbigstep
          (vmx_set_tsc_offset_body_correct
             s (Genv.globalenv p) makeglobalenv b0 Hb0fs Hb0fp
             m´0 labd labd´ (PTree.empty _)
             (bind_parameter_temps´
                (fn_params f_vmx_set_tsc_offset)
                (Vlong tsc_offset :: nil)
                (create_undef_temps (fn_temps f_vmx_set_tsc_offset))
             )
          ) H0.
      Qed.

    End VMXSETTSCOFFSET.


    Section VMXGETTSCOFFSET.

      Let L: compatlayer (cdata RData) :=
        vmcs_readz64 gensem vmcs_readz64_spec.

      Local Instance: ExternalCallsOps mem := CompatExternalCalls.compatlayer_extcall_ops L.

      Local Instance: CompilerConfigOps mem := CompatExternalCalls.compatlayer_compiler_config_ops L.

      Local Open Scope Z_scope.

      Section VMXGetTscOffsetBody.

        Context `{Hwb: WritableBlockOps}.

        Variable (sc: stencil).

        Variables (ge: genv)
                  (STENCIL_MATCHES: stencil_matches sc ge).

vmcs_readz64
        Variable bvmcs_readz64: block.
        Hypothesis hvmcs_readz64_1 : Genv.find_symbol ge vmcs_readz64 = Some bvmcs_readz64.
        Hypothesis hvmcs_readz64_2 : Genv.find_funct_ptr ge bvmcs_readz64 =
                                     let arg_type := (Tcons tuint Tnil) in
                                     let ret_type := tulong in
                                     let cal_conv := cc_default in
                                     Some (External (EF_external
                                                       vmcs_readz64
                                                       (signature_of_type arg_type ret_type cal_conv))
                                                    arg_type ret_type cal_conv).

        Lemma vmx_get_tsc_offset_body_correct:
           m d env le v,
            env = PTree.empty _
            vmx_get_tsc_offset_spec d = Some (unsigned64 v) →
             le´,
              exec_stmt ge env le ((m, d): mem) vmx_get_tsc_offset_body E0 le´ (m, d)
                        (Out_return (Some (Vlong v, tulong))).
        Proof.
          generalize max_unsigned64_val; intro muval.
          intros; subst.
          unfold vmx_get_tsc_offset_body.
          functional inversion H0; subst.
          esplit.
          repeat vcgenfull; try discriminate.
          unfold vmcs_readz64_spec.
          rewrite H3, H2, H1, H4, H5, H6; simpl.
          rewrite H. reflexivity.
        Qed.

      End VMXGetTscOffsetBody.

      Theorem vmx_get_tsc_offset__code_correct:
        spec_le
          (vmx_get_tsc_offset vmx_get_tsc_offset_spec_low)
          (vmx_get_tsc_offset f_vmx_get_tsc_offset L).
      Proof.
        fbigstep_pre L.
        fbigstep
          (vmx_get_tsc_offset_body_correct
             s (Genv.globalenv p) makeglobalenv b0 Hb0fs Hb0fp
             m´0 labd (PTree.empty _)
             (bind_parameter_temps´
                (fn_params f_vmx_get_tsc_offset)
                (nil)
                (create_undef_temps (fn_temps f_vmx_get_tsc_offset))
             )
          ) H0.
      Qed.

    End VMXGETTSCOFFSET.

    Section VMXGETEXITFAULTADDR.

      Let L: compatlayer (cdata RData) :=
        vmcs_readz gensem vmcs_readz_spec.

      Local Instance: ExternalCallsOps mem := CompatExternalCalls.compatlayer_extcall_ops L.

      Local Instance: CompilerConfigOps mem := CompatExternalCalls.compatlayer_compiler_config_ops L.

      Local Open Scope Z_scope.

      Section VMXGetExitFaultAddrBody.

        Context `{Hwb: WritableBlockOps}.

        Variable (sc: stencil).

        Variables (ge: genv)
                  (STENCIL_MATCHES: stencil_matches sc ge).

vmcs_readz
        Variable bvmcs_readz: block.
        Hypothesis hvmcs_readz1 : Genv.find_symbol ge vmcs_readz = Some bvmcs_readz.
        Hypothesis hvmcs_readz2 : Genv.find_funct_ptr ge bvmcs_readz =
                                  Some (External (EF_external vmcs_readz
                                                              (signature_of_type (Tcons tint Tnil) tint cc_default))
                                                 (Tcons tint Tnil) tint cc_default).

        Lemma vmx_get_exit_fault_addr_body_correct:
           m d env le v,
            env = PTree.empty _
            vmx_get_exit_fault_addr_spec d = Some (Int.unsigned v) →
             le´,
              exec_stmt ge env le ((m, d): mem) vmx_get_exit_fault_addr_body E0 le´ (m, d)
                        (Out_return (Some (Vint v, tuint))).
        Proof.
          generalize max_unsigned_val; intro muval.
          intros; subst.
          unfold vmx_get_exit_fault_addr_body.
          functional inversion H0; subst.
          esplit.
          repeat vcgenfull; try discriminate.
          unfold vmcs_readz_spec.
          rewrite H3, H2, H1, H4, H5, H.
          reflexivity.
        Qed.

      End VMXGetExitFaultAddrBody.

      Theorem vmx_get_exit_fault_addr__code_correct:
        spec_le
          ( vmx_get_exit_fault_addr vmx_get_exit_fault_addr_spec_low )
          ( vmx_get_exit_fault_addr f_vmx_get_exit_fault_addrL).
      Proof.
        fbigstep_pre L.
        fbigstep
          (vmx_get_exit_fault_addr_body_correct
             s (Genv.globalenv p) makeglobalenv b0 Hb0fs Hb0fp
             m´0 labd (PTree.empty _)
             (bind_parameter_temps´
                (fn_params f_vmx_get_exit_fault_addr)
                (nil)
                (create_undef_temps (fn_temps f_vmx_get_exit_fault_addr))
             )
          ) H0.
      Qed.
    End VMXGETEXITFAULTADDR.

    Section VMXGETEXITREASON.

      Let L: compatlayer (cdata RData) :=
        vmcs_readz gensem vmcs_readz_spec.

      Local Instance: ExternalCallsOps mem := CompatExternalCalls.compatlayer_extcall_ops L.

      Local Instance: CompilerConfigOps mem := CompatExternalCalls.compatlayer_compiler_config_ops L.

      Local Open Scope Z_scope.

      Section VMXGetExitReasonBody.

        Context `{Hwb: WritableBlockOps}.

        Variable (sc: stencil).

        Variables (ge: genv)
                  (STENCIL_MATCHES: stencil_matches sc ge).

vmcs_readz
        Variable bvmcs_readz: block.
        Hypothesis hvmcs_readz1 : Genv.find_symbol ge vmcs_readz = Some bvmcs_readz.
        Hypothesis hvmcs_readz2 : Genv.find_funct_ptr ge bvmcs_readz =
                                  Some (External (EF_external vmcs_readz
                                                              (signature_of_type (Tcons tint Tnil) tint cc_default))
                                                 (Tcons tint Tnil) tint cc_default).

        Lemma vmx_get_exit_reason_body_correct:
           m d env le v,
            env = PTree.empty _
            vmx_get_exit_reason_spec d = Some (Int.unsigned v) →
             le´,
              exec_stmt ge env le ((m, d): mem) vmx_get_exit_reason_body E0 le´ (m, d)
                        (Out_return (Some (Vint v, tint))).
        Proof.
          generalize max_unsigned_val; intro muval.
          intros; subst.
          unfold vmx_get_exit_reason_body.
          functional inversion H0; subst.
          esplit.
          repeat vcgenfull; try discriminate.
          - Case ("read 17410").
            unfold vmcs_readz_spec.
            rewrite H1, H3, H2, H4, H5; simpl.
            discharge_cmp.
          - discharge_cmp.
            rewrite <- Int.repr_unsigned with v.
            rewrite <- H.
            reflexivity.
        Qed.

      End VMXGetExitReasonBody.

      Theorem vmx_get_exit_reason__code_correct:
        spec_le
          (vmx_get_exit_reason vmx_get_exit_reason_spec_low)
          (vmx_get_exit_reason f_vmx_get_exit_reason L).
      Proof.
        fbigstep_pre L.
        fbigstep
          (vmx_get_exit_reason_body_correct
             s (Genv.globalenv p) makeglobalenv b0 Hb0fs Hb0fp
             m´0 labd (PTree.empty _)
             (bind_parameter_temps´
                (fn_params f_vmx_get_exit_reason)
                (nil)
                (create_undef_temps (fn_temps f_vmx_get_exit_reason))
             )
          ) H0.
      Qed.
    End VMXGETEXITREASON.

    Section VMXCHECKINTSHADOW.

      Let L: compatlayer (cdata RData) :=
        vmcs_readz gensem vmcs_readz_spec.

      Local Instance: ExternalCallsOps mem := CompatExternalCalls.compatlayer_extcall_ops L.

      Local Instance: CompilerConfigOps mem := CompatExternalCalls.compatlayer_compiler_config_ops L.

      Local Open Scope Z_scope.

      Section VMXCheckIntShadowBody.

        Context `{Hwb: WritableBlockOps}.

        Variable (sc: stencil).

        Variables (ge: genv)
                  (STENCIL_MATCHES: stencil_matches sc ge).

vmcs_readz
        Variable bvmcs_readz: block.
        Hypothesis hvmcs_readz1 : Genv.find_symbol ge vmcs_readz = Some bvmcs_readz.
        Hypothesis hvmcs_readz2 : Genv.find_funct_ptr ge bvmcs_readz =
                                  Some (External (EF_external vmcs_readz
                                                              (signature_of_type (Tcons tint Tnil) tint cc_default))
                                                 (Tcons tint Tnil) tint cc_default).

        Lemma vmx_check_int_shadow_body_correct:
           m d env le v,
            env = PTree.empty _
            vmx_check_int_shadow_spec d = Some (Int.unsigned v) →
             le´,
              exec_stmt ge env le ((m, d): mem) vmx_check_int_shadow_body E0 le´ (m, d)
                        (Out_return (Some (Vint v, tint))).
        Proof.
          generalize max_unsigned_val; intro muval.
          assert (Hone_or_two: Z.lor 1 2 = 3). reflexivity.
          intros; subst.
          unfold vmx_check_int_shadow_body.
          functional inversion H0; subst.
          - Case ("does not have shadowed int").
            esplit.
            destruct (zeq (Z.land (Int.unsigned ctrls) 3) 0); try discriminate H6.
            repeat vcgenfull; try discriminate.
            + SCase ("read 18468").
              unfold vmcs_readz_spec.
              rewrite H1, H3, H2, H4, H5; simpl.
              discharge_cmp.
            + rewrite Hone_or_two; rewrite e; repeat vcgen.
            + rewrite H; repeat vcgen.

          - Case ("has shadowed int").
            esplit.
            destruct (zeq (Z.land (Int.unsigned ctrls) 3) 0); try discriminate H6.
            repeat vcgenfull; try discriminate.
            unfold vmcs_readz_spec.
            rewrite H1, H3, H2, H4, H5; simpl.
            discharge_cmp.
            + rewrite Hone_or_two; discharge_cmp; repeat vcgen.
            + unfold Int.one; rewrite H; repeat vcgen.
        Qed.

      End VMXCheckIntShadowBody.

      Theorem vmx_check_int_shadow__code_correct:
        spec_le
          (vmx_check_int_shadow vmx_check_int_shadow_spec_low)
          (vmx_check_int_shadow f_vmx_check_int_shadow L).
      Proof.
        fbigstep_pre L.
        fbigstep
          (vmx_check_int_shadow_body_correct
             s (Genv.globalenv p) makeglobalenv b0 Hb0fs Hb0fp
             m´0 labd (PTree.empty _)
             (bind_parameter_temps´
                (fn_params f_vmx_check_int_shadow)
                (nil)
                (create_undef_temps (fn_temps f_vmx_check_int_shadow))
             )
          ) H0.
      Qed.
    End VMXCHECKINTSHADOW.

    Section VMXCHECKPENDINGEVENT.

      Let L: compatlayer (cdata RData) :=
        vmcs_readz gensem vmcs_readz_spec.

      Local Instance: ExternalCallsOps mem := CompatExternalCalls.compatlayer_extcall_ops L.

      Local Instance: CompilerConfigOps mem := CompatExternalCalls.compatlayer_compiler_config_ops L.

      Local Open Scope Z_scope.

      Section VMXCheckPendingEventBody.

        Context `{Hwb: WritableBlockOps}.

        Variable (sc: stencil).

        Variables (ge: genv)
                  (STENCIL_MATCHES: stencil_matches sc ge).

vmcs_readz
        Variable bvmcs_readz: block.
        Hypothesis hvmcs_readz1 : Genv.find_symbol ge vmcs_readz = Some bvmcs_readz.
        Hypothesis hvmcs_readz2 : Genv.find_funct_ptr ge bvmcs_readz =
                                  Some (External (EF_external vmcs_readz
                                                              (signature_of_type (Tcons tint Tnil) tint cc_default))
                                                 (Tcons tint Tnil) tint cc_default).

        Lemma vmx_check_pending_event_body_correct:
           m d env le v,
            env = PTree.empty _
            vmx_check_pending_event_spec d = Some (Int.unsigned v) →
             le´,
              exec_stmt ge env le ((m, d): mem) vmx_check_pending_event_body E0 le´ (m, d)
                        (Out_return (Some (Vint v, tint))).
        Proof.
          generalize max_unsigned_val; intro muval.
          intros; subst.
          unfold vmx_check_pending_event_body.
          functional inversion H0; subst.
          - Case ("does not have pending event").
            esplit.
            destruct (zeq (Z.land (Int.unsigned ctrls) 2147483648) 0); try discriminate H6.
            + SCase ("read 16406").
              repeat vcgenfull; try discriminate.
              unfold vmcs_readz_spec.
              rewrite H1, H3, H2, H4, H5; simpl.
              discharge_cmp.
              × rewrite _x; repeat vcgen.
              × rewrite H; repeat vcgen.

          - Case ("has pending event").
            esplit.
            destruct (zeq (Z.land (Int.unsigned ctrls) 2147483648) 0); try discriminate H6.
            repeat vcgenfull; try discriminate.
            + SCase ("read 16406").
              unfold vmcs_readz_spec.
              rewrite H1, H3, H2, H4, H5; simpl.
              discharge_cmp.
            + discharge_cmp. repeat vcgen.
            + unfold Int.one; rewrite H; repeat vcgen.
        Qed.

      End VMXCheckPendingEventBody.

      Theorem vmx_check_pending_event__code_correct:
        spec_le
          (vmx_check_pending_event vmx_check_pending_event_spec_low)
          (vmx_check_pending_event f_vmx_check_pending_event L).
      Proof.
        fbigstep_pre L.
        fbigstep
          (vmx_check_pending_event_body_correct
             s (Genv.globalenv p) makeglobalenv b0 Hb0fs Hb0fp
             m´0 labd (PTree.empty _)
             (bind_parameter_temps´
                (fn_params f_vmx_check_pending_event)
                (nil)
                (create_undef_temps (fn_temps f_vmx_check_pending_event))
             )
          ) H0.
      Qed.
    End VMXCHECKPENDINGEVENT.


    Section VMXINJECTEVENT.

      Let L: compatlayer (cdata RData) :=
        vmcs_readz gensem vmcs_readz_spec
      vmcs_writez gensem vmcs_writez_spec.

      Local Instance: ExternalCallsOps mem := CompatExternalCalls.compatlayer_extcall_ops L.

      Local Instance: CompilerConfigOps mem := CompatExternalCalls.compatlayer_compiler_config_ops L.

      Local Open Scope Z_scope.

      Section VMXInjectEventBody.

        Context `{Hwb: WritableBlockOps}.

        Variable (sc: stencil).

        Variables (ge: genv)
                  (STENCIL_MATCHES: stencil_matches sc ge).

vmcs_readz
        Variable bvmcs_readz: block.
        Hypothesis hvmcs_readz1 : Genv.find_symbol ge vmcs_readz = Some bvmcs_readz.
        Hypothesis hvmcs_readz2 : Genv.find_funct_ptr ge bvmcs_readz =
                                  Some (External (EF_external vmcs_readz
                                                              (signature_of_type (Tcons tint Tnil) tint cc_default))
                                                 (Tcons tint Tnil) tint cc_default).

vmcs_writez
        Variable bvmcs_writez: block.
        Hypothesis hvmcs_writez1 : Genv.find_symbol ge vmcs_writez = Some bvmcs_writez.
        Hypothesis hvmcs_writez2 : Genv.find_funct_ptr ge bvmcs_writez =
                                   let arg_type := (Tcons tint (Tcons tint Tnil)) in
                                   let ret_type := tvoid in
                                   let cal_conv := cc_default in
                                   Some (External (EF_external vmcs_writez
                                                               (signature_of_type arg_type ret_type cal_conv))
                                                  arg_type ret_type cal_conv).


        Lemma vmx_inject_event_body_correct:
           m d env le type vector errcode ev,
            env = PTree.empty _
            PTree.get _type le = Some (Vint type) →
            PTree.get _vector le = Some (Vint vector) →
            PTree.get _errcode le = Some (Vint errcode) →
            PTree.get _ev le = Some (Vint ev) →
            vmx_inject_event_spec (Int.unsigned type) (Int.unsigned vector)
                                  (Int.unsigned errcode) (Int.unsigned ev) d
            = Some
             le´,
              exec_stmt ge env le ((m, d): mem) vmx_inject_event_body E0 le´ (m, )
                        Out_normal.
        Proof.
          generalize max_unsigned_val; intro muval.
          intros; subst.
          unfold vmx_inject_event_body.
          functional inversion H4; subst.

          - Case ("intr_info & VMCS_INTERRUPTION_INFO_VALID == 0 && ev == 1").
            destruct (zeq (Z.land i 2147483648) 0); try discriminate H10.
            destruct (zeq (Int.unsigned ev) 1); try discriminate H11.
            unfold i in ×.
            SCase ("assertion: get vmcs VMCS_ENTRY_INTR_INFO").

            assert ( read16406 :
                       match vmcs_readz_spec 16406 d with
                       | Some aret (d, a)
                       | NoneNone
                       end =
                       ret (d, Int.unsigned
                                 (Int.repr (Int.unsigned (Int.repr (Int.unsigned intr_info)))))).
            unfold vmcs_readz_spec.
            rewrite H5, H7, H6, H8, H9; simpl.
            repeat zdestruct; discharge_cmp.

            SSCase ("assertion: set vmcs VMCS_ENTRY_INTR_INFO").
            assert ( write16408 :
                       vmcs_writez_spec
                         16408
                         (Int.unsigned errcode)
                         d {vmcs
                            : VMCSValid
                                revid abrtid
                                (ZMap.set
                                   16406
                                   (Vint (Int.repr (Z.lor (Z.lor (Z.lor 2147483648 (Int.unsigned type))
                                                                 (Int.unsigned vector)) 2048))) d0)} =
                       ret d {vmcs : VMCSValid revid abrtid d2}).
            unfold vmcs_writez_spec.
            unfold d2, d1, i3, i2, i1 in ×.
            repeat zdestruct. discharge_cmp.
            rewrite H5, H7, H6. vcgen.
            + esplit.
              repeat vcgenfull; try discriminate;
              repeat (try apply Z_lor_range; try vcgen; try omega).

          - Case ("intr_info & VMCS_INTERRUPTION_INFO_VALID == 0 && ev != 1").
             destruct (zeq (Z.land i 2147483648) 0); try discriminate H10.
             destruct (zeq (Int.unsigned ev) 1); try discriminate H11.
             unfold i in ×.
             SCase ("assertion: get vmcs VMCS_ENTRY_INTR_INFO").

             assert ( read16406 :
                        match vmcs_readz_spec 16406 d with
                        | Some aret (d, a)
                        | NoneNone
                        end =
                        ret (d, Int.unsigned
                                  (Int.repr (Int.unsigned (Int.repr (Int.unsigned intr_info)))))).
             unfold vmcs_readz_spec.
             rewrite H5, H7, H6, H8, H9; simpl.
             repeat zdestruct; discharge_cmp.
             + esplit.
               repeat vcgenfull; try discriminate;
               repeat (try apply Z_lor_range; try vcgen; try omega).

          - Case ("assertion: another get vmcs VMCS_ENTRY_INTR_INFO").
            assert ( read16406´neq0 :
                       match vmcs_readz_spec 16406 with
                       | Some aret (, a)
                       | NoneNone
                       end = ret (, Int.unsigned intr_info)).
            unfold vmcs_readz_spec.
            rewrite H5, H7, H6, H8, H9; simpl.
            reflexivity.

            + SCase ("intr_info & VMCS_INTERRUPTION_INFO_VALID != 0").
              unfold i in ×.
              unfold is_invalid in ×.

              × esplit.
                repeat vcgenfull; try discriminate;
                repeat (try apply Z_lor_range; try vcgen; try omega).
        Qed.

      End VMXInjectEventBody.

      Theorem vmx_inject_event__code_correct:
        spec_le
          (vmx_inject_event vmx_inject_event_spec_low)
          (vmx_inject_event f_vmx_inject_event L).
      Proof.
        set ( := L) in ×. unfold L in ×.
        fbigstep_pre .
        Require Import TacticsForTesting.
        fbigsteptest
          (vmx_inject_event_body_correct
             s (Genv.globalenv p) makeglobalenv b0 Hb0fs Hb0fp b1 Hb1fs Hb1fp
             m´0 labd labd´ (PTree.empty _)
             (bind_parameter_temps´
                (fn_params f_vmx_inject_event)
                (Vint type :: Vint vector :: Vint errcode :: Vint ev :: nil)
                (create_undef_temps (fn_temps f_vmx_inject_event))
             )
          ) H0; try discriminate.
        intro tmpH; destruct tmpH as [le´ stmt].
        repeat fbigstep_post.
      Qed.

    End VMXINJECTEVENT.

    Section VMXSETINTERCEPTINTWIN.

      Let L: compatlayer (cdata RData) :=
        vmcs_readz gensem vmcs_readz_spec
      vmcs_writez gensem vmcs_writez_spec.

      Local Instance: ExternalCallsOps mem := CompatExternalCalls.compatlayer_extcall_ops L.

      Local Instance: CompilerConfigOps mem := CompatExternalCalls.compatlayer_compiler_config_ops L.

      Local Open Scope Z_scope.

      Section VMXSetInterceptionIntwinBody.

        Context `{Hwb: WritableBlockOps}.

        Variable (sc: stencil).

        Variables (ge: genv)
                  (STENCIL_MATCHES: stencil_matches sc ge).

vmcs_readz
        Variable bvmcs_readz: block.
        Hypothesis hvmcs_readz1 : Genv.find_symbol ge vmcs_readz = Some bvmcs_readz.
        Hypothesis hvmcs_readz2 : Genv.find_funct_ptr ge bvmcs_readz =
                                  Some (External (EF_external vmcs_readz
                                                              (signature_of_type (Tcons tint Tnil) tint cc_default))
                                                 (Tcons tint Tnil) tint cc_default).

vmcs_writez
        Variable bvmcs_writez: block.
        Hypothesis hvmcs_writez1 : Genv.find_symbol ge vmcs_writez = Some bvmcs_writez.
        Hypothesis hvmcs_writez2 : Genv.find_funct_ptr ge bvmcs_writez =
                                   let arg_type := (Tcons tint (Tcons tint Tnil)) in
                                   let ret_type := tvoid in
                                   let cal_conv := cc_default in
                                   Some (External (EF_external vmcs_writez
                                                               (signature_of_type arg_type ret_type cal_conv))
                                                  arg_type ret_type cal_conv).

        Lemma vmx_set_intercept_intwin_body_correct:
           m d env le enable,
            env = PTree.empty _
            PTree.get tenable le = Some (Vint enable) →
            vmx_set_intercept_intwin_spec (Int.unsigned enable) d = Some
             le´,
              exec_stmt ge env le ((m, d): mem) vmx_set_intercept_intwin_body E0 le´ (m, )
                        Out_normal.
        Proof.
          generalize max_unsigned_val; intro muval.
          intros. subst.
          unfold vmx_set_intercept_intwin_body.
          functional inversion H1; subst.
          - Case ("enable == 1").
            destruct (zeq (Int.unsigned enable) 1); try discriminate H7.
            esplit.
            repeat vcgen; try discriminate.
            + SCase ("get value").
              unfold vmcs_readz_spec.
              rewrite H2, H4, H3, H5, H6; simpl.
              repeat zdestruct. discharge_cmp.
            + SCase ("set value").
              unfold vmcs_writez_spec.
              rewrite H2, H4, H3, H5; simpl.
              repeat zdestruct. discharge_cmp.
            + SCase ("arithmetic").
              apply Z_lor_range. rewrite muval. apply Int.unsigned_range_2. omega.

          - Case ("enable != 1").
            destruct (zeq (Int.unsigned enable) 1); try discriminate H7.
            esplit.
            repeat vcgen; try discriminate.
            + SCase ("get value").
              unfold vmcs_readz_spec.
              rewrite H2, H4, H3, H5, H6; simpl.
              repeat zdestruct. discharge_cmp.
            + SCase ("set value").
              rewrite Int.unsigned_not, Int.unsigned_repr, muval; simpl.
              unfold vmcs_writez_spec.
              rewrite H2, H4, H3, H5; simpl.
              repeat zdestruct. discharge_cmp.
              omega.
            + SCase ("arithmetic").
              rewrite Int.unsigned_not, Int.unsigned_repr, muval; simpl.
              apply Z_land_range. apply Int.unsigned_range_2. omega.
              omega.
        Qed.

      End VMXSetInterceptionIntwinBody.

      Theorem vmx_set_intercept_intwin__code_correct:
        spec_le
          (vmx_set_intercept_intwin vmx_set_intercept_intwin_spec_low)
          (vmx_set_intercept_intwin f_vmx_set_intercept_intwin L).
      Proof.
        set ( := L) in ×. unfold L in ×.
        fbigstep_pre .
        fbigstep
          (vmx_set_intercept_intwin_body_correct
             s (Genv.globalenv p) makeglobalenv b0 Hb0fs Hb0fp b1 Hb1fs Hb1fp
             m´0 labd labd´ (PTree.empty _)
             (bind_parameter_temps´
                (fn_params f_vmx_set_intercept_intwin)
                (Vint enable :: nil)
                (create_undef_temps (fn_temps f_vmx_set_intercept_intwin))
             )
          ) H0.
      Qed.
    End VMXSETINTERCEPTINTWIN.

  End WithPrimitives.

End VMCSINTROCODE.