An Operating System Machine

4 downloads 0 Views 660KB Size Report
tion, which is primarily used on PCs, in 2005 and Parallels Desktop for Mac, ... Other differences between virtualization in server/desktop and embedded envi-.
An Operating System Machine Ming-Yuan Zhu CoreTek Systems, Inc. 1109 CEC Building 6 South Zhongguancun Street Beijing 100086 People’s Republic of China E-Mail: [email protected]

Preface This work is a part of TRUSTIE Project and is supported in part by the HiTech Research and Development Program of China under the contract number 2007AA010304.

i

Contents I

Verification of Real-Time Operating Systems

2

1 Introduction 1.1 Common Criteria . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2 Software Specification . . . . . . . . . . . . . . . . . . . . . . . 1.3 Verification Technology . . . . . . . . . . . . . . . . . . . . . . 1.3.1 Model Checking . . . . . . . . . . . . . . . . . . . . . . 1.3.2 Theorem Proving . . . . . . . . . . . . . . . . . . . . . . 1.3.3 Verifying Kernels . . . . . . . . . . . . . . . . . . . . . . 1.4 Formal Verification of Microkernels . . . . . . . . . . . . . . . . 1.4.1 Formal Verification . . . . . . . . . . . . . . . . . . . . . 1.4.2 Monolithic and Microkernels . . . . . . . . . . . . . . . 1.4.3 Architectures . . . . . . . . . . . . . . . . . . . . . . . . 1.4.3.1 Monolithic Kernels . . . . . . . . . . . . . . . . 1.4.3.2 Microkernels . . . . . . . . . . . . . . . . . . . 1.4.3.3 Advantages and Disadvantages of Microkernels 1.4.3.4 Basic Services in Microkernels . . . . . . . . . 1.4.4 Services and Policies . . . . . . . . . . . . . . . . . . . . 1.4.4.1 Functional Specifications of Microkernels . . . 1.4.4.2 Access Control and Data Separation . . . . . . 1.4.4.3 Information Flow . . . . . . . . . . . . . . . . 1.4.4.4 Non-Interference . . . . . . . . . . . . . . . . . 1.4.4.5 Common Criteria . . . . . . . . . . . . . . . . 1.5 The Contribution of This Book . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

3 3 3 5 5 5 6 7 7 7 8 8 8 8 9 9 10 10 11 12 12 13

2 Type Theory and PowerEpsilon 2.1 PowerEpsilon . . . . . . . . . . . 2.2 Notations . . . . . . . . . . . . . 2.3 Lexicon . . . . . . . . . . . . . . 2.4 Syntax . . . . . . . . . . . . . . . 2.4.1 Variables . . . . . . . . . 2.4.2 Prop, Type(i), and Kind 2.4.3 Π-Formulas . . . . . . . .

. . . . . . .

14 14 15 15 15 16 17 17

ii

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

CONTENTS

2.4.4 Σ-Formulas . . . . . . . . . . . . . . . . . . . . 2.4.5 λ-Abstractions . . . . . . . . . . . . . . . . . . 2.4.6 Implication-Formula . . . . . . . . . . . . . . . 2.4.7 Function Application . . . . . . . . . . . . . . . 2.4.8 Pair . . . . . . . . . . . . . . . . . . . . . . . . 2.4.9 Let-Expression . . . . . . . . . . . . . . . . . . 2.4.10 Lec-Formula . . . . . . . . . . . . . . . . . . . 2.5 Examples . . . . . . . . . . . . . . . . . . . . . . . . . 2.5.1 Boolean . . . . . . . . . . . . . . . . . . . . . . 2.5.2 Natural Numbers . . . . . . . . . . . . . . . . . 2.5.3 List . . . . . . . . . . . . . . . . . . . . . . . . 2.6 Currying and Higher-Order Terms . . . . . . . . . . . 2.6.1 Higher-Order Functions . . . . . . . . . . . . . 2.6.2 Currying and Uncurrying . . . . . . . . . . . . 2.6.3 Generic Functions . . . . . . . . . . . . . . . . 2.7 Mathematical Logic in PowerEpsilon . . . . . . . . . . 2.7.1 Null Type . . . . . . . . . . . . . . . . . . . . . 2.7.2 Trivial Type . . . . . . . . . . . . . . . . . . . 2.7.3 Π-Type . . . . . . . . . . . . . . . . . . . . . . 2.7.4 Σ-Types . . . . . . . . . . . . . . . . . . . . . . 2.7.5 Product Types (×) . . . . . . . . . . . . . . . . 2.7.5.1 Product of Two Types P and Q . . . . 2.7.5.2 Product of Three Types U, V and W . 2.7.5.3 Product of Infinite Type Sequence . . 2.7.6 Sum Types (+) . . . . . . . . . . . . . . . . . . 2.7.6.1 Sum of Two Types U and V . . . . . . 2.7.6.2 Sum of Three Types U, V and W . . . . 2.7.6.3 Sum of Infinite Type Sequence . . . . 2.7.7 Subset Types . . . . . . . . . . . . . . . . . . . 2.7.8 Leibniz’s Equality . . . . . . . . . . . . . . . . 2.8 Transforming English to PowerEpsilon . . . . . . . . . 2.9 Propositions as Types and Proofs as Programs . . . . 2.10 Types, Sets and Domains . . . . . . . . . . . . . . . . 2.10.1 The Problem of Recursively Defined Functions 2.10.2 The Problem of Recursively Defined Sets . . . 2.10.3 The Role of Scott’s Domain Theory . . . . . . 2.10.4 Types as Domains . . . . . . . . . . . . . . . . 2.10.5 Defining Domains . . . . . . . . . . . . . . . . 2.10.5.1 Standard Domains . . . . . . . . . . . 2.10.5.2 Finite Domains . . . . . . . . . . . . . 2.10.5.3 Domain Constructors . . . . . . . . . 2.10.5.4 Domain Equations . . . . . . . . . . . 2.10.6 Functions . . . . . . . . . . . . . . . . . . . . .

iii

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

17 17 18 18 18 18 18 19 19 20 23 28 28 29 30 31 31 31 31 32 32 32 33 34 35 35 36 37 37 38 39 40 42 42 43 43 44 44 44 44 45 45 46

CONTENTS

iv

3 Hypervisor Technology 3.1 Classifications . . . . . . . . . . . . . . . . . . . 3.1.1 Type 1 Hypervisors . . . . . . . . . . . 3.1.2 Type 2 Hypervisors . . . . . . . . . . . 3.2 Mainframe Origins . . . . . . . . . . . . . . . . 3.3 UNIX and Linux Servers . . . . . . . . . . . . . 3.4 PCs and Desktop Systems . . . . . . . . . . . . 3.4.1 Paravirtualization . . . . . . . . . . . . 3.4.2 Hypervisors on PCs and Desktops . . . 3.5 Embedded Systems . . . . . . . . . . . . . . . . 3.5.1 Embedded Hypervisors . . . . . . . . . 3.5.2 Virtualization vs Paravirtualization . . 3.5.3 Challenges for Embedded Virtualization 3.5.4 Hypervisors in Embedded Industry . . . 3.5.4.1 Integrity from Green Hills . . . 3.5.4.2 OKL4 . . . . . . . . . . . . . . 3.5.4.3 Other Hypervisors . . . . . . . 3.6 Security Implications . . . . . . . . . . . . . . . 3.7 About SVMK . . . . . . . . . . . . . . . . . . .

II

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

The Abstract Target Machine

4 How The Machine Designed 4.1 Abstract Machine TM and TM-2 . . . . . . 4.2 The System Service APIs . . . . . . . . . . 4.2.1 Specifications for VM Management . 4.2.1.1 vmkGetVMID . . . . . . . . 4.2.1.2 vmkGetVMName . . . . . . . 4.2.1.3 vmkGetVMName . . . . . . . 4.2.1.4 vmkHaltVM . . . . . . . . . 4.2.1.5 vmkStartVM . . . . . . . . 4.2.1.6 vmkStopVM . . . . . . . . . 4.2.1.7 vmkSuspendVM . . . . . . . 4.2.1.8 vmkResumeVM . . . . . . . . 4.2.1.9 vmkGetInfo . . . . . . . . 4.2.1.10 vmkAccessVM . . . . . . . . 4.2.1.11 vmkAttachVM . . . . . . . . 4.2.1.12 vmkDetachVM . . . . . . . . 4.2.1.13 vmkGetExceptionVM . . . . 4.2.1.14 vmkAccessContext . . . . 4.2.1.15 vmkResetVM . . . . . . . . 4.2.2 Specifications for Virtual Interrupts 4.2.2.1 vmkInitializeVint . . . .

47 47 47 48 49 50 52 52 53 53 53 54 54 54 54 54 54 55 55

56 . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

57 57 57 57 57 58 58 58 58 58 58 59 59 59 59 59 59 60 60 60 60

CONTENTS

4.3 4.4 4.5

4.2.2.2 vmkEnablePIC . . . . . . . . . . . . 4.2.2.3 vmkDisablePIC . . . . . . . . . . . 4.2.2.4 vmkSendServiceInt . . . . . . . . . 4.2.2.5 vmkAckException . . . . . . . . . . 4.2.2.6 vmkDispatchInt . . . . . . . . . . . 4.2.2.7 vmkDispatchInt . . . . . . . . . . . 4.2.3 Specifications for TTS . . . . . . . . . . . . . 4.2.3.1 vmkInstallTTS . . . . . . . . . . . 4.2.3.2 vmkGetTTSID . . . . . . . . . . . . . 4.2.3.3 vmkGetTTSName . . . . . . . . . . . 4.2.3.4 vmkStartTTS . . . . . . . . . . . . . 4.2.3.5 vmkStopTTS . . . . . . . . . . . . . 4.2.4 Specifications for Initialization . . . . . . . . 4.2.5 Specifications for Scheduling . . . . . . . . . 4.2.5.1 vmkSchedule . . . . . . . . . . . . . 4.2.5.2 vmkSetVMReady . . . . . . . . . . . 4.2.5.3 vmkClearVMReady . . . . . . . . . . 4.2.5.4 vmkExactWaitedVM . . . . . . . . . 4.2.5.5 ClearVMWaiting . . . . . . . . . . . 4.2.5.6 vmkTickNotify . . . . . . . . . . . 4.2.6 Specifications for Health Monitor . . . . . . . 4.2.6.1 vmkDispatchHM . . . . . . . . . . . 4.2.6.2 vmkInformHM . . . . . . . . . . . . . 4.2.7 Specifications for Hooks . . . . . . . . . . . . Instructions for Operating System Kernel . . . . . . Data Structures of SVMK . . . . . . . . . . . . . . . Interrupts and Virtual Interrupts . . . . . . . . . . . 4.5.1 Overview . . . . . . . . . . . . . . . . . . . . 4.5.2 Types of Interrupts . . . . . . . . . . . . . . . 4.5.2.1 Level-Triggered . . . . . . . . . . . . 4.5.2.2 Edge-Triggered . . . . . . . . . . . . 4.5.2.3 Hybrid . . . . . . . . . . . . . . . . 4.5.2.4 Message-Signalled . . . . . . . . . . 4.5.2.5 Doorbell . . . . . . . . . . . . . . . 4.5.3 Difficulty with Sharing Interrupt Lines . . . . 4.5.4 Performance Issues . . . . . . . . . . . . . . . 4.5.5 Typical Uses . . . . . . . . . . . . . . . . . . 4.5.6 Interrupt Handler . . . . . . . . . . . . . . . 4.5.6.1 Classification of Interrupt Handlers 4.5.6.2 Interrupt Threads . . . . . . . . . . 4.5.7 Interrupt Latency . . . . . . . . . . . . . . . 4.5.7.1 Background . . . . . . . . . . . . . . 4.5.7.2 Considerations . . . . . . . . . . . .

v

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

60 60 60 61 61 61 61 61 61 62 62 62 62 62 62 62 63 63 63 63 63 63 63 64 64 66 66 67 68 68 69 70 70 71 71 72 72 72 73 73 74 74 75

CONTENTS

5 The Extended Machine 5.1 The Instruction Set . . . . . . . . . . . . . . . . . . . . . . . . . . 5.1.1 RO-Instruction Set . . . . . . . . . . . . . . . . . . . . . . 5.1.1.1 The Basic RO-Instruction Set . . . . . . . . . . 5.1.1.2 An Assumption on Operating System Related RO-Instructions . . . . . . . . . . . . . . . . . . 5.1.1.3 The RO-Instruction Set for Interrupt Handling, VM Controlling and Scheduling . . . . . . . . . 5.1.1.4 The RO-Instruction Set for Kernel State Transformation . . . . . . . . . . . . . . . . . . . . . . 5.1.1.5 Basic Instructions for Computing and Control . 5.1.1.6 Instructions for VMK Manager . . . . . . . . . . 5.1.1.7 Instructions for Virtual Interruption Management 5.1.1.8 Instructions for Scheduling . . . . . . . . . . . . 5.1.1.9 Instructions for Location List . . . . . . . . . . . 5.1.1.10 The Definition of ROInstr . . . . . . . . . . . . 5.1.2 RM-Instruction Set . . . . . . . . . . . . . . . . . . . . . . 5.1.2.1 Instructions for Computing and Control . . . . . 5.1.2.2 The Definition of RMInstr . . . . . . . . . . . . 5.1.3 Instruction Set . . . . . . . . . . . . . . . . . . . . . . . . 5.1.3.1 Type Definition of Instr . . . . . . . . . . . . . 5.1.3.2 Constructors of Instr . . . . . . . . . . . . . . . 5.1.3.3 Predicate Functions of Instr . . . . . . . . . . . 5.1.3.4 Projectors of Instr . . . . . . . . . . . . . . . . 5.1.4 TM Instructions . . . . . . . . . . . . . . . . . . . . . . . 5.1.4.1 Definition of TM Instruction . . . . . . . . . . . 5.1.4.2 TM Instruction Sequence . . . . . . . . . . . . . 5.1.5 Translation from C to TM-2 . . . . . . . . . . . . . . . . . 5.2 SVM Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2.1 SVM Status . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2.2 Interrupt Dispatch Table . . . . . . . . . . . . . . . . . . 5.2.3 Registers of SVM Manager . . . . . . . . . . . . . . . . . 5.2.4 Priority VM Queues . . . . . . . . . . . . . . . . . . . . . 5.2.5 SVM Manager . . . . . . . . . . . . . . . . . . . . . . . . 5.2.5.1 Type Definition of VMKManager . . . . . . . . . . 5.2.5.2 Constructor of VMKManager . . . . . . . . . . . . 5.2.5.3 Selectors of VMKManager . . . . . . . . . . . . . . 5.2.5.4 Modifiers of VMKManager . . . . . . . . . . . . . 5.3 VM Control Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . 5.3.1 Types of Health Monitoring . . . . . . . . . . . . . . . . . 5.3.2 Actions of Health Monitoring . . . . . . . . . . . . . . . . 5.3.3 VM Status . . . . . . . . . . . . . . . . . . . . . . . . . . 5.3.4 VM Scheduling Type . . . . . . . . . . . . . . . . . . . . . 5.3.4.1 VM Wakeup Type . . . . . . . . . . . . . . . . .

vi

76 76 76 76 77 77 78 79 80 80 80 81 81 81 82 83 83 83 83 84 84 84 84 85 85 86 86 87 87 87 88 88 88 89 89 89 90 90 91 91 92

CONTENTS

5.3.5 5.3.6 5.3.7

5.4

5.5

5.6

Other Attributes of VM . . . . . . . . . . . . . . . . . Registers of VMs . . . . . . . . . . . . . . . . . . . . . VM Control Blocks . . . . . . . . . . . . . . . . . . . . 5.3.7.1 Type Definition of VMCB . . . . . . . . . . . . 5.3.7.2 Constructor of VMCB . . . . . . . . . . . . . . 5.3.7.3 Selectors of VMCB . . . . . . . . . . . . . . . . 5.3.7.4 Modifiers of VMCB . . . . . . . . . . . . . . . TTS Control Blocks . . . . . . . . . . . . . . . . . . . . . . . 5.4.1 TTS Nodes . . . . . . . . . . . . . . . . . . . . . . . . 5.4.2 TTS Status Types . . . . . . . . . . . . . . . . . . . . 5.4.3 Tick Notify Type . . . . . . . . . . . . . . . . . . . . . 5.4.4 Registers of TTS . . . . . . . . . . . . . . . . . . . . . 5.4.5 TTS Control Blocks . . . . . . . . . . . . . . . . . . . Virtual Interrupt Control Blocks . . . . . . . . . . . . . . . . 5.5.1 When Virtual Interrupt Delivered . . . . . . . . . . . 5.5.2 Types of Virtual Interrupts . . . . . . . . . . . . . . . 5.5.3 Tick Interrupt Control Blocks . . . . . . . . . . . . . . 5.5.4 Other Interrupt Control Blocks . . . . . . . . . . . . . 5.5.5 List of Virtual Interruption Control Blocks . . . . . . 5.5.6 Virtual Interrupt Management System . . . . . . . . . TM State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.6.1 Nested Interrupt Handling Model . . . . . . . . . . . . 5.6.2 Basic Utilities . . . . . . . . . . . . . . . . . . . . . . . 5.6.3 Registers of TM . . . . . . . . . . . . . . . . . . . . . 5.6.3.1 PC - Program Counter . . . . . . . . . . . . 5.6.3.2 Memory Pointer . . . . . . . . . . . . . . . . 5.6.3.3 Global Pointer . . . . . . . . . . . . . . . . . 5.6.3.4 Accumulator . . . . . . . . . . . . . . . . . . 5.6.3.5 2nd Accumulator . . . . . . . . . . . . . . . . 5.6.3.6 Frame Pointer . . . . . . . . . . . . . . . . . 5.6.3.7 Static Chain Register . . . . . . . . . . . . . 5.6.3.8 Interrupt Control Register . . . . . . . . . . 5.6.3.9 Interrupt Enable Register . . . . . . . . . . . 5.6.3.10 Interrupt Service Register . . . . . . . . . . . 5.6.3.11 May We Need An Interrupt Service Register? 5.6.3.12 Interrupt Mask Register . . . . . . . . . . . . 5.6.3.13 Interrupt Handler Register . . . . . . . . . . 5.6.3.14 Segment Register . . . . . . . . . . . . . . . 5.6.3.15 Mode Register . . . . . . . . . . . . . . . . . 5.6.3.16 Virtual Interrupt Type Register . . . . . . . 5.6.3.17 Virtual Interrupt Service Register . . . . . . 5.6.3.18 Segment Number of SVM Manager . . . . . 5.6.3.19 Register Set . . . . . . . . . . . . . . . . . . 5.6.4 IO Vector . . . . . . . . . . . . . . . . . . . . . . . . .

vii

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

92 93 93 93 94 94 94 95 95 95 96 96 97 98 98 98 99 99 100 100 101 101 101 102 102 102 102 102 103 103 103 103 103 103 103 103 104 104 104 104 104 104 104 105

CONTENTS

5.6.5 5.6.6 5.6.7 5.6.8 5.6.9 5.6.10 5.6.11

viii

Data Memory . . . . . . . . . . . . . . . . . . . . . . Instruction Memory . . . . . . . . . . . . . . . . . . Context Stack . . . . . . . . . . . . . . . . . . . . . Segments . . . . . . . . . . . . . . . . . . . . . . . . Set of VMCBs . . . . . . . . . . . . . . . . . . . . . Set of TTSCBs . . . . . . . . . . . . . . . . . . . . . TM State . . . . . . . . . . . . . . . . . . . . . . . . 5.6.11.1 Type Definition of TMState . . . . . . . . . 5.6.11.2 Constructor of TMState . . . . . . . . . . . 5.6.11.3 Selectors of TMState . . . . . . . . . . . . . 5.6.11.4 Modifiers of TMState . . . . . . . . . . . . 5.6.11.5 Data Memory Access for TMState . . . . . 5.6.11.6 VMCB Access for TMState . . . . . . . . . 5.6.11.7 TTSCB Access for TMState . . . . . . . . . 5.6.11.8 Segment Access for TMState . . . . . . . . 5.6.11.9 SVM Manager Register Access for TMState 5.6.11.10 Location List Access for TMState . . . . . 5.6.11.11 VMVIntCB Access for TMState . . . . . . . . 5.6.11.12 Error State for TMState . . . . . . . . . . .

6 Semantics of Extended Target Machine 6.1 Semantics for Computation and Control . . . . 6.1.1 Semantics of IRET . . . . . . . . . . . . 6.1.2 Semantics of VIRET . . . . . . . . . . . . 6.1.3 Semantics of HALT . . . . . . . . . . . . 6.1.4 Semantics of ADD . . . . . . . . . . . . . 6.1.5 Semantics of SUB . . . . . . . . . . . . . 6.1.6 Semantics of MUL . . . . . . . . . . . . . 6.1.7 Semantics of DIV . . . . . . . . . . . . . 6.1.8 Semantics of BITAND . . . . . . . . . . . 6.1.9 Semantics of BITOR . . . . . . . . . . . . 6.1.10 Semantics of BITMASK . . . . . . . . . . 6.1.11 Semantics of BITANDMATCH . . . . . . . . 6.1.12 Semantics of BITORMATCH . . . . . . . . 6.1.13 Semantics of BITSHIFTL . . . . . . . . . 6.1.14 Semantics of BITSHIFTR . . . . . . . . . 6.1.15 Dynamic Capability Checking Functions 6.1.15.1 Readability Checking . . . . . 6.1.15.2 Writability Checking . . . . . . 6.1.16 Semantics of LD . . . . . . . . . . . . . . 6.1.17 Semantics of LDA . . . . . . . . . . . . . 6.1.18 Semantics of LDC . . . . . . . . . . . . . 6.1.19 Semantics of ST . . . . . . . . . . . . . . 6.1.20 Semantics of JLT . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

105 105 106 106 106 107 107 107 107 108 108 109 109 109 110 110 112 116 121

. . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . .

123 123 123 124 124 124 125 125 125 126 126 127 127 127 128 128 128 128 129 130 132 133 134 135

CONTENTS

6.2

6.3

6.4

6.5

6.6

6.1.21 Semantics of JLE . . . . . . . . . . . . . . . . . . . . 6.1.22 Semantics of JGE . . . . . . . . . . . . . . . . . . . . 6.1.23 Semantics of JGT . . . . . . . . . . . . . . . . . . . . 6.1.24 Semantics of JEQ . . . . . . . . . . . . . . . . . . . . 6.1.25 Semantics of JNE . . . . . . . . . . . . . . . . . . . . Semantics for VMK Manager, VMCBs and TTSCBs . . . . 6.2.1 Semantics of MAN GET . . . . . . . . . . . . . . . . . 6.2.2 Semantics of MAN SET . . . . . . . . . . . . . . . . . 6.2.3 Semantics of VM GET . . . . . . . . . . . . . . . . . . 6.2.4 Semantics of VM SET . . . . . . . . . . . . . . . . . . 6.2.5 Semantics of TTS GET . . . . . . . . . . . . . . . . . 6.2.6 Semantics of TTS SET . . . . . . . . . . . . . . . . . Semantics for Scheduling . . . . . . . . . . . . . . . . . . . . 6.3.1 Semantics of SCHEDULE . . . . . . . . . . . . . . . . . 6.3.2 Semantics of CLEAR VM READY . . . . . . . . . . . . . 6.3.3 Semantics of SET VM READY . . . . . . . . . . . . . . 6.3.4 Semantics of CLEAR VM WAIT . . . . . . . . . . . . . . 6.3.5 Semantics of EXACT VM WAIT . . . . . . . . . . . . . . 6.3.6 Semantics of TICK NOTIFY . . . . . . . . . . . . . . . Semantics for Interrupt and Virtual Interrupt Management 6.4.1 Semantics of EPIC . . . . . . . . . . . . . . . . . . . 6.4.2 Semantics of DPIC . . . . . . . . . . . . . . . . . . . 6.4.3 Semantics of SSINT . . . . . . . . . . . . . . . . . . . 6.4.4 Semantics of VAE . . . . . . . . . . . . . . . . . . . . 6.4.5 Semantics of TVI . . . . . . . . . . . . . . . . . . . . 6.4.6 Semantics of INTP . . . . . . . . . . . . . . . . . . . 6.4.7 Semantics of IVTI . . . . . . . . . . . . . . . . . . . Semantics for Location List . . . . . . . . . . . . . . . . . . 6.5.1 Semantics of INSERT WVM . . . . . . . . . . . . . . . 6.5.2 Semantics of VLOC EMPTY . . . . . . . . . . . . . . . 6.5.3 Semantics of VLOC HEAD . . . . . . . . . . . . . . . . 6.5.4 Semantics of VLOC TAIL . . . . . . . . . . . . . . . . 6.5.5 Semantics of VLOC CONS . . . . . . . . . . . . . . . . 6.5.6 Semantics of VLOC IN . . . . . . . . . . . . . . . . . 6.5.7 Semantics of VLOC GET . . . . . . . . . . . . . . . . . 6.5.8 Semantics of VLOC SET . . . . . . . . . . . . . . . . . 6.5.9 Semantics of VLOC DEL . . . . . . . . . . . . . . . . . Semantics of TM-2 . . . . . . . . . . . . . . . . . . . . . . . 6.6.1 Semantics of RO-Instructions . . . . . . . . . . . . . 6.6.2 Semantics of RM-Instructions . . . . . . . . . . . . . 6.6.3 Semantics of TM Instructions . . . . . . . . . . . . . 6.6.4 Fetch-Execution Cycle . . . . . . . . . . . . . . . . . 6.6.5 Functions for Interruption Handling . . . . . . . . . 6.6.6 Functions for Virtual Interruption Handling . . . . .

ix

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

135 136 136 137 137 138 138 138 139 140 140 141 141 141 143 145 147 148 149 156 156 158 159 161 161 164 165 166 166 166 166 167 167 167 168 168 169 169 169 170 171 171 171 173

CONTENTS

6.6.7 6.6.8

III

x

Simulation Semantics . Initialization . . . . . . 6.6.8.1 Initialization of 6.6.8.2 Initialization of 6.6.8.3 Initialization of

. . . . . . . . . . . . . . . . . . Registers . . . Data Memory TM . . . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

The Verification

177 179 179 179 180

181

7 The Separation Kernel Property 7.1 Specification of Separation Kernel . . . . . . . . . . . . 7.1.1 Temporal Separation . . . . . . . . . . . . . . . . 7.1.2 Spatial Separation . . . . . . . . . . . . . . . . . 7.2 Formal Definition of Spatial Separation . . . . . . . . . 7.2.1 Well-Defined VMCB . . . . . . . . . . . . . . . . 7.2.2 Well-Defined Address . . . . . . . . . . . . . . . 7.2.3 Uniqness of VMKMagnager Index . . . . . . . . 7.2.4 Uniqness of VMCB Indexes . . . . . . . . . . . . 7.2.5 Space Separation Property . . . . . . . . . . . . 7.3 Formal Definition of Temporal Separation . . . . . . . . 7.3.1 Uniqueness of Running VM . . . . . . . . . . . . 7.4 Spatial Separation Kernel Theorem . . . . . . . . . . . . 7.4.1 The Spatial Separation Kernel Theorem . . . . . 7.4.2 The Proof of Spatial Separation Kernel Theorem

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

182 182 182 183 183 183 184 184 184 185 185 186 186 186 186

8 The Memory Separation Property 8.1 Specification of Memory Partitioning . . . . . . . . . . . 8.1.1 Instructions Well-Defined in Instruction Memory 8.1.2 Memory Partitioning . . . . . . . . . . . . . . . . 8.1.3 Specification of Safe Memory . . . . . . . . . . . 8.2 Memory Safe Theorem . . . . . . . . . . . . . . . . . . . 8.2.1 The Safe Kernel Theorem . . . . . . . . . . . . . 8.2.2 The Proof of Safe Kernel Theorem . . . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

189 189 189 189 190 191 191 191

9 The Safe ISR Property 9.1 The Specification Safe ISR Property . . 9.2 Safe ISR Theorem . . . . . . . . . . . . 9.2.1 The Safe ISR Theorem . . . . . . 9.2.2 The Proof of Safe ISR Theorem .

. . . .

. . . .

. . . .

. . . .

. . . .

193 193 197 197 198

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

10 Formal Deterministic Analysis of SVMK 199 10.1 What is Deterministic RTOSes? . . . . . . . . . . . . . . . . . . . 199 10.1.1 The Definition of Deterministics . . . . . . . . . . . . . . 199 10.1.2 The Deterministic Requirement for RTOSes . . . . . . . . 199

CONTENTS

xi

10.1.3 Deterministics and Termination Condition . . . . . . . . . 200 10.2 Functions for Time-Complexity Calculation . . . . . . . . . . . . 200 10.3 Definitions of Deterministics . . . . . . . . . . . . . . . . . . . . . 201 10.3.1 Definitions of Deterministics for Functions on TMState . . 201 10.3.2 Definitions of Deterministics for Functions on Bool and Nat202 10.3.3 Definitions of Deterministics for Functions on TMReg . . . 203 10.3.4 Definitions of Deterministics for Functions on VMCB . . . . 203 10.3.5 Deterministics of Instructions . . . . . . . . . . . . . . . . 204 10.4 Deterministic Conditions . . . . . . . . . . . . . . . . . . . . . . . 205 10.4.1 Deterministic Condition for Instructions . . . . . . . . . . 205 10.4.2 Deterministic Condition for State Transition Functions . . 205 10.4.3 Deterministic Condition for Bool, Nat and TMReg . . . . . 206 10.4.4 Deterministic Conditions for VMKManager . . . . . . . . . 207 10.4.5 Deterministic Conditions for VMCB . . . . . . . . . . . . . 207 10.5 The Time-Deterministic Theorems . . . . . . . . . . . . . . . . . 208 10.6 The Proofs of Time-Deterministic Theorems . . . . . . . . . . . . 208 10.6.1 Time-Deterministic Theorems for RO-Instructions . . . . 208 10.6.2 Time-Deterministic Theorems for RM-Instructions . . . . 209 10.6.3 Axioms of Time-Deterministic Analysis . . . . . . . . . . 209 10.6.4 Auxiliary Theorems . . . . . . . . . . . . . . . . . . . . . 212 10.6.4.1 Utility Theorems for Conditional Functions . . . 212 10.6.4.2 Utility Theorems for Composition Functions . . 212 10.6.4.3 Proofs of Utility Theorems . . . . . . . . . . . . 217 10.6.5 Proofs of TimeDetThm . . . . . . . . . . . . . . . . . . . . 219 10.6.6 Proofs of TimeDetThm2 . . . . . . . . . . . . . . . . . . . . 219 10.6.7 Proofs of RMTimeDetThm and RMTimeDetThm2 . . . . . . . 222 10.6.7.1 The Theorem RMTimeDetThm3 and Its Proof . . 222 10.6.7.2 Time Deterministic Theorem for RMOpcode . . . 222 10.6.7.3 Two Axioms . . . . . . . . . . . . . . . . . . . . 223 10.6.7.4 Time Deterministic Theorem for LD . . . . . . . 223 10.6.7.5 Time Deterministic Theorem for LDA . . . . . . 224 10.6.7.6 Time Deterministic Theorem for LDA . . . . . . 225 10.6.7.7 Time Deterministic Theorem for ST . . . . . . . 225 10.6.7.8 Time Deterministic Theorem for JLT . . . . . . 225 10.6.7.9 Time Deterministic Theorem for JLE . . . . . . 226 10.6.7.10 Time Deterministic Theorem for JGT . . . . . . 226 10.6.7.11 Time Deterministic Theorem for JGE . . . . . . 226 10.6.7.12 Time Deterministic Theorem for JEQ . . . . . . 226 10.6.7.13 Time Deterministic Theorem for JNE . . . . . . 227 10.6.7.14 Proof of RMInstrTDetThm . . . . . . . . . . . . . 227 10.6.7.15 Proof of RMInstrTDetLem2 . . . . . . . . . . . . 228 10.6.7.16 Proof of RMTimeDetThm . . . . . . . . . . . . . . 231 10.6.7.17 Proof of RMTimeDetThm2 . . . . . . . . . . . . . 231 10.6.8 Proofs of ROTimeDetThm and ROTimeDetThm2 . . . . . . . 232

CONTENTS

xii

10.6.8.1 Theorem SCHROInstTDetThm . 10.6.8.2 Time Deterministic Lemma for 10.6.8.3 Proof of ScheduleBoolLem . . 10.6.8.4 Proof of ScheduleFunLem1 . . 10.6.8.5 Proof of ScheduleFunLem2 . . 10.6.8.6 Proof of SaveContxTDetLem . 10.6.8.7 Proof of SwitContxTDetLem . 10.6.8.8 Proof of SchedulVMTDetLem . 10.6.8.9 Proof of SchVMTimeDetLem1 . 10.6.8.10 Proof of SchVMTimeDetLem2 . 10.6.8.11 Proof of SchVMTDetLem21 . . . 10.6.8.12 Proof of SchVMTDetLem22 . . . 10.6.8.13 Proof of SchVMTDetLem221 . . 10.6.8.14 Proof of SchVMTDetLem222 . . 10.6.8.15 Proof of SchVMTDetLem23 . . . 10.6.8.16 Proof of SchVMTDetLem2 . . . 10.6.8.17 Proof of SchedulVMTDetLem . 10.6.8.18 Proof of ScheduleFunLem2 . . 10.6.8.19 Proof of SCHROInstTDetThm .

IV

. . . . . . . . . . Identity Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Epilogue

11 Related Works 11.1 KIT . . . . . . . . . . . . . . . . . . . . . . . . . 11.2 Formal Models of Operating System Kernels in Z 11.2.1 A Simple Kernel . . . . . . . . . . . . . . 11.2.2 A Swapping Kernel . . . . . . . . . . . . . 11.2.3 Messages Passing in the Swapping Kernel 11.2.4 Virtual Storage . . . . . . . . . . . . . . . 11.2.5 A Separation Kernel . . . . . . . . . . . . 11.3 Abstract Interrupt Machine . . . . . . . . . . . . 11.4 Idaho Partitioning Machine . . . . . . . . . . . .

232 232 232 233 233 234 234 235 236 237 237 239 240 240 241 242 243 243 244

245 . . . . . . . . and Object-Z . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . .

12 Conclusions 12.1 Formal Verification of Compilers and Operating Systems: The Same and Differences . . . . . . . . . . . . . . . . . . . . . . . . . 12.1.1 What You Want To Prove . . . . . . . . . . . . . . . . . . 12.1.2 The Complexity of Abstraction . . . . . . . . . . . . . . . 12.1.3 Termination and Nontermination Problem . . . . . . . . .

246 247 249 249 249 250 250 250 251 251 253 253 253 253 254

List of Figures

xiii

List of Tables 1.1

Common Criteria Evaluation Levels . . . . . . . . . . . . . . . .

4

11.1 OS Verification Projects . . . . . . . . . . . . . . . . . . . . . . . 247

1

Part I

Verification of Real-Time Operating Systems

2

Chapter 1

Introduction 1.1

Common Criteria

The Common Criteria are a standard for software verification that is mutually recognized by a large number of countries. There are seven levels of assurance (EAL 1-7) in the standard and a number of so-called protection profiles that detail what exactly is being certified and for which application area. The standard is used for example by government agencies to specify software assurance requirements in requisitions and regulations. Fig 1.1 shows a table with the assurance levels on the left, and software artifacts on the top. From left to right, the software artifacts are: the software requirements, for example a security property, the functional specification, the high-level design of the system, the low-level design, and finally the implementation. The bottom row of the table compares this with software that is fully formally verified. The highest Common Criteria evaluation level requires a formal treatments of requirements, functional specification and high-level design. The low-level design may be treated semi-formally and correspondence between implementation and low-level design is usually affirmed in an informal way. To call a piece of software fully formally verified, the verification chain should reach at least down to the level of implementation.

1.2

Software Specification

For our purposes, the software specification process occurs in four distinct phases. • Functional Specification. First we develop the functional specification driven by a set of user requirements. This consists of the functional model and a set of operations that the user will employ to manipulate the operational model. Again, the sole purpose of this set of specifications is to 3

Introduction

Common Criteria EAL 1 EAL 2 EAL 3 EAL 4 EAL 5 EAL 6 EAL 7 Verified

4

Requirements Informal Informal Informal Informal Formal Formal Formal Formal

Functional Specification Informal Informal Informal Informal Semiformal Semiformal Formal Formal

HLD

LLD

Implementation

Informal Informal Informal Informal Semiformal Semiformal Formal Formal

Informal Informal Informal Informal Informal Semiformal Semiformal Formal

Informal Informal Informal Informal Informal Informal Informal Formal

Table 1.1: Common Criteria Evaluation Levels

define a virtual system that can be manipulated by the user by a set of very well-defined operations. The functional mode, together with the set of operations, defines what the new system is to do. • High-Level Design Specification. The next step in the software specification process is intimately bound to the software design process. During this phase we map the functional model onto a specific high-level design model. We solve the problem of how the functional model works within the confines of a new virtual architecture. This high-level design model is manipulated by a set of functionalities. The high-level design model, together with its set of functionalities, constitutes our high-level design specification. • Low-Level Design Specification. The third step in the software specification process is the decomposition of functionalities into specific program modules. This is the low-level design process. Each module receives data from a set of modules from which it can potentially receive execution control. Through an algorithm specified in the module design, this data is transformed according to the dictates of the algorithm and made available to the module that transferred control to the current module. At this stage, we are concerned with the specifics of each datum and the transformations made on that datum. • Implementation. The final step in the specification process is to select a programming language model that we can use to implement the lowlevel design. We will not be able to modify these models; we must simply choose the least bad model from a repertoire of simply awful and inefficient language models to use in our application.

Introduction

1.3

5

Verification Technology

At present there are two main verification techniques in use: model checking and theorem proving.

1.3.1

Model Checking

Model checking works on a model of the system that is typically reduced to what is relevant to the specific properties of interest. The model checker then exhaustively explores the models reachable state space to determine whether the properties hold. This approach is only feasible for systems with a moderatelysized state space, which implies dramatic simplification. As a consequence, model checking is unsuitable for establishing a kernel’s full compliance with its API. Instead it is typically used to establish very specific safety or liveness properties. Furthermore, the formalization step from system to model is quite large, commonly done manually and therefore error prone. Hence, model checking usually does not give guarantees about the actual system. Model checking has been applied to the OS layer and has shown utility here as a means of bug discovery in code involving concurrency. However, claims of implementation verification are disputable due to the manual abstraction step. Tools like SLAM can operate directly on the kernel source code and automatically find safe approximations of system behavior. However, they can only verify relatively simple properties, such as the correct sequencing of operations on a mutex necessary but not sufficient for correct system behavior.

1.3.2

Theorem Proving

The theorem proving approach involves describing the intended properties of the system and its model in a formal logic, and then deriving a mathematical proof showing that the model satisfies these properties. The size of the state space is not a problem, as mathematical proofs can deal with large or even infinite state spaces. This makes theorem proving applicable to more complex models and full functional correctness. Contrary to model checking, theorem proving is usually not an automatic procedure, but requires human interaction. While modern theorem provers remove some of the tedium from the proof process by providing rewriting, decision procedures, automated search tactics, etc, it is ultimately the user who guides the proof, provides the structure, or comes up with a suitably strong induction statement. While this is often seen as a drawback of theorem proving, we consider it its greatest strength: It ensures that verification does not only tell you that a system is correct, but also why it is correct. Proofs are developed interactively with this technique but can be checked automatically for validity once derived, making the size and complexity of the proof irrelevant to soundness.

Introduction

1.3.3

6

Verifying Kernels

What do the models and specifications look like in kernel verification? Clearly a kernel needs to implement its API, so the specification is typically a formalization of this API. This is created by a manual process with a potential for misstatement, as APIs tend to be specified informally or at best semi-formally using natural languages, and are typically incomplete and sometimes inconsistent. It is then desirable to utilize a formalism such that the correspondence between the informal and formal specification is relatively easy to see even for OS developers who are no experts in formal methods. The kernel model is ideally the kernel executing on the hardware. In reality it is preferable to take advantage of the abstraction provided by the programming language in which the kernel is implemented, so the model becomes the kernel’s source-level implementation. This introduces a reliance on the correctness of the compiler and linker (in addition to the hardware, boot-loader and firmware). Some criticisms are commonly voiced when considering OS verification. Is there any point if we have to rely on compiler and hardware correctness? With source-level verification, compiler and hardware correctness have become orthogonal issues - when we have the required formal semantics for the language and hardware, verification of these system components can be attempted independently to that of the OS. Both hardware and compiler verification are currently active areas of research. It should be noted that the gap between formal model and implementation will always exist, even in the presence of a verified processor, since real hardware is a physical realization of some model and its correct operation is beyond the scope of formal verification - one cannot prove the absence of manufacturing defects for example. The aim of OS verification is to significantly reduce the larger gap between user requirements and implementation and hence gain increased confidence in system correctness. Even if the kernel is verified, what has been gained when user-level applications such as file-systems are not? In the first scenario described in the introduction, the question is really that of what do we need to verify to be able to claim the trusted applications are correct. The kernel provides the basic abstraction over the underlying hardware necessary to enforce the boundary between trusted and un-trusted applications and allows the behavior of un-trusted applications to be abstracted away or ignored when verifying the trusted code. Trusted applications may also have some redeeming characteristics when it comes to verification - they should be relatively small in a well-designed TCB and may take advantage of higher-level languages. For a hypervisor no additional work remains after OS verification - if the correct resource management and isolation is provided at the OS level then there is no possibility of faulty or malicious code executing in one partition from influencing or knowing about another. As becomes clear from the discussion above, a wide variety of systems and architectures can be implemented with microkernels. One topic of discussion

Introduction

7

in the OS community is whether a microkernel should provide a hardware abstraction layer (HAL) and hide hardware details, or simply provide a set of mechanisms to control the hardware and export underlying complexities to user space. The verification projects surveyed in the next section take different views on this topic which influences what the formal models look like and what properties are being proved.

1.4

Formal Verification of Microkernels

This section introduces the subject of the verification projects in this report: operating system microkernels.

1.4.1

Formal Verification

Formal verification is about producing strict mathematical proofs of the correctness of a system. But what does this mean? From the formal-methods point of view, it means that a formal model of the system behaves in a manner that is consistent with a formal specification of the requirements. This leaves a significant semantic gap between the formal verification and the user’s view of correctness. The user (e.g. application programmer) views the system as “correct” if the behavior of its object code on the target hardware is consistent with the user’s interpretation of the (usually informally specified) API. Bridging this semantic gap is called formalization.

1.4.2

Monolithic and Microkernels

By definition, the kernel of an operating system is the part of the software that runs in the privileged mode of the hardware. This privileged mode typically distinguishes itself from normal user mode by additional machine instructions and by write access to hardware registers and devices that are invisible or readonly in user mode, for instance the memory management unit (MMU) of the processor. Microkernels try to minimize the amount of code that runs in the privileged mode. There are many kinds of such small OS kernels. For the purposes of this survey, we restrict ourselves to kernels such as Mach, L4, and VAMOS that do not rely on co-operation from user mode processes to implement their services. This usually implies that the kernel at least manages the MMU and runs only on hardware that provides such a unit. The MMU can be used to implement virtual memory. It provides translation from virtual to physical addresses and other management functions like memory access rights (read/write/execute). If operated correctly, it can be used to protect kernel memory and memory of different user applications from each other.

Introduction

1.4.3

8

Architectures

Kernels are classified into two categories: traditional monolithic kernels such as Windows and Linux and the microkernels. 1.4.3.1

Monolithic Kernels

In a monolithic kernel, device drivers, system services like the file system, and even parts of the graphical user interface are part of the kernel and run in privileged mode. 1.4.3.2

Microkernels

In the microkernel approach, only the microkernel itself runs in privileged mode. It exports sufficiently powerful mechanisms to run system services and even low-level device drivers with the same degree of protection that is afforded to applications. 1.4.3.3

Advantages and Disadvantages of Microkernels

The microkernel approach has several advantages for system design and reliability. In a monolithic kernel, even an unimportant part of the kernel, e.g. a graphics card driver on a network server, has full access to all memory and all kernel data structures. A fault in such a driver can be exploited to fully undermine the whole system, be it maliciously or by accident. This is not a theoretical threat. In a microkernel on the other hand, such a driver would run in its own protection domain. An exploit in the driver would compromise only memory of that driver and will only deny service to those parts of the system that rely on it. For the normal operation of a network server for instance, the graphics driver is irrelevant and could be safely terminated and restarted. The main disadvantage of the microkernel approach was famously brought forward by Linus Torvalds in 1992: Performance. Creating these protection domains, switching between them for execution, and passing messages across domain boundaries was considered expensive overhead. This overhead would be incurred at the innermost, lowest level and therefore accumulate rapidly and unacceptably for all OS services. Providing roughly equal services, the main selling point of operating systems is performance, and the years that followed seemed to prove Torvalds right. Monolithic OS kernels not only persevered, but rose in popularity. More recently, however, it has been shown that the performance of microkernels can be improved to minimize this overhead down to the order of magnitude of a C procedure call. As becomes clear from the discussion above, a wide variety of systems and architectures can be implemented with microkernels. One topic of discussion

Introduction

9

in the OS community is whether a microkernel should provide a hardware abstraction layer (HAL) and hide hardware details, or simply provide a set of mechanisms to control the hardware and export underlying complexities to user space. The verification projects surveyed in the next section take different views on this topic which influences what the formal models look like and what properties are being proved. 1.4.3.4

Basic Services in Microkernels

HAL or not, all microkernels used in these verification projects provide at least the following services: • Threads. Threads are an abstraction from the CPU, in effect allowing multiple programs to share a single CPU and provide the illusion of parallel execution. Typical operations on threads are starting and stopping execution, managing scheduling parameters or inspecting and possibly modifying the execution state of a thread. • IPC. IPC stands for inter process communication. This communication can be synchronous (communication partners have to rendezvous and be ready at the same time) or asynchronous (which usually involves some form of buffering or potential message loss). IPC is the central mechanism for transferring information across protection boundaries. • Virtual Memory. As mentioned above, protection domains are usually implemented using MMU hardware mechanisms. The kernel can either fully manage the MMU or just export sufficient mechanisms and resource arbitration to user space for implementing specific virtual memory policies there. In the latter case, the mechanism needs to be hardened against malicious use from user space. The typical implementation size of a microkernel is on the order of 10,000 lines of C code. The kernels differ in which additional services they provide and how access to shared resources such as interrupts and devices is managed. We will go into more detail where necessary in later sections when we look at specific verification projects.

1.4.4

Services and Policies

The usage scenarios and consequently the services and mechanisms the kernels are optimized to provide are as diverse as the microkernels themselves.Without attempting to create a full taxonomy of microkernels, we can divide them into kernels intended to support general-purpose operating systems and kernels that are optimized for smaller, embedded systems. The emphasis in the former case is often on abstraction and flexibility, such as the ability to dynamically reconfigure possibly hierarchical security policies and protection domains. The

Introduction

10

emphasis for embedded systems on the other hand is often on small memory footprint, short interrupt latencies, real-time capabilities and strong isolation guarantees. There are also systems that cater to both areas. The most complex end of the scale tend to be general-purpose kernels. The least complex end of the scale usually are specific-purpose embedded systems kernels. An example would be an extremely simple separation kernel whose only purpose is to multiplex hardware into a fixed number of partitions without any communication between them. These kernels would not even provide the IPC service mentioned above. Allowing controlled communication would be the next step up; allowing communication channels to be changed during runtime would further increase complexity. Allowing to adjust protection domains at runtime, or to create new protection domains at runtime increases complexity again, until we arrive at a fully dynamic system where communication, CPU, or memory access cannot only be changed dynamically, but the authority to do so can also be safely delegated to subsystems. 1.4.4.1

Functional Specifications of Microkernels

Functional specifications of microkernels usually consider at least two levels. • The first level concerns all the services the kernel provides, and their formalization. In order to be useful and general enough, this kind of specification needs to be fairly detailed and describe precisely which actions the kernel can perform and what their effect is. • The second, more abstract level concerns a specific purpose important for the kernel. For microkernels, these tend to be security and isolation properties. If the system can be reduced to its security aspects only, the specifications involved become much smaller, more abstract and easier to reason about. In the following, we concentrate on security-related properties that make interesting targets for formal verification. 1.4.4.2

Access Control and Data Separation

A classic target for verification is access control. One purpose of the kernel will be to arbitrate and restrict access to shared resources such as memory, devices and CPUs. There is a whole host of different abstract access control models that kernels can implement and that could be used as a top-level specification. Examples are capability models or the Bell-La Padula model. In the first, access to a resource is granted only on presentation of a sufficiently authorized capability to that resource. A capability is basically a set of access rights together with a reference to a specific resource. Capability systems allow very fine-grained access control.

Introduction

11

Security-critical systems often require mandatory access control. This means that the kernel enforces a security policy via its access control method and does not rely on good behavior of processes and users not to circumvent the policy. Mandatory access control is used to implement system-wide security policies, for example stating that files with classification level top-secret have to remain protected. In contrast to that, discretionary access control allows users to make policy decisions themselves and for instance grant read access to everyone; an example is the standard Unix file system model. Access control can be used to achieve data separation between processes. Data separation means that no process is allowed access to memory of other processes, be it by accident or malicious intent. Because they are easy to formalize and already provide strong security implications, access control models are the most popular specification target for the verification projects surveyed below. 1.4.4.3

Information Flow

A stronger property is control of information flows. Formally, it is hard to define what information flow is, and there currently is still no universally accepted definition. Information flow properties are usually about secrecy: Process A stores a secret cryptographic key, and no other process should be able to infer what that key is. The information is not allowed to flow outside process A. Pure access control models are not strong enough to establish this property. They will prohibit direct access to the memory storing the key, and might also prohibit explicit communication channels, but there might be indirect means of inferring what the key is. One of the most challenging scenarios is collaboration between security levels to break system policies. For example, top-secret process A might be controlled by a spy in the organization, and unclassified process B might be the means to send the information outside. In this case, so-called covert channels need to be considered: process A could for instance use up its full time slice for transmitting a 1-bit and otherwise donate its remaining time slice. All B needs to observe is if more than its allocated time is available for computation. If yes, then A has transferred information. Of course, one can devise mechanisms against this specific attack, but the game becomes one of guessing the attack and guarding against it. Creating a new attack merely requires looking at the model and choosing something that is below its level of abstraction or that is otherwise not covered. The above example is a timing channel attack; it would not work against a kernel providing strict temporal separation, such that no thread can influence the scheduling and computing time available to other threads. Other attacks include observing CPU temperature, memory bus congestion, or cache misses. Known attacks against smart cards go as far as using radiation or heat to introduce memory faults into a computation, using an electron microscope to look at the chip in operation, etc. Modern high-security smart

Introduction

12

cards have physical tamper-proof devices against such attacks. It is unclear how far software alone can guard against them. 1.4.4.4

Non-Interference

More well-defined than general information flow is the property of noninterference. This property is able to capture indirect information flows in a model if the code for both sides is known. Given a secret process S and an attacker A, it requires one to prove that the behavior of A cannot depend on the actions of S, i.e. that S does not interfere with the behavior of A. It is possible to establish this property by looking at execution traces of the system: Given a trace where execution of both S and A occurs, one needs to show that the result in A is the same when all S actions are removed from the trace. Unfortunately, this property is not necessarily preserved by the proof technique of refinement which is the one most commonly used to relate an implementation to its model. This means that proving non-interference of the model only implies non-interference of the implementation when special care is taken in the implementation proof. The standard access control models do not have this problem. 1.4.4.5

Common Criteria

The Common Criteria have a protection profile geared towards separation kernels which are close to the services micro-kernels provide. The properties considered important for this class of kernels are: • Non-By-Passable, • Evaluatable, • Always Invoked, • Tamper Proof (NEAT). They are designed to be able to build systems with multiple independent levels of security (MILS), i.e. systems with components of different trust and assurance levels. • Non-By-Passable: In this context, non-by-passable means that the communication channels provided by the kernel are the only ones available to components and that there are no lower-level mechanisms that could be used for communication. • Evaluatable: Evaluatable means that the system must be designed such that an in-depth evaluation, including a fully formal evaluation if required, is possible. This restricts the size, complexity, and design of such systems.

Introduction

13

• Always Invoked: The term always invoked means that the access control methods of the kernel must be used every time a resource is accessed, not for instance just the first time a resource is requested. • Tamper Proof: Finally, tamper proof means that the access control system cannot be subverted, e.g. access rights be changed against the security policy by exploiting a loophole in the mechanism. These concepts, although intuitive, are not necessarily easy to formalize and prove directly. However, they can be established with reasonable effort by inspecting high-level formal models of the system. In this case it is important that the proof method used to relate the high-level model to code preserves these properties down to the code level. Because of their small size, the small number of services they provide, and their critical nature, micro-kernels offer a high-yield target for pervasive formal verification. The next section surveys the state of the art and the progress of current micro-kernel verification projects.

1.5

The Contribution of This Book

Our analysis will be conducted by development of an operating system machine for a hypervisor technology based virtual machine monitor (VMM) called SVMK (standing for Systematic Virtual Machine Kernel). The reason to do so is that we found out that it is almost impossible to give a formal semantic model for interruption mechanism in high-level language-based model. In order to handling interruptions, we have to deal with instructions directly. The work was started by designing a simple RISC machine and then extended by making all the operating system primitives which are non-interruptable as the machine instructions. So we may give another name to the book - “Operating System as an Extended Machine”.

Chapter 2

Type Theory and PowerEpsilon 2.1

PowerEpsilon

PowerEpsilon, [ZW91, ZW92, ZW93b, ZW93a], is a strongly-typed polymorphic functional programming language based on Martin-L¨of’s type theory [ML84] and the Calculus of Constructions [CH88]. In PowerEpsilon, the concept of limit of type universe hierarchies (Kind) and a scheme for inductive defined types are introduced. The system can be used as both a programming language with a very rich set of data structures and a meta-language for formalizing constructive mathematics. The system has been implemented using the software development system AUTOSTAR constructed by author [Zhu89]. PowerEpsilon is a proof checker much similar to other mechanical proof checkers, such as LCF [GMW79] and Nuprl [Cea86], which are completely formal user-controlled systems. However, PowerEpsilon is more powerful than LCF and Nuprl, in which the equality and induction rules for arbitrary inductive types are definable. One of the main reasons for using type theory for programming is that it is a theory both for writing specifications and constructing programs. In type theory, a specification is expressed by a type and an element of that type is a program that satisfies the specification. We hope that this system will be useful for future development of programming environments, where programs will be developed consistently with logical propositions expressing in one unified formalism – types. PowerEpsilon, as we have claimed, can be used as both a programming language with a very rich set of data structures and a proof development system. PowerEpsilon can be classified into two categories: the core of the language – PowerEpsilon/Logic and a various of extension of PowerEpsilon

14

Type Theory and PowerEpsilon

15

– PowerEpsilon/Computation. In PowerEpsilon/Logic, functions cannot be defined with both dec and def constructs. In the other word, if a function is declared with dec construct, it cannot be defined with def construct again. However, in PowerEpsilon/Computation, functions can be defined with both dec and def constructs. It means that a restricted set of fixed-point operators are definable within PowerEpsilon.

2.2

Notations

For technical reasons the following notations are used in PowerEpsilon: • ! : for the universal quantifier ∀. • ? : for the existential quantifier ∃. • \ : for the λ-abstraction quantifier λ.

2.3

Lexicon

Since the limited usage of computer character set (ASCII codes only), we can use a variety of letters, both lowercase (a, b, . . . ), uppercase (A, B, . . . ), and even digits (0, 1, 2, . . . ). However, subscript and superscript letters, and Greek letters usually used in mathematics are not allowed. Comments are enclosed in between % and %.

2.4

Syntax

A program written in PowerEpsilon is a theory with an optional query part: program ::= theory {query} theory ::= theory identifier is {import} term decl list end; query ::= query import term list end; A theory is a syntactic unit in PowerEpsilon, which has no semantic meaning at all; the only role played is to syntactically wrap a set of closely related terms (propositions and proofs) into one package. The purpose of introduction of

Type Theory and PowerEpsilon

16

‘theory’ is to make it easy to manage the proof environment for PowerEpsilon. For instance, Nat is a theory that wraps all the propositions and functions for specifying properties of natural numbers. The query part describes the expressions to be evaluated. Terms in a theory or query may be dependent on other theories. This dependency is specified by a import clause. import ::= import ident list ident list ::= identifier {, identifier}∗ The main part of a theory is a sequence of term declarations. A term declaration is either a term specification or a term definition. A term specification specifies the type of a term. The specification of a term is optional. In the absence of such a specification, the term definition acts as the specification. There is a type inference system which can derive the specification of a term from its definition. If both a specification and a definition for a term are given, the term definition must conform to the term specification. term term term term

decl list ::= term decl {; term decl}∗ decl ::= term dec | term def dec ::= dec identifier : term def ::= def identifier = term

The dec-construct is used for variable declaration and the def-construct is used for variable definition. Similar to the programming languages such as Pascal and Ada, an identifier f must be declared before using it. The basic expressions of PowerEpsilon, called terms, are defined as follows: term ::= identifier | Prop | Type(natural) | Kind | (term) | !(identifier : term {, identifier : term}∗ ) term | ?(identifier : term {, identifier : term}∗ ) term | \(identifier : term {, identifier : term}∗ ) term | [term -> term {-> term}∗ ] | @(term, term {, term}∗ ) | | let identifier = term in term | lec identifier : term in term

2.4.1

Variables

There are two kind of variables: identifiers and meta-variables. An identifier is a string of letters or digits beginning with a letter. A meta-variable is an

Type Theory and PowerEpsilon

17

identifier beginning with a character “*”. The meta-variables are specially used for defining inductively defined types.

2.4.2

Prop, Type(i), and Kind

An object T of type Prop defines a proposition. A proposition P has the type Type(0); Type(0) has the type Type(1); and so on. This forms a type hierarchy of the type system. The Kind can be used to define a generic type object as: def KT = \(T : Kind) [T -> Prop]; def KT0 = @(KT, Type(0));

2.4.3

Π-Formulas

The term !(x : A) B is usually called Π-formula which represents an universal qualified predicate. It can be read as ‘for every x of type A, the proposition B is true’. For instance, we may have the following predicate !(x : Bird) @(Can Fly, x), read as “for every bird x, x can fly”. The logical formulas in PowerEpsilon can be represented more abstractly in the sense that the type and logical formula can also be used as parameters inside of the formula, for instance, we may define the following logical formula: def Pi Form = !(T : Prop, P : [T -> Prop]) !(x : T) @(P, x), which can be instantiated as @(Pi Form, Bird, Can fly).

2.4.4

Σ-Formulas

The term ?(x : A) B is usually called Σ-formula which represents an existential qualified predicate. It can be read as ‘for some x of type A, the proposition B is true’. For instance, we may define the following predicate ?(x : Man) @(Is Married, x), read as “there is a number of men x, x is married”.

2.4.5

λ-Abstractions

Functions in PowerEpsilon is defined by λ-abstraction in forms of \(x : A) e, where x is the formal parameter and A is type of x and e is the body of function. There is a relationship between λ-abstraction and Π-formula. The type of function definition \(x : A) b is !(x : A) B, if within the context of x : A, we can infer that b : B.

Type Theory and PowerEpsilon

2.4.6

18

Implication-Formula

Computationally the formula [A -> B] specifies a function which maps type A to B. Logically the formula [A -> B] can be read as “A infers B”.

2.4.7

Function Application

The function application is represented as @(f, e), where the symbol @ may be read as “applying”. For instance, if we have a function f defined as def f = \(x : T) b; and we also have e of type T, we then will obtain @(f, e) = d, where d is obtained by substituting all of the occurrences of x by e.

2.4.8

Pair

The term represents a proof object of logical formula ?(x : A) B, if a has a type A, and b has a type D and B is obtained by replacing all occurrences of a in D by x. For example, if we have a : Man and b : @(Is Married, a), then we will be able to obtain : ?(x : Man) @(Is Married, x).

2.4.9

Let-Expression

The term of form let x = e in @(b, x) is a sugared PowerEpsilon expression which may be rewritten as @(\(x : A) @(b, x), e). Use of letconstruct can sometimes shorten expressions and highlight essential aspects of their structure. One can also use let-construct for ‘subsidiary’ functions, for example let f = \(x : Nat) @(TIMES, x, x) in @(ADD, @(f, ONE), @(f, TWO)); which means @(ADD, @(\(x : Nat) @(TIMES, x, x), ONE), @(\(x : Nat) @(TIMES, x, x), TWO));

2.4.10

Lec-Formula

The term of form lec x : T in @(S, x) is a formula declaring a local context inside of @(S, x). This construct can be used for defining a local recursive function. For example, we may define the following PowerEpsilon expression:

Type Theory and PowerEpsilon

19

\(e : A) lec f : [A -> A] in let f = \(x : A) @(f, x) in @(f, e); Since f is recursively defined in this expression, we must declare it before.

2.5

Examples

In this section we present some examples showing the expressive power of PowerEpsilon. Since PowerEpsilon is a purely symbolic language all of the mathematical objects can be built with it.

2.5.1

Boolean

In most programming languages, Boolean is a basic built-in data type for constructing more complicated data structures and functions. In PowerEpsilon, however, Boolean can be defined as follows: theory Bool is %-- Definition of Bool --% def Bool = !(T : Prop) [T -> T -> T]; %-- Function definitions for Bool --% %-- Constructors --% def TT = \(T : Prop, x : T, y : T) x; def FF = \(T : Prop, x : T, y : T) y; %-- Canonical functions --% def NOT = \(t : Bool) @(t, Bool, FF, TT); def AND = \(t1 : Bool, t2 : Bool) @(t2, Bool, @(t1, Bool, TT, FF), FF); def OR = \(t1 : Bool, t2 : Bool) @(t2, Bool, TT, @(t1, Bool, TT, FF)); def IMPLY = \(t1 : Bool, t2 : Bool) @(OR, @(NOT, t1), t2); def GIF_THEN_ELSE = \(U : Prop, t : Bool, u : U, v : U) @(t, U, u, v)

Type Theory and PowerEpsilon

20

end;

where TT and FF are the functions for Bool introduction and GIF THEN ELSE is the function for Bool elimination. The function @(GIF THEN ELSE, T, b, UU, VV) is a conditional function like if-then-else construct in most conventional programming languages which will select one of the two subcomponents UU and VV for execution, depending on the input Boolean value. For example, we will have @(GIF THEN ELSE, T, TT, UU, VV) −→ UU and @(GIF THEN ELSE, T, FF, UU, VV) −→ VV Other enumeration data types can be specified in a very similar way.

2.5.2

Natural Numbers

Let us present a definition for natural number and few functions over naturals. theory Nat is import Bool def BIF_THEN_ELSE

= @(GIF_THEN_ELSE, Bool);

%-- Definition of Nat --% def Nat = !(Ti : Prop) [Ti -> [Ti -> Ti] -> Ti]; dec ERR : [Nat -> Nat]; dec dec dec dec

PP EQUAL LESS MINUS

: : : :

[Nat [Nat [Nat [Nat

-> -> -> ->

Nat]; Nat -> Bool]; Nat -> Bool]; Nat -> Nat];

def NIF_THEN_ELSE = @(GIF_THEN_ELSE, Nat); %-- Function definitions for Nat --% %-- Constructors --% def OO = \(Ti : Prop, x : Ti, y : [Ti -> Ti]) x; def SS = \(t : Nat, Ti : Prop, x : Ti, y : [Ti -> Ti]) @(y, @(t, Ti, x, y)); %-- Canonical functions --%

Type Theory and PowerEpsilon

def def def def

IS_ZERO = \(n : Nat) @(n, Bool, TT, \(x : Bool) FF); ADD = \(n1 : Nat, n2 : Nat) @(n2, Nat, n1, SS); TIMES = \(n1 : Nat, n2 : Nat) @(n2, Nat, OO, @(ADD, n1)); EXP = \(n1 : Nat, n2 : Nat) @(n2, Nat, @(SS, OO), @(TIMES, n1));

def T = \(x : Nat, y : Nat) x; def F = \(x : Nat, y : Nat) y; def PP = \(n : Nat) @(n, [[Nat -> Nat -> Nat] -> Nat], \(u : [Nat -> Nat -> Nat]) @(u, OO, OO), \(p : [[Nat -> Nat -> Nat] -> Nat], v : [Nat -> Nat -> Nat]) @(v, @(SS, @(p, T)), @(p, T)), F); def MINUS = \(n1 : Nat, n2 : Nat) @(NIF_THEN_ELSE, @(LESS, n1, n2), @(ERR, n1), @(NIF_THEN_ELSE, @(IS_ZERO, n2), n1, @(MINUS, @(PP, n1), @(PP, n2)))); def EQUAL = \(n1 : Nat, n2 : Nat) @(BIF_THEN_ELSE, @(IS_ZERO, n1), @(IS_ZERO, n2), @(BIF_THEN_ELSE, @(IS_ZERO, n2), FF, @(EQUAL, @(PP, n1), @(PP, n2)))); def LESS = \(n1 : Nat, n2 : Nat) @(BIF_THEN_ELSE, @(EQUAL, n1, n2), FF, @(BIF_THEN_ELSE, @(IS_ZERO, n1), TT, @(BIF_THEN_ELSE,

21

Type Theory and PowerEpsilon

22

@(IS_ZERO, n2), FF, @(LESS, @(PP, n1), @(PP, n2))))); dec REC : !(A : Prop) [Nat -> A -> [Nat -> A -> A] -> A]; def REC = \(A : Prop) \(n : Nat, a : A, f : [Nat -> A -> A]) @(GIF_THEN_ELSE, A, @(IS_ZERO, n), a, @(f, n, @(REC, A, @(PP, n), a, f))) end;

where IS ZERO is a Boolean function to check whether a given natural number is zero or not. EQUAL is a Boolean function to check whether two given natural numbers are equal or not. PP is a predecessor function for any given natural numbers. We may see that natural numbers are polymorphic iterators. The addition function ADD is obtained by iterating successor SS; the multiplication function TIMES is obtained by iterating ADD; similarly, the exponentiation function EXP is obtained by iterating TIMES. The REC is a recursive operator. Iterating a natural on a functional type may produce non-primitive recursive functions; for example, we can get Ackermann’s function by the following definition: def ACK = \(n : Nat) @(n, [Nat -> Nat], SS, \(f : [Nat -> Nat]) \(m : Nat) @(m, Nat, m, f));

It is interesting to see the type Nat as expression the proposition “there are natural numbers”, which has the constructive proofs OO, @(SS, OO), @(SS, @(SS, OO)), . . . . The basic way of proving that a proposition holds for all natural numbers is by mathematical induction: from @(P, OO) and that @(P, n) implies @(P, @(SS, n)) we may conclude that @(P, n) holds for all natural numbers n. In order to be able to prove properties by induction on natural numbers in type theory, we introduce the formation Rec. From a computational point of view, Rec makes it possible to make definitions by primitive recursion. An inductive type over Nat can be defined as follows: theory Recnat is import Bool, Nat dec Rec :

Type Theory and PowerEpsilon

23

!(P : [Nat -> Prop]) [@(P, OO) -> !(u : Nat) [@(P, u) -> @(P, @(SS, u))] -> !(n : Nat) @(P, n)]; def Rec = \(P : [Nat -> Prop]) \(a : @(P, OO)) \(f : !(u : Nat) [@(P, u) -> @(P, @(SS, u))]) \(*n : Nat) @(GIF_THEN_ELSE, @(P, *n), @(IS_ZERO, *n), a, @(f, @(PP, *n), @(Rec, P, a, f, @(PP, *n)))); end;

2.5.3

List

For any type A, an important type built from it are lists of elements from A. The type is denoted in terms of PowerEpsilon @(List, A). All nonempty lists are built from the empty list which is denoted by NIL. If a is an element of A, then @(CONS, a, NIL) is a nonempty list. In general given a list t and an element h of A, @(CONS, h, t) is a list with h as its head and t as its tail. One important kind of construction arise from the inductive nature of lists. We can build an object incrementally from the elements of a list following the same pattern used to build the list. That is , a list starts from the empty list NIL. Suppose that corresponding to it we can specify some object, such as the natural number OO. Given a list t, we extend it by adjoining an element h to form @(CONS, h, t). In the same way, given a value associated with t, say its length v, we can build a value associated with @(CONS, h, t) incrementally, say by adding one to v, thereby associating @(SS, OO) to @(CONS, h, t). This process of associating a value with a list is sometimes called primitive recursion on lists or list recursion or list induction. The critical components in this definition are expression a for the value in the base case and an expression b for the value in the inductive base. We can use a linear format to present this definition: theory List is import Bool dec Uu : Prop; dec Aa : Prop; def BIF_THEN_ELSE

= @(GIF_THEN_ELSE, Bool);

Type Theory and PowerEpsilon

dec EQUAL : [Uu -> Uu -> Bool]; %-- Definition of List --% def List = !(Ti : Prop) [Ti -> [Uu -> Ti -> Ti] -> Ti]; dec ERR : Uu; dec ITM : Uu; dec LST : List; %-- Function declarations for List --% dec LISTREC : [List -> List -> [Uu -> List -> List -> List] -> List]; dec LEQUAL : [List -> List -> Bool]; def LIF_THEN_ELSE = @(GIF_THEN_ELSE, List); %-- Function definitions for List --% def NIL = \(Ti : Prop, x : Ti, y : [Uu -> Ti -> Ti]) x; def CONS = \(w : Uu, t : List) \(Ti : Prop, x : Ti, y : [Uu -> Ti -> Ti]) @(y, w, @(t, Ti, x, y)); def T = \(x : List, y : List) x; def F = \(x : List, y : List) y; def HEAD = \(s : List) @(s, Uu, ERR, \(u : Uu, v : Uu) u); def TAIL = \(n : List) @(n, [[List -> List -> List] -> List], \(u : [List -> List -> List]) @(u, NIL, NIL), \(e : Uu, p : [[List -> List -> List] -> List], v : [List -> List -> List]) @(v, @(CONS, e, @(p, T)), @(p, T)), F); def IS_EMPTY = \(s : List) @(s, Bool, TT, \(u : Uu, v : Bool) FF); def IS_IN_LIST = \(e : Uu, s : List)

24

Type Theory and PowerEpsilon

@(s, Bool, FF, \(u : Uu, v : Bool) @(BIF_THEN_ELSE, @(EQUAL, u, e), TT, v)); def EQUAL = \(s1 : List, s2 : List) @(BIF_THEN_ELSE, @(AND, @(IS_EMPTY, s1), @(IS_EMPTY, s2)), TT, @(BIF_THEN_ELSE, @(OR, @(IS_EMPTY, s1), @(IS_EMPTY, s2)), FF, @(s1, Bool, TT, \(u1 : Uu, v1 : Bool) @(BIF_THEN_ELSE, @(IS_IN_LIST, u1, s2), v1, FF)))); def CONCAT = \(s1 : List, s2 : List) @(s2, List, s1, \(u : Uu, v : List) @(CONS, u, v)); def LISTREC = \(l : List, a : List, b : [Uu -> List -> List -> List]) @(l, List, a, \(u : Uu, v : List) @(b, @(HEAD, l), @(TAIL, l), @(LISTREC, @(TAIL, l), a, b))); dec Rec : !(P : [List -> Prop]) [@(P, NIL) -> !(a : Uu, u : List) [@(P, u) -> @(P, @(CONS, a, u))] -> !(*n : List) @(P, *n)]; def Rec = \(P : [List -> Prop]) \(a : @(P, NIL)) \(f : !(x : Uu, u : List) [@(P, u) -> @(P, @(CONS, x, u))]) \(*n : List) @(GIF_THEN_ELSE, @(P, *n), @(LEQUAL, *n, NIL), a, @(f, @(HEAD, *n), @(TAIL, *n), @(Rec, P, a, f, @(TAIL, *n))))

25

Type Theory and PowerEpsilon

26

end;

where given a list l, HEAD and TAIL are two functions to take its first and second components respectively; IS EMPTY is a Boolean function to check whether a given list l is empty or not; IS IN LIST is a Boolean function to check whether for a given list l and an element x, x is in l or not; CONCAT is a function concatenate two lists l1 and l2 into one; LEQUAL is a Boolean function to check whether two given lists l1 and l2 are equal or not. LISTREC is a recursive function on List. Rec is an inductive type defined on Prop and Rec0 is an inductive type defined on Type(0) for List. Similarly, we may define Rec1, Rec2, . . . , and so on. The abstract data type List can be parameterized by taking the type of elements as a parameter. theory List is import Bool dec Aa : Prop; def BIF_THEN_ELSE = @(GIF_THEN_ELSE, Bool); %-- Definition of List --% def List = \(Uu : Prop) !(Ti : Prop) [Ti -> [Uu -> Ti -> Ti] -> Ti]; dec LERR : !(Uu : Prop) Uu; dec UEQUAL : !(Uu : Prop) [Uu -> Uu -> Bool]; dec HEAD : !(Uu : Prop) [@(List, Uu) -> Uu]; dec TAIL : !(Uu : Prop) [@(List, Uu) -> @(List, Uu)]; dec LISTREC : !(Uu : Prop) [@(List, Uu) -> Aa -> [Uu -> @(List, Uu) -> Aa -> Aa] -> Aa]; %-- Function definitions for List --% def NIL = \(Uu : Prop) \(Ti : Prop, x : Ti, y : [Uu -> Ti -> Ti]) x; def CONS = \(Uu : Prop) \(w : Uu, t : @(List, Uu))

Type Theory and PowerEpsilon

\(Ti : Prop, x : Ti, y : [Uu -> Ti -> Ti]) @(y, w, @(t, Ti, x, y)); def HEAD = \(Uu : Prop, l : @(List, Uu)) @(l, Uu, @(LERR, Uu), \(u : Uu, v : Uu) u); def IS_EMPTY = \(Uu : Prop, s : @(List, Uu)) @(s, Bool, TT, \(u : Uu, v : Bool) FF); def IS_IN_LIST = \(Uu : Prop, e : Uu, s : @(List, Uu)) @(s, Bool, FF, \(u : Uu, v : Bool) @(BIF_THEN_ELSE, @(UEQUAL, Uu, u, e), TT, v)); def UEQUAL = \(Uu : Prop, s1 : @(List, Uu), s2 : @(List, Uu)) @(BIF_THEN_ELSE, @(AND, @(IS_EMPTY, Uu, s1), @(IS_EMPTY, Uu, s2)), TT, @(BIF_THEN_ELSE, @(OR, @(IS_EMPTY, Uu, s1), @(IS_EMPTY, Uu, s2)), FF, @(s1, Bool, TT, \(u1 : Uu, v1 : Bool) @(BIF_THEN_ELSE, @(IS_IN_LIST, Uu, u1, s2), v1, FF)))); def CONCAT = \(Uu : Prop, s1 : @(List, Uu), s2 : @(List, Uu)) @(s2, @(List, Uu), s1, \(u : Uu, v : @(List, Uu)) @(CONS, Uu, u, v)); def LISTREC = \(Uu : Prop, l : @(List, Uu), a : Aa, b : [Uu -> @(List, Uu) -> Aa -> Aa]) @(l, Aa,

27

Type Theory and PowerEpsilon

28

a, \(u : Uu, v : Aa) @(b, @(HEAD, Uu, l), @(TAIL, Uu, l), @(LISTREC, Uu, @(TAIL, Uu, l), a, b))) end;

2.6 2.6.1

Currying and Higher-Order Terms Higher-Order Functions

The function definition like \(x : A) \(y : B) x is a λ-expression which denotes a higher-order function. Higher-order functions are functions whose source and target contains functions. Thus \(x : A) \(y : B) x has a type of the form [A -> [B -> A]] and so the result of applying \(x : A) \(y : B) x to an argument, a say, is a member [B -> A] (\(y : B) x exact), i.e., a function. Another example of a higher-order function is dec TWICE : [[Nat -> Nat] -> [Nat -> Nat]]; defined by def TWICE = \(f : [Nat -> Nat]) \(x : Nat) @(f, @(f, x)); So @(TWICE, f) is a function which does f twice, for example, @(TWICE, \(n : Nat) @(ADD, n, ONE)) is a function which applies @(ADD, n, ONE) twice – i.e. adds 1 twice – i.e. adds 2. Higher-order functions are very useful and we shall frequently use them. Moreover, higher-order functions are perfectly ordinary and everything we say about functions in general applies to them also. The reason why we singled them out for discussion is because in many programming languages (for example Algol 60 and Pascal) ‘functions’ (as opposed to mathematical functions) are subject to various constraints. For example in neither Algol 60 nor Pascal can ‘functions’ return ‘functions’ as results (so TWICE could not be programmed). These constarints are to enable efficient implementations of the languages and do not reflect anything inherent in the concept of a function. Indeed other (less efficient) languages like LISP or POP-2 allow the unrestricted programming

Type Theory and PowerEpsilon

29

of higher-order ‘functions’.

2.6.2

Currying and Uncurrying

PowerEpsilon is a higher-order language – functions types are first class citizens and can be both passed as parameters and return as results. Function application is left-associative, so when we write @(f, x, y) it is passed as @(@(f, x), y), meaning that the result of applying f to x is a function, which is then applied to y. Functions of more than one argument which take them “one at a time” like f are called currying. The curring form of λ-expressions provides some flexibility which is important for writing easily understood programs. For example, \(x1 : A1 ) (\(x2 : A2 ) · · · (\(xn : An )M ) · · ·) can be written \(x1 : A1 ) \(x2 : A2 ) · · · \(xn : An )M, or further simplified to \(x1 : A1 , x2 : A2 , · · · , xn : An )M. !-terms and ?-terms are treated similarly. In addition, the following terms [A1 −> A2 −> · · · −> An−1 −> An ] @(A1 , A2 , A3 , ; · · · , An ) < A1 , A2 , · · · , An−1 , An > are respectively abbreviations for [A1 −> [A2 −> · · · [An−1 −> An ] · · · ; ]] @(· · · @(@(A1 , A2 ), A3 ), · · · , An ) < A1 , < A2 , · · · < An−1 , An > · · · >> Unlike function application which is left-associative, all of other constructs are right-associative. The dec and def constructs are sugared λ-expressions which can be decoded as an explicit on-line form of λ-expression. For instance, if a sequence of defconstructs are given as follows: def S = \(T : Prop) \(x : [T -> T -> T], y : [T -> T], z : T) @(x, z, @(y, z)); def K = \(T : Prop) \(x : T, y : T) x;

Type Theory and PowerEpsilon

30

def I = \(T : Prop) \(x : T) x; ...... These λ-expressions can be decoded as \(S : \(T : Prop) \(x : [T -> T -> T], y : [T -> T], z : T) @(x, z, @(y, z))) \(K : \(T : Prop) \(x : T, y : T) x) \(I : \(T : Prop) \(x : T) x) ...... In PowerEpsilon, expressions and types have same forms of representation, for example, the term \(x : T) E can be interpreted as either an expression or a type depending on the role played by that term in context. Current version of PowerEpsilon has neither built-in functions nor built-in types. Everything must be constructed from bottom. The recursive functions can be defined using both dec and def constructs. For instance, we might define a factorial function FACT as dec FACT : [Nat -> Nat]; def FACT = \(n : Nat) @(GIF_THEN_ELSE, Nat, @(IS_ZERO, n), ONE, @(TIMES, n, @(FACT, @(PP, n))));

2.6.3

Generic Functions

Functions like GIF THEN ELSE which strictly speaking, are collections of functions, one for each domain of an appropriate type, are called generic. The actual functions which make up the collections of functions are called instances; thus @(GIF THEN ELSE, Bool) and @(GIF THEN ELSE, Nat), are instances of GIF THEN ELSE. The expressions which describe the types of the instances of generic functions are called generic types.

Type Theory and PowerEpsilon

2.7 2.7.1

31

Mathematical Logic in PowerEpsilon Null Type

The Null type corresponding to logical value false can be defined in terms of PowerEpsilon as Null = !(A : TYPE) A. Since Null has no proof at all. theory Null is def Null = !(T : Prop) T end;

2.7.2

Trivial Type

Just as the false proposition ‘falsity’ (which should not be confused with the object FF of type Bool) was represented by the type Null, so the true proposition is represented by the one-element type Triv. Why one element? The intuition is that the proposition is valid for obvious reasons, so there is only one trivial proof TRIV of it. theory Trivial is def Triv = !(T : Prop) [T -> T]; def TRIV = \(T : Prop, t : T) t end;

2.7.3

Π-Type

Universal quantification, or general product, or Π-type, can be defined by a generalization of binary product Pi, where the Π-introduction, i.e. universal generalization, is proved by abstraction GEN and the Π-elimination is proved by instantiation INST, i.e. application. theory Pi is def Pi = \(T : Kind, Ai : T, Pp : [Ai -> Prop]) !(x : Ai) @(Pp, x); def GEN = \(T : Kind, Ai : T, Pp : [Ai -> Prop], Bi : T) \(f : !(x : Ai) [Bi -> @(Pp, x)]) \(y : Bi, x : Ai)

Type Theory and PowerEpsilon

32

@(f, x, y); def INST = \(T : Kind, Ai : T, Pp : [Ai -> Prop]) \(x : Ai, p : @(Pi, T, Ai, Pp)) @(p, x) end;

2.7.4

Σ-Types

Existential quantification, or general sum, or Σ-type, can be defined by a generalization of the binary sum Sigma, where the Σ-introduction is proved by EXIST and the Σ-elimination is proved by WITNESS. theory Sigma is def Sigma = \(T : Kind, Ai : T, Pi : [Ai -> Prop]) !(Bi : T) [!(x : Ai) [@(Pi, x) -> Bi] -> Bi]; def EXIST = \(T : Kind, Ai : T, Pi : [Ai -> Prop]) \(x : Ai, y : @(Pi, x), Bi : T, q : !(x : Ai) [@(Pi, x) -> Bi]) @(q, x, y); def WITNESS = \(T : Kind, Ai : T, Pi : [Ai -> Prop], p : @(Sigma, T, Ai, Pi)) @(p, Ai, \(x : Ai, y : @(Pi, x)) x) end;

The Sigma type presented here is usually called weak sum. One of the major difference between the weak sum and the strong sum ?(x : A) B is that the elimination-rule for the weak sum is too weak and, in particular, there is no way to prove that the first component of a weak pair of type @(Sigma, Ai, Pi) satisfies the property Bi.

2.7.5

Product Types (×)

2.7.5.1

Product of Two Types P and Q

Given two types U and V, we can construct their Cartesian product – a type of which is a pair whose first component being U and whose second component being V. theory Product2 is

Type Theory and PowerEpsilon

33

def Product = \(Ui : Prop, Vi : Prop) !(Ti : Prop) [[Ui -> Vi -> Ti] -> Ti]; def PRODUCT = \(Ui : Prop, Vi : Prop) \(u : Ui, v : Vi, Ti : Prop, z : [Ui -> Vi -> Ti]) @(z, u, v); def PRO1 = \(Ui : Prop, Vi : Prop, t : @(Product, Ui, Vi)) @(t, Ui, \(x : Ui, y : Vi) x); def PRO2 = \(Ui : Prop, Vi : Prop, t : @(Product, Ui, Vi)) @(t, Vi, \(x : Ui, y : Vi) y); def SPLIT = \(Ui : Prop, Vi : Prop, Wi : Prop) \(t : @(Product, Ui, Vi), f : [Ui -> Vi -> Wi]) @(f, @(PRO1, Ui, Vi, t), @(PRO2, Ui, Vi, t)); def And = Product end;

@(Product, P, Q) is a method for proving any proposition A, provided one has a proof that A follows from P and Q. Note that the proof of productintroduction PRODUCT above is a pairing algorithm, the two projection functions PRO1 and PRO2 being the proofs of product-elimination on the left and on the right. 2.7.5.2

Product of Three Types U, V and W

Similarly we can define the intuitionistic product of three propositions P, Q and R which represent the conjunction of three propositions: theory Product3 is import Product2 def Product3 = \(Ui : Prop, Vi : Prop, Wi : Prop) @(Product, Ui, @(Product, Vi, Wi)); def PRODUCT3 = \(Ui : Prop, Vi : Prop, Wi : Prop) \(u : Ui, v : Vi, w : Wi)

Type Theory and PowerEpsilon

34

@(PRODUCT, Ui, @(Product, Vi, Wi), u, @(PRODUCT, Vi, Wi, v, w)); def PROJ1 = \(Ui : Prop, Vi : Prop, Wi : Prop) \(t : @(Product3, Ui, Vi, Wi)) @(PRO1, Ui, @(Product, Vi, Wi), t); def PROJ2 = \(Ui : Prop, Vi : Prop, Wi : Prop) \(t : @(Product3, Ui, Vi, Wi)) @(PRO1, Vi, Wi, @(PRO2, Ui, @(Product, Vi, Wi), t)); def PROJ3 = \(Ui : Prop, Vi : Prop, Wi : Prop) \(t : @(Product3, Ui, Vi, Wi)) @(PRO2, Vi, Wi, @(PRO2, Ui, @(Product, Vi, Wi), t)); def SPLIT3 = \(Ui : Prop, Vi \(Yi : Type(0), \(f : [Ui -> Vi @(f, @(PROJ1, Ui, @(PROJ2, Ui, @(PROJ3, Ui,

: Prop, Wi : Prop) t : @(Product3, Ui, Vi, Wi)) -> Wi -> Yi]) Vi, Wi, t), Vi, Wi, t), Vi, Wi, t))

end;

2.7.5.3

Product of Infinite Type Sequence

Consider the Cartesian product of an infinite sequence of types defined as a function A : [Nat -> Prop]. Now, the product type of A is @(GProduct, A), and @(GPRODUCT, A, a) is one of its element, if a is of type A. If t is an element of type @(GProduct, A), then @(GPROJ, A, n, t) is its nth component. theory GProduct is import Nat def GProduct = \(A : [Nat -> Prop]) !(T : Prop) [!(n : Nat) @(A, n) -> T] -> T]; def GPRODUCT = \(A : [Nat -> Prop) \(a : !(n : Nat) @(A, n)) \(T : Prop, z : [!(n : Nat) @(A, n) -> T]) @(z, a);

Type Theory and PowerEpsilon

35

def GPROJ = \(A : [Nat -> Prop]) \(n : Nat, t : @(GProduct, A)) @(t, @(A, n), \(a : !(n : Nat) @(A, n)) @(a, n)) end;

2.7.6

Sum Types (+)

2.7.6.1

Sum of Two Types U and V

We may similarly construct the intuitionistic sum of two propositions P and Q which represents the disjunction of two propositions: theory Sum2 is def Sum2 = \(Ui : Prop, Vi : Prop) !(Ti : Prop) [[Ui -> Ti] -> [Vi -> Ti] -> Ti]; def INJ1 = \(Ui : Prop, Vi : Prop) \(u : Ui) \(Ti : Prop) \(x : [Ui -> Ti], y : [Vi -> Ti]) @(x, u); def INJ2 = \(Ui : Prop, Vi : Prop) \(v : Vi) \(Ti : Prop) \(x : [Ui -> Ti], y : [Vi -> Ti]) @(y, v); def CASE = \(U : Prop, V : Prop, Ti : Prop) \(x : [U -> Ti], y : [V -> Ti], s : @(Sum2, U, V)) @(s, Ti, x, y); def WHEN = \(U : Prop, V : Prop, W : Prop) \(a : @(Sum2, U, V), c : [U -> W], d : [V -> W]) @(a, W, \(x : U) @(CASE, U, V, W, c, d, a), \(y : V) @(CASE, U, V, W, c, d, a)); def Or = Sum2 end;

Type Theory and PowerEpsilon

36

where the sum-elimination is proved by the conditional expression CASE and the two sum-introduction rules correspond to the two injection functions INJ1 and INJ2. 2.7.6.2

Sum of Three Types U, V and W

Similarly we can define the intuitionistic sum of three propositions P, Q and R which represent the disjunction of three propositions: theory Sum3 is import Sum2 def Sum3 = \(U : Prop, V : Prop, W : Prop) !(Ti : Type(0)) [[U -> Ti] -> [V -> Ti] -> [W -> Ti] -> Ti]; def CASE3 = \(U : Prop, V : Prop, W : Prop) \(T : Type(0), x : [U -> T], y : [V -> T], z : [W -> T]) \(s : @(Sum3, U, V, W)) @(s, T, x, y, z); def INJC1 = \(U : Prop, V : Prop, W : Prop) \(u : U) \(Ti : Type(0)) \(x : [U -> Ti], y : [V -> Ti], z : [W -> Ti]) @(x, u); def INJC2 = \(U : Prop, V : Prop, W : Prop) \(v : V) \(Ti : Type(0)) \(x : [U -> Ti], y : [V -> Ti], z : [W -> Ti]) @(y, v); def INJC3 = \(U : Prop, V : Prop, W : Prop) \(w : W) \(Ti : Type(0)) \(x : [U -> Ti], y : [V -> Ti], z : [W -> Ti]) @(z, w); def WHEN3 = \(U : Prop, V : Prop, W : Prop) \(Xi : Type(0), a : @(Sum3, U, V, W)) \(c : [U -> Xi], d : [V -> Xi], e : [W -> Xi]) @(a, Xi,

Type Theory and PowerEpsilon

37

\(x : U) @(CASE3, U, V, W, Xi, c, d, e, a), \(y : V) @(CASE3, U, V, W, Xi, c, d, e, a), \(z : W) @(CASE3, U, V, W, Xi, c, d, e, a)) end;

2.7.6.3

Sum of Infinite Type Sequence

Consider the sum of an infinite sequence of types defined as a function A : [Nat -> Prop]. According to the definition, the infinite disjoint union type of A is @(GSum, A), and @(GINJ, A, a) is its element, if a is of type A. theory GSum is import Nat def GSum = \(A : [Nat -> Prop]) !(T : Prop) [?(n : Nat) @(A, n) -> T] -> T]; def GINJ = \(A : [Nat -> Prop) \(a : ?(n : Nat) @(A, n)) \(T : Prop, z : [?(n : Nat) @(A, n) -> T]) @(z, a); def GCASE = \(A : [Nat -> Prop]) \(n : Nat, a : [?(m : Nat) @(A, m) -> @(A, n)], t : @(GSum, A)) @(t, @(A, n), a) end;

2.7.7

Subset Types

We may also define the intuitionistic subset of a given type with the subsetintroduction rule INTRO and the subset-elimination rule ELIMIT: theory Subset is def Subset = \(T : Kind, Ai : T, Pi : [Ai -> Prop]) !(Bi : T) [!(x : Ai) [@(Pi, x) -> Bi] -> Bi]; def INTRO = \(T : Kind, Ai : T, Pi : [Ai -> Prop]) \(x : Ai, y : @(Pi, x)) \(Bi : T) \(q : !(x : Ai) [@(Pi, x) -> Bi])

Type Theory and PowerEpsilon

38

@(q, x, y); def ELIMIT = \(T : Kind, Ai : T, Pi : [Ai -> Prop]) \(p : @(Subset, T, Ai, Pi)) @(p, Ai, \(x : Ai, y : @(Pi, x)) x) end;

There is a little difference between Subset and Sigma which can be seen as follows: def Subset = \(T : Kind) \(Ai : T) \(Pi : [Ai -> Prop]) !(Bi : T) [!(x : Ai) [@(Pi, x) -> Bi] -> Ai]; def Sigma = \(T : Kind) \(Ai : T) \(Pi : [Ai -> Prop]) !(Bi : T) [!(x : Ai) [@(Pi, x) -> Bi] -> Bi];

2.7.8

Leibniz’s Equality

Leibniz’s equality is definable in PowerEpsilon: theory Equal is def Equal = \(A : Type(0), x : A, y : A) !(P : [A -> Prop]) [@(P, x) -> @(P, y)] end;

The equality satisfies the reflexive, symmetric and transitive properties, which can be verified as follows. If REFLEX, SYMM and TRANS specify the desired properties, we will have: dec REFLEX : !(A : Type(0), R : [A -> A -> Prop], x : A) @(R, x, x); dec SYMM : !(A : Type(0), R : [A -> A -> Prop], x : A, y : A) [@(R, x, y) -> @(R, y, x)]; dec TRANS : !(A : Type(0), R : [A -> A -> Prop], x : A, y : A, z : A)

Type Theory and PowerEpsilon

39

[@(R, x, y) -> @(R, y, z) -> @(R, x, z)]

The following lemmas give the proofs which state that Equal satisfies the reflexive, symmetric and transitive properties. def LEMMA1 = @(REFLEX, Ti, @(Equal, Ti)); def LEMMA2 = @(SYMM, Ti, @(Equal, Ti)); def LEMMA3 = @(TRANS, Ti, @(Equal, Ti))

The following results are delivered by PowerEpsilon system: LEMMA1 : !(x : Ti) @(Equal, Ti, x, x) LEMMA2 : !(x : Ti) !(y : Ti) [@(Equal, Ti, x, y) -> @(Equal, Ti, y, x)] LEMMA3 : !(x : Ti) !(y : Ti) !(z : Ti) [@(Equal, Ti, x, y) -> @(Equal, Ti, y, z) -> @(Equal, Ti, x, z)]

2.8

Transforming English to PowerEpsilon

At this point, we translate a few sentences into propositional form. Consider the sentence “if it rains, the picnic is cancelled.” Let identifier R stand for the proposition “it rains” and let identifier PC represent the “picnic is cancelled”. Then the sentence can be written as [R -> PC]. As shown by this example, the technique is to represent “atomic parts” of a sentence – how there are chosen is up to the translator – by identifiers and to describe their relationship using logical operators. Here are some more examples, using identifiers R, PC, Wet, and S defined as follows: it rains: R : Prop picnic is cancelled: PC : Prop be wet: Wet : Prop Stay at home: S : Prop We then may define the following propositions in terms of PowerEpsilon: 1. If it rains but I stay at home, I won’t be wet: [@(And, R, S) -> @(Not Wet). 2. I will be wet if it rains: [R -> Wet].

Type Theory and PowerEpsilon

40

3. If it rains and the picnic is not cancelled or I don’t stay home, I will be wet: either @(Or, @(And, R, @(Not, PC)), @(Not, S)) -> Wet] or @(And, R, @(Or, @(Not, PC)), @(Not, S)) -> Wet]. The English is ambiguous; the latter proposition is probably the desired one. 4. Whether or not the picnic is cancelled, I am staying home if it rains: [@(And, @(Or, PC, @(Not, PC)), R) -> S] . In classical logic, this may reduce to [R -> S]. However, in constructive logic, this is not reducible. 5. Either it does not rain or I am staying home: @(Or, @(Not, R), S).

2.9

Propositions as Types and Proofs as Programs

One of the basic ideas behind constructive type theory is the Curry-Howard interpretation of propositions as types and proofs as programs. This view of propositions is related both to Heyting’s explanation of intuitionistic logic and, on a more formal level, to Kleene’s realizability interpretation of intuitionistic arithmetic. The judgement or type assignment “a : A” in PowerEpsilon can be read in at least the four following ways: • a is an element of type A. • a is a proof object for the proposition A. • a is a program satisfying the specification A. • a is a solution to the problem A. In classical mathematics, a proposition is thought of as being true or false independently of whether we can prove or disprove it. On the other hand, a proposition is constructively true only if we have a method to prove it. For example, classically the law of excluded middle, A ∨ ¬A, is true, since the proposition A is either true or false. Constructively, however, a disjunction is true only if we can prove one of the disjuncts. Since we have no method of proving or disproving an arbitrary proposition A, we have no proof of A ∨ ¬A and therefore the law of excluded middle is not constructively valid. We may establish the following identifications between propositions and types. • A proof of type [A -> B] is a function (method, program) which to each proof of A gives a proof of B. • A proof of type @(Product, A, B) is a pair whose first component is a proof A and whose second component is a proof of B.

Type Theory and PowerEpsilon

41

• A proof of type @(Sum, A, B) is either a proof A or a proof of B together with the information of which of A or B we have a proof. The elements in @(Sum, A, B) are of the form @(INJ1, A, B, a) and @(INJ2, A, B, b) where a : A and b : B. • A proof of type !(x : A) @(B, x) is a function (method, program) which to each element a of type A gives a proof of @(B, a). The type corresponding to this is the Cartesian product of a family of types. The elements of this type are functions which, when applied to an element a in the type A gives an element in the type @(B, a). • A proof of type ?(x : A) @(B, x) is a pair whose first component a is an element of type A and whose second component is a proof of @(B, a). The type corresponding to this is the disjoint union of a family of types. The elements of this type are pairs where a : A and b : @(B, a). The correspondence between propositions and types, and proofs and programs are called Curry-Howard isomorphism. From the points of view for computer programming, a proposition could be interpreted as the specifications of the task of a program in the following way. • @(Product, A, B) is a specification of programs which, when executed, yield a pair @(PRODUCT, A, B, a, b), where a is a program for the task A and b is a program for the task B. • @(Sum, A, B) is a specification of programs which, when executed, either yields @(INJ1, A, B, a) or @(INJ2, A, B, b), where a is a program for A and b is a program for B. • [A -> B] is a specification of programs which, when executed, yields \(x : A) b, where b is a program for B under the assumption that x is a program for A. • !(x : A) @(B, x) is a specification of programs which, when executed, yields \(x : A) b, where b is a program for @(B, x) under the assumption that x is an object of A. This means that when a program for the problem !(x : A) @(B, x) is applied to an arbitrary object x of A, the result will be the program for @(B, x). • ?(x : A) @(B, x) is a specification of programs which, when executed, yields , where a is an object of A and b a program for @(B, a). So, to solve the task ?(x : A) @(B, x) it is necessary to find a method which yields an object a in A and a program for @(B, a).

Type Theory and PowerEpsilon

2.10

42

Types, Sets and Domains

In describing the semantics of programming languages, we usually use the word “domain” instead of “set”. This was for mathematical reasons. Unfortunately to fully explain the difference between sets and domains, and to convincingly justify our use of the latter, we would have to delve in detail into the underlying mathematics. This we wish to avoid, and so we shall just very crudely sketch some of the issues involved. There are really two related, but separate, problems which lead to the use of domains rather than sets: • Recursive definitions of functions. • Recursive definitions of sets. We shall look at the these in turn.

2.10.1

The Problem of Recursively Defined Functions

We often find it necessary to define functions recursively. For example, the semantic clause for @(WHILE, e, s), defines as let v = @(EXPR, e, r, z) in @(GIF_THEN_ELSE, State, @(GET_BVAL, v), @(STAT, @(SEQ, s, @(WHILE, e, s)), r, z), z), At first sight such ‘definitions’ are highly suspicious since they seem to assume that the thing they are trying to define is already defined. The way out is to regard recursive definitions as equations – to regards the definition given above as analogous to the quadratic equation x = a × x2 + b and to seek methods of solving functional equations. It turns out that the kind of functional equations we want to solve in semantics only have solutions when the functions involved map between specially structured sets called domains. To see what goes wrong with ordinary sets consider the following two equations ‘defining’ f : [Nat -> Nat]: 1. f(x) = f(x) + 1 2. f(x) = f(x) There is no f satisfying equation 1 and every f satisfies equation 2; thus neither of these two equations in any sense defines f .

Type Theory and PowerEpsilon

2.10.2

43

The Problem of Recursively Defined Sets

It is often the case that intuitions about the ‘data’ manipulated by programs in a language lead us to want to define recursively the domains modelling the corresponding ‘data-types’. For example, we may have the following type definitions: def Sval = !(T : Prop) [[Bool -> T] -> [Int -> T] -> [Location -> T] [Cont -> T] -> T]; def Memory = !(T : Prop) [T -> [Location -> Sval -> T -> T] -> T]; def Input = @(List, Sval); def State = @(Product, Memory, Input); dec Ans : Prop; def Ans = @(Product, Sval, Ans); def Cont = [State -> Ans];

These domain equations are recursive: State is defined in terms of Memory, which is defined in terms of Sval, which is defined in terms of Cont, which is defined in terms of State. The domain Ans is defined in terms of itself. Thus just as the ‘looping’ of @(WHILE, e, s) led us to define its denotation as a recursive function, so the embedding of procedures in states leads us to define State as a recursive domain.

2.10.3

The Role of Scott’s Domain Theory

A major breakthrough in semantic theory came when Dana Scott showed how to consistently interpret both kinds of recursive definitions – definitions of members of domains and definitions of domains themselves – in a single framework. In summary what he did was: • Devise a class of ‘structured’ sets called domains and define the operators Product, Sum and -> etc. on them. • Show how elements of domains could be defined recursively. • Show how domains themselves could be defined recursively.

Type Theory and PowerEpsilon

2.10.4

44

Types as Domains

In PowerEpsilon, there is a natural corresponding between types and sets. So the type assignment “a : A” in PowerEpsilon can be read as a is an element of set A. We may establish the following identifications between sets and types. • An element of set [A -> B] is a function which to each element of A gives an element of B. • An element of set @(Product, A, B) is a pair whose first component is an element A and whose second component is an element of B. • An element of set @(Sum, A, B) is either an element A or an element of B together with the information of which of A or B we have an element. The elements in @(Sum, A, B) are of the form @(INJ1, A, B, a) and @(INJ2, A, B, b) where a : A and b : B. • An element of set !(x : A) @(B, x) is a function which to each element a of set A gives an element of @(B, a). The corresponding to this is the Cartesian product of a family of sets. The elements of this set are functions which, when applied to an element a in the set A gives an element in the set @(B, a). • An element of set ?(x : A) @(B, x) is a pair whose first component a is an element of set A and whose second component is an element of @(B, a). The corresponding to this is the disjoint union of a family of sets. The elements of this set are pairs where a : A and b : @(B, a). Therefore for denotational semantics setting, we may view types of PowerEpsilon as domains. As a theoretical foundation, it will be easy to give a denotational semantics of PowerEpsilon, since PowerEpsilon by itself is a programming language too. The only difference is that the static semantics of PowerEpsilon is more complicated than its dynamic one. In this book, the words “type” and “domain” will be used denoting the same things without further explanation.

2.10.5

Defining Domains

2.10.5.1

Standard Domains

The following domains are standard domains and will be used without further explanation: Bool, Nat, Int, Rat and Identifier. 2.10.5.2

Finite Domains

Finite domains will be defined explicitly by listing their elements as we have already defined for Bool. The following is a seven elements of domain Spectrum:

Type Theory and PowerEpsilon

45

def Spectrum = !(T : Prop) [T -> T -> T -> T -> T -> T -> T -> T]; def RED = \(T : Prop) \(a : T, b : T, c : T, d : T, e : T, f : T, g : T) a; def ORANGE = \(T : Prop) \(a : T, b : T, c : T, d : T, e : T, f : T, g : T) b; def YELLOW = \(T : Prop) \(a : T, b : T, c : T, d : T, e : T, f : T, g : T) c; def GREEN = \(T : Prop) \(a : T, b : T, c : T, d : T, e : T, f : T, g : T) d; def BLUE = \(T : Prop) \(a : T, b : T, c : T, d : T, e : T, f : T, g : T) e; def INDIGO = \(T : Prop) \(a : T, b : T, c : T, d : T, e : T, f : T, g : T) f; def VIOLET = \(T : Prop) \(a : T, b : T, c : T, d : T, e : T, f : T, g : T) g;

2.10.5.3

Domain Constructors

We shall build domains out of standard, or finite, domains using the various domain constructors such as ->, !, ?, Product, Sum and List. 2.10.5.4

Domain Equations

In general the domain equations have the following general form def D1 = @(T1, D1, ..., Dn); def D2 = @(T1, D1, ..., Dn); . . .

Type Theory and PowerEpsilon

46

def Dn = @(T1, D1, ..., Dn); Where each @(Ti, D1, ..., Dn) is some expression built out of D1, D2, ..., Dn using some domain constructors such as ->, Product, Sum and List described above. An example of a single domain equation is the domain Dw of infinite sequences of members of D defined by def Dw = @(Product, D, Dw); In doing so, we need a pre-declaration of Dw: dec Dw : Prop;

2.10.6

Functions

The word “function” has a number of different meaning which, if not carefully distinguished, can lead to total confusion. It is especially important to distinguish mathematical functions from the so called “functions” which occur as constructs in several programming languages.

Chapter 3

Hypervisor Technology The following contents were taken from Wikipedia, the free encyclopedia which described the concepts of hypervisor technology. In computing, a hypervisor, also called virtual machine monitor (VMM), is a piece of software/hardware platform-virtualization software that allows multiple operating systems to run on a host computer concurrently.

3.1

Classifications

Hypervisors are classified into two types: The Type 1 Hypervisors and the Type 2 Hypervisors.

3.1.1

Type 1 Hypervisors

Type 1 (or native, bare-metal) hypervisors are software systems that run directly on the host’s hardware to control the hardware control and to monitor guest operating-systems. A guest operating system thus runs on another level above the hypervisor. This model represents the classic implementation of virtual machine architectures; the original hypervisor was CP/CMS, developed at IBM in the 1960s, ancestor of IBM’s current z/VM. More recent examples include • VMware ESX Server • INTEGRITY from Green Hills Software • LynxSecure from LynuxWorks • L4 microkernels including OKL4 from Open Kernel Labs

47

CHAPTER 3. HYPERVISOR TECHNOLOGY

48

• Real-Time Systems RTS-Hypervisor • VirtualLogix VLX • TRANGO (now VMware MVP) • IBM POWER Hypervisor (PowerVM) • IBM System zHypervisor (PR/SM) • Microsoft Hyper-V (released in June 2008) • Xen • Citrix XenServer • Oracle VM Server • Parallels Server (released in 2008) • ScaleMP vSMP Foundation (released in 2005) • Sun’s Logical Domains Hypervisor (released in 2005) • Wind River’s hypervisor and VxWorks MILS Platform • XtratuM A variation of Type-1 hypervisors involves embedding the hypervisor in the firmware of the platform, as is done in the case of Hitachi’s Virtage hypervisor and VMware ESXi. This group also includes Kernel-based Virtual Machine (KVM) which turns a Linux kernel into a hypervisor.

3.1.2

Type 2 Hypervisors

Type 2 (or hosted) hypervisors are software applications running within a conventional operating-system environment. Considering the hypervisor layer as a distinct software layer, guest operating systems thus run at the third level above the hardware. Examples include • VMware Server (formerly known as GSX) • VMware Workstation • VMware Fusion • The open source QEMU • Microsoft Virtual PC and Microsoft Virtual Server products

CHAPTER 3. HYPERVISOR TECHNOLOGY

49

• Sun’s (formerly InnoTek) VirtualBox • KUKA’s RTOSWin product family as well as Parallels Workstation and Parallels Desktop • TenAsys’ eVM. The term hypervisor apparently originated in IBM’s CP-370 reimplementation of CP-67 for the System/370, released in 1972 as VM/370. The term hypervisor call, or hypercall, referred to the paravirtualization interface, by which a guest operating system could access services directly from the (higher-level) control program C analogous to making a supervisor call to the (same level) operating system. The term supervisor refers to the operating system kernel, which runs in supervisor state on IBM mainframes.

3.2

Mainframe Origins

The first hypervisor providing full virtualization, IBM’s one-off research CP-40 system, began production use in January 1967, and became the first version of IBM’s CP/CMS operating system. CP-40 ran on a one-off S/360-40 that was customized to support virtualization. Prior to this time, computer hardware had only been virtualized enough to allow multiple user applications to be run (see CTSS and IBM M44/44X). With CP-40, the hardware’s supervisor state was virtualized as well, allowing multiple operating systems to run simultaneously. Programmers soon re-implemented CP-40 (as CP-67) for the IBM System/360-67, the first production computer system capable of full virtualization. This machine was first shipped in 1966, and included page translation table hardware for virtual memory, and other techniques that allowed a full virtualization of all kernel tasks, including I/O and interrupt handling. (Note that its “official” operating system, the ill-fated TSS/360, did not employ full virtualization.) Both CP-40 and CP-67 began production use in 1967. CP/CMS was available to IBM customers from 1968 to 1972, in source code form without support. CP/CMS was part of IBM’s attempt to build robust time-sharing systems for its mainframe computers. By running multiple operating systems simultaneously, the hypervisor increased system robustness and stability: Even if one operating system crashed, the others would continue working without interruption. Indeed, this even allowed beta or experimental versions of operating systems C or even of new hardware C to be deployed and debugged, without jeopardizing the stable main production system, and without requiring costly additional development systems. IBM announced its System/370 series in 1970 without any virtualization features, but these were added to the series in 1972, and have appeared in all successor systems. (All modern-day (as of 2009) IBM mainframes, such as

CHAPTER 3. HYPERVISOR TECHNOLOGY

50

the zSeries line, retain backwards-compatibility with the 1960s-era IBM S/360 line.) The 1972 announcement also included VM/370, a reimplementation of CP/CMS for the S/370. Unlike CP/CMS, IBM provided support for this version (though it was still distributed in source code form for several releases). VM stands for Virtual Machine, emphasizing that all, and not just some, of the hardware interfaces are virtualized. Both VM and CP/CMS enjoyed early acceptance and rapid development by universities, corporate users, and time-sharing vendors, as well as within IBM. Users played an active role in ongoing development, anticipating trends seen in modern open source projects. However, in a series of disputed and bitter battles, time-sharing lost out to batch processing through IBM political infighting, and VM remained IBM’s “other” mainframe operating system for decades, losing over MVS. It has enjoyed a resurgence of popularity and support in recent years as the current z/VM product, e.g. as the platform for Linux for zSeries. As mentioned above, the VM control program includes a hypervisor call handler which intercepts DIAG (“Diagnose”) instructions used within a virtual machine. This provides fast-path non-virtualized execution of file-system access and other operations. (DIAG is a model-dependent privileged instruction, not used in normal programming, and thus is not virtualized. It is therefore available for use as a signal to the “host” operating system.) When first implemented in CP/CMS release 3.1, this use of DIAG provided an operating system interface that was analogous to the System/360 SVC (“supervisor call”) instruction, but that did not require altering or extending the system’s virtualization of SVC.

3.3

UNIX and Linux Servers

Several factors led to a resurgence in the use of virtualization technology among UNIX and Linux server vendors: • Expanding hardware capabilities, allowing more simultaneous work to be done per machine • Efforts to control costs and simplify management through consolidation of servers • The need to control large multiprocessor and cluster installations, e.g. in server farms and render farms • The improved security, reliability, and device independence possible from hypervisor architectures • The desire to run complex, OS-dependent applications in different hardware or OS environments Major UNIX vendors, including Sun Microsystems, HP, IBM, and SGI, have been selling virtualized hardware since before 2000. These have generally been

CHAPTER 3. HYPERVISOR TECHNOLOGY

51

large systems with hefty, server-class price tags (in the multi-million dollar range at the high end), although virtualization is also available on some mid-range systems, such as IBM’s System-P servers, Sun’s CoolThreads T1000, T2000 and T5x00 servers and HP Superdome series. Multiple host operating systems have been modified to run as guest OSes on Sun’s Logical Domains Hypervisor. As of late 2006, Solaris, Linux (Ubuntu and Gentoo), and FreeBSD have been ported to run on top of Hypervisor (and can all run simultaneously on the same processor, as fullyvirtualized independent guest OSes). Wind River “Carrier Grade Linux” also plans to run on Sun’s Hypervisor. Full virtualization on SPARC processors was not difficult because the SPARC architecture, since its inception in the mid-1980s, was deliberately kept clean of artifacts that would have impeded virtualization. (Compare with virtualization on x86 processors below.) HP calls its technology to host multiple OS technology on its Itanium powered systems (Integrity) “Integrity Virtual Machines” (Integrity VM). Itanium is capable of running HP-UX, Linux, Windows and OpenVMS. Except for OpenVMS, to be supported in a later release, these environments are also supported as virtual servers on HP’s Integrity VM platform. The HPUX operating system hosts the Integrity VM hypervisor layer which allows for many important features of HP-UX to be taken advantage of and provides major differentiation between this platform and other commodity platforms - such as processor hotswap, memory hotswap, and dynamic kernel updates without system reboot. While it heavily leverages HP-UX, the Integrity VM hypervisor is really a hybrid that runs on bare-metal while guests are executing. Running normal HP-UX applications on an Integrity VM host is heavily discouraged, because Integrity VM implements its own memory management, scheduling and I/O policies that are tuned for virtual machines and are not as effective for normal applications. HP also provides more rigid partitioning of their Integrity and HP9000 systems by way of VPAR and nPar technology, the former offering shared resource partitioning and the later offering complete I/O and processing isolation. The flexibility of VSE has given way to its use more frequently in newer deployments. IBM provides virtualization partition technology known as logical partitioning (LPAR) on System/390, zSeries, pSeries and iSeries systems. For IBM’s Power Systems, the Power Hypervisor (PowerVM) is native (bare-metal) and provides EAL4+ strong isolation between LPARs. Processor capacity is provided to LPARs in either a dedicated fashion or on an entitlement basis where unused capacity is harvested and can be re-allocated to busy workloads. Groups of LPARs can have their processor capacity managed as if they were in a “pool” - IBM refers to this capability as Multiple Shared-Processor Pools (MSPPs) and implements it in servers with the POWER6 processor. LPAR and MSPP capacity allocations can be dynamically changed. Memory is allocated to each LPAR (at LPAR initiation or dynamically) and is address-controlled by the POWER Hypervisor. For real-mode addressing by operating systems (AIX,

CHAPTER 3. HYPERVISOR TECHNOLOGY

52

Linux, IBM i), the POWER processors (POWER4 onwards) have architected virtualization capabilities where a hardware address-offset is evaluated with the OS address-offset to arrive at the physical memory address. Input/Output (I/O) adapters can be exclusively “owned” by LPARs or shared by LPARs through an appliance partition known as the Virtual I/O Server (VIOS). The Power Hypervisor provides for high levels of reliability, availability and serviceability (RAS) by facilitating hot add/replace of many parts (model dependent: processors, memory, I/O adapters, blowers, power units, disks, system controllers, etc.) Similar trends have occurred with x86/x86 64 server platforms, where virtualization efforts have been led by open source projects such as Xen. These include hypervisors built on Linux and Solaris kernels as well as custom kernels. Since these technologies span from large systems down to desktops, they are described in the next section.

3.4

PCs and Desktop Systems

Interest in the high-profit server hardware market sector has led to the development of hypervisors for machines using the Intel x86 instruction set, including for traditional desktop PCs. One of the early PC hypervisors was the commercial VMware, introduced in 1998. Parallels, Inc. introduced Parallels Workstation, which is primarily used on PCs, in 2005 and Parallels Desktop for Mac, which runs on Mac OS X, in 2006. The x86 architecture used in most PC systems poses particular difficulties to virtualization. Full virtualization (presenting the illusion of a complete set of standard hardware) on x86 has significant costs in hypervisor complexity and run-time performance. More recently CPU vendors have added hardware virtualization assistance to their products. Intel’s is called Intel VT (codenamed Vanderpool) and AMD’s is referred to as AMD-V (codenamed Pacifica). These extensions address the parts of x86 that are difficult or inefficient to virtualize, providing additional support to the hypervisor. This enables simpler virtualization code and a higher performance for full virtualization.

3.4.1

Paravirtualization

An alternative approach requires modifying the guest operating-system to make system calls to the hypervisor, rather than executing machine I/O instructions which are then simulated by the hypervisor. This is called paravirtualization in Xen, a “hypercall” in Parallels Workstation, and a “DIAGNOSE code” in IBM’s VM. VMware supplements the slowest rough corners of virtualization with device drivers for the guest. All are really the same thing, a system call to the hypervisor below. Some microkernels such as Mach and L4 are flexible enough such that “paravirtualization” of guest operating systems is possible.

CHAPTER 3. HYPERVISOR TECHNOLOGY

3.4.2

53

Hypervisors on PCs and Desktops

Others, like Xen, implement software-only virtual machines. Xen runs on a normal host operating system such as Linux, and is able to run both paravirtualized and fully virtualized (i.e., unmodified) operating systems with the help of the hardware virtualization extensions Intel VT-x. The Xen distribution already contains versions of FreeBSD, Linux, NetBSD, and Plan 9 from Bell Labs that have been so modified. User programs will continue to work on Xen without change. Also, Xen has been re-implemented on the OpenSolaris operating system as of build 75 the result is called Sun xVM Server. In June 2008 Microsoft delivered a new Type-1 hypervisor called HyperV (codenamed “Viridian” and previously referred to as “Windows Server Virtualization”); the design features OS integration at the lowest level. New versions of the Windows operating system beginning with Windows Vista include extensions to boost performance when running on top of the Viridian hypervisor. Green Hills Software’s Integrity (operating system) uses Intel VT to provide its Type-1+ full virtualization on laptops, desktops, and mobile devices. Integrity can optionally use paravirtualized drivers for improved performance.

3.5

Embedded Systems

As of 2009 virtual machines have started to appear in embedded systems, such as mobile phones. This is driven by the desire to provide a high-level operatingsystem interface for application programming, such as Linux or Microsoft Windows, while at the same time maintaining traditional real-time operating system (RTOS) APIs. The low-level RTOS environments need to be retained for legacy support, and because the real-time capabilities of high-level OSes are insufficient for many embedded applications.

3.5.1

Embedded Hypervisors

Embedded hypervisors must therefore have real-time capability, a design criterion not present for hypervisors used in other domains. The resource-constrained nature of many embedded systems, especially battery-powered mobile systems, imposes a further requirement for small memory-size and low overhead. Finally, in contrast to the ubiquity of the x86 architecture in the PC world, the embedded world uses a wider variety of architectures. Support for virtualization requires memory protection (in the form of a memory management unit or at least a memory protection unit) and a distinction between user mode and privileged mode, which rules out most microcontrollers. This still leaves x86, MIPS, ARM and PowerPC as widely-deployed architectures on medium- to high-end embedded systems.

CHAPTER 3. HYPERVISOR TECHNOLOGY

3.5.2

54

Virtualization vs Paravirtualization

As embedded-system manufacturers usually have source code to their operating systems, they have less need for full virtualization in this space. Instead, the performance advantages of paravirtualization make this usually the virtualization technology of choice. Nevertheless, ARM has recently added a limited form of support for full virtualization (single guest only) with its TrustZone technology.

3.5.3

Challenges for Embedded Virtualization

Other differences between virtualization in server/desktop and embedded environments include requirements for efficient sharing of resources across virtual machines, high-bandwidth, low-latency inter-VM communication, a global view of scheduling and power management, and fine-grained information-flow control.

3.5.4

Hypervisors in Embedded Industry

3.5.4.1

Integrity from Green Hills

The real-time operating system Integrity from Green Hills Software has employed Type-1+ virtualization in embedded and mobile devices since 2003, and uses a combination of hardware-accelerated full virtualization (e.g. Intel VT) and paravirtualization, depending on the microprocessor’s capabilities. Integrity supports Intel, Power, ARM, MIPS, and ColdFire architectures. Guest operating systems include Linux, Windows, Solaris, VxWorks, etc. 3.5.4.2

OKL4

Another hypervisor deployed in mobile embedded systems (such as Toshiba mobile phones) is OK-labs OKL4 kernel, a dual licensed open source and commercial member of the L4 microkernel family. It supports x86, ARM and MIPS processors, it is purportedly the worlds most widely-deployed mobile virtualisation solution. The plans of OK-labs are to eventually create or modify current existing mobile operating systems to run on top of their kernel to provide portability for vendors and users. 3.5.4.3

Other Hypervisors

Other hypervisors for embedded use include: • TRANGO (Now VMware MVP), which supports ARM, MIPS and PowerPC. • x86-based LynxSecure from LynuxWorks. • The XtratuM from the Universidad Polit´ ecnica de Valencia (Spain).

CHAPTER 3. HYPERVISOR TECHNOLOGY

55

• The RTS-Hypervisor from Real-Time Systems which supports Windows XP, Windows CE, Linux,On Time RTOS-32, VxWorks, RadiSys’ Microware OS-9, QNX, Pharlap ETS. • The Wind River hypervisor which supports Linux and VxWorks on popular embedded processors. • TenAsys eVM Virtualization Platform for Windows which uses Intel VT to provide a virtual-machine environment on a dedicated core of a multi-core processor alongside the Windows OS. • The acontis technologies x86-based RTOSVisor which is available as Type 1 and Type 2 Real-Time Hypervisor, where as Type2 not requiring the Intel VT or AMD-V and also supporting single core processors.

3.6

Security Implications

The use of hypervisor technology by malware and rootkits installing themselves as a hypervisor below the operating system can make them more difficult to detect because the malware could intercept any operations of the operating system (such as someone entering a password) without the antivirus software necessarily detecting it (since the malware runs below the entire operating system). The concept has been implemented in the SubVirt laboratory rootkit, developed jointly by Microsoft and University of Michigan researchers, as well as by the Blue Pill malware package. However, such assertions have been disputed by others who claim that it would indeed be possible to detect the presence of a hypervisor-based rootkit. In 2009, researchers from Microsoft and the North Carolina State University demonstrated a hypervisor-layer anti-rootkit called Hooksafe that is able to provide generic protection against kernel-mode rootkits.

3.7

About SVMK

SVMK developed by CoreTek Systems is built using a Type 1 Hypervisor technology. It provides the services necessary to be compliant with the Separation Kernel Protection Profile (SKPP), provides for better system performance even with dozens of user-mode partitions. In addition, we have the DeltaOS guest operating system that can be utilized in the partitions, really giving DeltaOS users great API compatibility so they can take their applications and plug them into a MILS environment. And at that point, theyve got these applications that they can now reuse in a fully secure environment.

Part II

The Abstract Target Machine

56

Chapter 4

How The Machine Designed 4.1

Abstract Machine TM and TM-2

The abstract operating machine TM and TM-2 are designed in the following way: • As we have stated that the work was started by designing a simple RISC machine TM and then extended by making all the operating system primitives which are non-interruptible as the machine instructions and we call it the extended machine TM-2. It means that we start work from an existing design and implementation, the formal specification and analysis are given afterward. • Beside the registers, data memory and instruction memory for TM, we will make all the data structures such VMKManager, VMCBs, TTSCBs and so on as the built-in structures of TM-2 resulting a very rich architecture. • We then give the description of abstract syntax and semantic definition for TM and TM-2 in terms of PowerEpsilon.

4.2 4.2.1

The System Service APIs Specifications for VM Management

In general, VM management provides operations for starting and stoping of VMs, and control and access over VM attributes. There are totally 15 system service routines for VMs. 4.2.1.1

vmkGetVMID

Get the ID of a VM. 57

CHAPTER 4. HOW THE MACHINE DESIGNED

58

T_VMK_ReturnCode vmkGetVMID(T_UBYTE *vmName, T_UWORD *vmID);

4.2.1.2

vmkGetVMName

Get the name of a VM. T_VMK_ReturnCode vmkGetVMName(T_UWORD vmID, T_UBYTE *vmName);

4.2.1.3

vmkGetVMName

Get the status of a VM. T_VMK_ReturnCode vmkGetVMStatus(T_UWORD vmID, T_VMK_VMStatus *status);

4.2.1.4

vmkHaltVM

Halt a VM. T_VMK_ReturnCode vmkHaltVM(T_VMK_WakeupType wakeupType, T_UWORD ticks);

4.2.1.5

vmkStartVM

Start a VM. T_VMK_ReturnCode vmkStartVM(T_UWORD vmID, T_VMK_SchedType type);

4.2.1.6

vmkStopVM

Stop a VM. T_VMK_ReturnCode vmkStopVM(T_UWORD vmID);

4.2.1.7

vmkSuspendVM

Suspend a VM. T_VMK_ReturnCode vmkSuspendVM(T_UWORD vmID);

CHAPTER 4. HOW THE MACHINE DESIGNED

4.2.1.8

59

vmkResumeVM

Resume a VM. T_VMK_ReturnCode vmkResumeVM(T_UWORD vmID);

4.2.1.9

vmkGetInfo

Get the information of a VM. T_VMK_ReturnCode vmkGetInfo(T_VMK_InfoType infoType, void *buf, T_UWORD id);

4.2.1.10

vmkAccessVM

Access the memory space of VM. T_VMK_ReturnCode vmkAccessVM(T_UWORD vmID, T_VMK_AccessType accessType, T_VOID *address, T_UWORD size, T_VOID *buf);

4.2.1.11

vmkAttachVM

Set VM to the debugging status and suspend the VM. T_VMK_ReturnCode vmkAttachVM(T_UWORD vmID);

4.2.1.12

vmkDetachVM

Remove the debugging status of VM and resume its normal status if it is in suspend mode. T_VMK_ReturnCode vmkDetachVM(T_UWORD vmID);

4.2.1.13

vmkGetExceptionVM

Get the VM which is in exception status. T_VMK_ReturnCode vmkGetExceptionVM(T_UWORD *vmID);

CHAPTER 4. HOW THE MACHINE DESIGNED

4.2.1.14

60

vmkAccessContext

Retrieve and store the context of a VM. T_VMK_ReturnCode vmkAccessContext(T_UWORD vmID, T_VMK_AccessType type, T_VOID *buf);

4.2.1.15

vmkResetVM

Reset a VM. T_VMK_ReturnCode vmkResetVM(T_UWORD vmID, T_VMK_SchedType type);

4.2.2

Specifications for Virtual Interrupts

4.2.2.1

vmkInitializeVint

To install the virtual interrupt routines of the current VM in SVMK so that the SVMK will be able to deliver the virtual interrupts to the VM. The interrupts to be delivered include tick interrupt, external interrupts, service interrupts and exception interrupts. T_VMK_ReturnCode vmkInitializeVint(T_VMK_VMVintMask *vintMask, T_VOID *handler);

4.2.2.2

vmkEnablePIC

Enable the designated external interrupts of the current VM. T_VMK_ReturnCode vmkEnablePIC(T_UWORD intNum);

4.2.2.3

vmkDisablePIC

Disable the designated external interrupts of the current VM. T_VMK_ReturnCode vmkDisablePIC(T_UWORD intNum);

4.2.2.4

vmkSendServiceInt

Send the virtual service interrupts from a VM to another VM. The virtual service interrupts can be sent to VM itself.

CHAPTER 4. HOW THE MACHINE DESIGNED

61

T_VMK_ReturnCode vmkSendServiceInt(T_UWORD vmID, T_UWORD serviceIntNum);

4.2.2.5

vmkAckException

Acknowledge the exception interrupt being handled correctly. T_VMK_ReturnCode vmkAckException(T_VOID);

4.2.2.6

vmkDispatchInt

To deliver the external interrupts. T_UWORD vmkDispatchInt(T_UWORD vector);

4.2.2.7

vmkDispatchInt

Get the virtual interrupts from current VM. T_VMK_ReturnCode vmkGetVint(T_UWORD *vintType, T_UWORD *vintNum, T_UWORD *entry);

4.2.3

Specifications for TTS

There are totally 5 system service routines for time-table scheduling services. 4.2.3.1

vmkInstallTTS

Install a time-table. T_VMK_ReturnCode vmkInstallTTS(T_UWORD ttsID, T_VMK_TTSNode *table, T_UWORD count, T_UWORD mainFrameTicks);

4.2.3.2

vmkGetTTSID

Get the ID of a time-table.

CHAPTER 4. HOW THE MACHINE DESIGNED

62

T_VMK_ReturnCode vmkGetTTSID(T_UBYTE *ttsName, T_UWORD *ttsID);

4.2.3.3

vmkGetTTSName

Get the name of a time-table. T_VMK_ReturnCode vmkGetTTSName(T_UWORD ttsID, T_UBYTE *ttsName);

4.2.3.4

vmkStartTTS

Start a time-table. T_VMK_ReturnCode vmkStartTTS(T_UWORD ttsID);

4.2.3.5

vmkStopTTS

Stop a time-table. T_VMK_ReturnCode vmkStopTTS(T_VOID);

4.2.4

Specifications for Initialization

T_VOID vmkInit(T_VOID);

4.2.5

Specifications for Scheduling

4.2.5.1

vmkSchedule

Reschedule according to the VM selected from the priority-based scheduling and time-table based schedule policy. T_VOID vmkSchedule(T_VOID);

4.2.5.2

vmkSetVMReady

Set VM to ready status. T_VOID vmkSetVMReady(T_VMK_VMControlBlock *vm);

CHAPTER 4. HOW THE MACHINE DESIGNED

4.2.5.3

63

vmkClearVMReady

Clear the ready status of VM. T_VOID vmkClearVMReady(T_VMK_VMControlBlock *vm);

4.2.5.4

vmkExactWaitedVM

Remove the VM from the time-waiting queue. T_VOID vmkExactWaitedVM(T_VMK_VMControlBlock *vm);

4.2.5.5

ClearVMWaiting

Clear the time-waiting status of VM. T_VOID vmkClearVMWaiting(T_VMK_VMControlBlock *vm);

4.2.5.6

vmkTickNotify

Time notify including system tick, window-time for time-table and main frame time for time-table. T_UWORD vmkTickNotify(T_VMK_TickNotifyType type);

4.2.6

Specifications for Health Monitor

4.2.6.1

vmkDispatchHM

To deliver exceptions. T_VOID vmkDispatchHM(T_UWORD vector, T_VMK_HMType type, T_VOID *context);

4.2.6.2

vmkInformHM

Exception processing in VM. T_VMK_HMAction vmkInformHM(T_VMK_HMType type, T_VOID *context);

CHAPTER 4. HOW THE MACHINE DESIGNED

4.2.7

64

Specifications for Hooks

There are 9 hooks which can be classified into three categories: • Hooks for system initialization, startup and idle. • Hooks for entering and exiting from VM. • Hooks for SVMK level exception processing on reseting, shutting-down, and ignoring operations. T_VOID vmkIdleHook(T_VOID); T_VOID vmkHMResetHook(T_UWORD vector, T_VMK_HMType type, T_VOID *context); T_VOID vmkHMShutDownHook(T_UWORD vector, T_VMK_HMType type, T_VOID *context); T_VOID vmkHMIgnoreHook(T_UWORD vector, T_VMK_HMType type, T_VOID *context); T_VOID vmkVMEnterHook(T_VOID); T_VOID vmkVMLeaveHook(T_VOID); T_VOID vmkInitHook(T_VOID); T_VOID vmkStartHook(T_VOID); T_VMK_ReturnCode vmkNullSysCall(T_VOID);

4.3

Instructions for Operating System Kernel

As we have stated before that we will treat the group of operations defined in the system service routines and interface routines which are not interruptable as the instructions of the operating system machine. Take a look at the system service routine vmkStartVM. #include "vmkBase.h" #include "vmkHal.h" T_VMK_ReturnCode vmkStartVM(T_UWORD vmID, T_VMK_SchedType type) { T_VMK_VMControlBlock *vm; KBSP_MSR_TYPE msr; /* Only VMM can use this system service routine */ if (vmkManager.runningVM->object.id != VMK_VMM_ID) return VMK_INVALID_USER; /*

CHAPTER 4. HOW THE MACHINE DESIGNED

65

vmkManager.vmNumber is the maximal number of VMs, VM is indexed from 0 */ else if (vmID >= vmkManager.vmNumber) return VMK_INVALID_ID; else { vm = &((vmkManager.vmTable + vmID)->vm); /* VM must be non-started status */ if (vm->status != VMK_VM_DORMANT) return VMK_INVALID_STATE; /* Only two scheduling type: time table based and priority based */ else if ((type != VMK_SCHED_TIME_TABLE) && (type != VMK_SCHED_PRIORITY)) return VMK_INVALID_TYPE; else { /* Start VM */ vm->schedType = type; vm->status = VMK_VM_FIRSTRUN; /* Dealing with priority bitmap, ready VM queue and time-table based scheduling, need to disable the interrupt for mutual exclusion operation */ KBSP_GLOBALINT_DISABLE(msr); vmkSetVMReady(vm); KBSP_GLOBALINT_ENABLE(msr); /* There might be VMs into ready status, need to re-scheduling */ vmkSchedule(); return VMK_OK; } } }

There are two interface routines need to be invoked with interrupt disabled: vmkSetVMReady and vmkSchedule. In an actual implementation, vmkSchedule is divided into three parts, each part should be invoked with interrupt disabled. However, for simplicity, we will treat the routine as the whole. So we may have vmkSetVMReady and vmkSchedule to be designed the instructions in our operating system kernel machine.

CHAPTER 4. HOW THE MACHINE DESIGNED

4.4

66

Data Structures of SVMK

The following C code shows the data structure of manager of SVMK which will become a built-in structure in abstract machine TM-2. typedef struct { T_UWORD status; T_UWORD vmkTicks; T_VMK_VMControlBlock T_VMK_VMControlBlock T_VMK_VMControlBlock T_VMK_VMControlBlock

*runningVM; *ttsVM; *priorityQueueVM; *idleVM;

T_UWORD *intDispatchTable; T_VMK_TTSControlBlock *currentTTS; T_VMK_TTSControlBlock *ttsTable; T_VMK_VMControlBlockWithStack *vmTable; T_VMK_ChainControl tickWaitedVM; T_VMK_ChainControl exceptionVM; T_VMK_ChainControl priorityQueue[VMK_PRIORITY_NUMBER]; T_UWORD vmNumber; T_UWORD ttsNumber; T_VMK_MemoryBlock *vmkSpace; } T_VMK_VMKManager;

4.5

Interrupts and Virtual Interrupts

In computing, an interrupt is an asynchronous signal indicating the need for attention or a synchronous event in software indicating the need for a change in execution. A hardware interrupt causes the processor to save its state of execution and begin execution of an interrupt handler. Software interrupts are usually implemented as instructions in the instruction set, which cause a context switch to an interrupt handler similar to a hardware interrupt. Interrupts are a commonly used technique for computer multitasking, especially in real-time computing. Such a system is said to be interrupt-driven. An act of interrupting is referred to as an interrupt request (IRQ).

CHAPTER 4. HOW THE MACHINE DESIGNED

4.5.1

67

Overview

Hardware interrupts were introduced as a way to avoid wasting the processor’s valuable time in polling loops, waiting for external events. They may be implemented in hardware as a distinct system with control lines, or they may be integrated into the memory subsystem. If implemented in hardware, an interrupt controller circuit such as the IBM PC’s Programmable Interrupt Controller (PIC) may be connected between the interrupting device and the processor’s interrupt pin to multiplex several sources of interrupt onto the one or two CPU lines typically available. If implemented as part of the memory controller, interrupts are mapped into the system’s memory address space. Interrupts can be categorized into: maskable interrupt (IRQ), non-maskable interrupt (NMI), interprocessor interrupt (IPI), software interrupt, and spurious interrupt. • A maskable interrupt (IRQ) is a hardware interrupt that may be ignored by setting a bit in an interrupt mask register’s (IMR) bit-mask. • Likewise, a non-maskable interrupt (NMI) is a hardware interrupt that lacks an associated bit-mask, so that it can never be ignored. NMIs are often used for timers, especially watchdog timers. • An interprocessor interrupt is a special case of interrupt that is generated by one processor to interrupt another processor in a multiprocessor system. • A software interrupt is an interrupt generated within a processor by executing an instruction. Software interrupts are often used to implement system service calls because they implement a subroutine call with a CPU ring level change. • A spurious interrupt is a hardware interrupt that is unwanted. They are typically generated by system conditions such as electrical interference on an interrupt line or through incorrectly designed hardware. Processors typically have an internal interrupt mask which allows software to ignore all external hardware interrupts while it is set. This mask may offer faster access than accessing an interrupt mask register (IMR) in a PIC, or disabling interrupts in the device itself. In some cases, such as the x86 architecture, disabling and enabling interrupts on the processor itself acts as a memory barrier, in which case it may actually be slower. An interrupt that leaves the machine in a well-defined state is called a precise interrupt. Such an interrupt has four properties: • The Program Counter (PC) is saved in a known place. • All instructions before the one pointed to by the PC have fully executed.

CHAPTER 4. HOW THE MACHINE DESIGNED

68

• No instruction beyond the one pointed to by the PC has been executed (that is no prohibition on instruction beyond that in PC, it is just that any changes they make to registers or memory must be undone before the interrupt happens). • The execution state of the instruction pointed to by the PC is known. An interrupt that does not meet these requirements is called an imprecise interrupt. The phenomenon where the overall system performance is severely hindered by excessive amounts of processing time spent handling interrupts is called an interrupt storm.

4.5.2

Types of Interrupts

4.5.2.1

Level-Triggered

A level-triggered interrupt is a class of interrupts where the presence of an unserviced interrupt is indicated by a high level (1), or low level (0), of the interrupt request line. A device wishing to signal an interrupt drives the line to its active level, and then holds it at that level until serviced. It ceases asserting the line when the CPU commands it to or otherwise handles the condition that caused it to signal the interrupt. Typically, the processor samples the interrupt input at predefined times during each bus cycle such as state T2 for the Z80 microprocessor. If the interrupt isn’t active when the processor samples it, the CPU doesn’t see it. One possible use for this type of interrupt is to minimize spurious signals from a noisy interrupt line: a spurious pulse will often be so short that it is not noticed. Multiple devices may share a level-triggered interrupt line if they are designed to. The interrupt line must have a pull-down or pull-up resistor so that when not actively driven it settles to its inactive state. Devices actively assert the line to indicate an outstanding interrupt, but let the line float (do not actively drive it) when not signalling an interrupt. The line is then in its asserted state when any (one or more than one) of the sharing devices is signalling an outstanding interrupt. This class of interrupts is favored by some because of a convenient behavior when the line is shared. Upon detecting assertion of the interrupt line, the CPU must search through the devices sharing it until one requiring service is detected. After servicing this device, the CPU may recheck the interrupt line status to determine whether any other devices also need service. If the line is now deasserted, the CPU avoids checking the remaining devices on the line. Since some devices interrupt more frequently than others, and other device interrupts are particularly expensive, a careful ordering of device checks is employed to increase efficiency.

CHAPTER 4. HOW THE MACHINE DESIGNED

69

There are also serious problems with sharing level-triggered interrupts. As long as any device on the line has an outstanding request for service the line remains asserted, so it is not possible to detect a change in the status of any other device. Deferring servicing a low-priority device is not an option, because this would prevent detection of service requests from higher-priority devices. If there is a device on the line that the CPU does not know how to service, then any interrupt from that device permanently blocks all interrupts from the other devices. The original PCI standard mandated shareable level-triggered interrupts. The rationale for this was the efficiency gain discussed above. (Newer versions of PCI allow, and PCI Express requires the use of message-signalled interrupts.) 4.5.2.2

Edge-Triggered

An edge-triggered interrupt is a class of interrupts that are signalled by a level transition on the interrupt line, either a falling edge (1 to 0) or a rising edge (0 to 1). A device wishing to signal an interrupt drives a pulse onto the line and then releases the line to its quiescent state. If the pulse is too short to be detected by polled I/O then special hardware may be required to detect the edge. Multiple devices may share an edge-triggered interrupt line if they are designed to. The interrupt line must have a pull-down or pull-up resistor so that when not actively driven it settles to one particular state. Devices signal an interrupt by briefly driving the line to its non-default state, and let the line float (do not actively drive it) when not signalling an interrupt. This type of connection is also referred to as open collector. The line then carries all the pulses generated by all the devices. (This is analogous to the pull cord on some buses and trolleys that any passenger can pull to signal the driver that they are requesting a stop.) However, interrupt pulses from different devices may merge if they occur close in time. To avoid losing interrupts the CPU must trigger on the trailing edge of the pulse (e.g. the rising edge if the line is pulled up and driven low). After detecting an interrupt the CPU must check all the devices for service requirements. Edge-triggered interrupts do not suffer the problems that level-triggered interrupts have with sharing. Service of a low-priority device can be postponed arbitrarily, and interrupts will continue to be received from the high-priority devices that are being serviced. If there is a device that the CPU does not know how to service, it may cause a spurious interrupt, or even periodic spurious interrupts, but it does not interfere with the interrupt signalling of the other devices. However, it is fairly easy for an edge triggered interrupt to be missed - for example if interrupts have to be masked for a period - and unless there is some type of hardware latch that records the event it is impossible to recover. Such problems caused many ”lockups” in early computer hardware because the processor did not know it was expected to do something. More modern hard-

CHAPTER 4. HOW THE MACHINE DESIGNED

70

ware often has one or more interrupt status registers that latch the interrupt requests; well written edge-driven interrupt software often checks such registers to ensure events are not missed. The elderly Industry Standard Architecture (ISA) bus uses edge-triggered interrupts, but does not mandate that devices be able to share them. The parallel port also uses edge-triggered interrupts. Many older devices assume that they have exclusive use of their interrupt line, making it electrically unsafe to share them. However, ISA motherboards include pull-up resistors on the IRQ lines, so well-behaved devices share ISA interrupts just fine. 4.5.2.3

Hybrid

Some systems use a hybrid of level-triggered and edge-triggered signalling. The hardware not only looks for an edge, but it also verifies that the interrupt signal stays active for a certain period of time. A common use of a hybrid interrupt is for the NMI (non-maskable interrupt) input. Because NMIs generally signal major C or even catastrophic C system events, a good implementation of this signal tries to ensure that the interrupt is valid by verifying that it remains active for a period of time. This 2-step approach helps to eliminate false interrupts from affecting the system. 4.5.2.4

Message-Signalled

A message-signalled interrupt does not use a physical interrupt line. Instead, a device signals its request for service by sending a short message over some communications medium, typically a computer bus. The message might be of a type reserved for interrupts, or it might be of some pre-existing type such as a memory write. Message-signalled interrupts behave very much like edge-triggered interrupts, in that the interrupt is a momentary signal rather than a continuous condition. Interrupt-handling software treats the two in much the same manner. Typically, multiple pending message-signalled interrupts with the same message (the same virtual interrupt line) are allowed to merge, just as closely-spaced edge-triggered interrupts can merge. Message-signalled interrupt vectors can be shared, to the extent that the underlying communication medium can be shared. No additional effort is required. Because the identity of the interrupt is indicated by a pattern of data bits, not requiring a separate physical conductor, many more distinct interrupts can be efficiently handled. This reduces the need for sharing. Interrupt messages can also be passed over a serial bus, not requiring any additional lines. PCI Express, a serial computer bus, uses message-signalled interrupts exclusively.

CHAPTER 4. HOW THE MACHINE DESIGNED

4.5.2.5

71

Doorbell

In a push button analogy applied to computer systems, the term doorbell or doorbell interrupt is often used to describe a mechanism whereby a software system can signal or notify a hardware device that there is some work to be done. Typically, the software system will place data in some well known and mutually agreed upon memory location(s), and ”ring the doorbell” by writing to a different memory location. This different memory location is often called the doorbell region, and there may even be multiple doorbells serving different purposes in this region. It’s this act of writing to the doorbell region of memory that ”rings the bell” and notifies the hardware device that the data is ready and waiting. The hardware device would now know that the data is valid and can be acted upon. It would typically write the data to a hard disk drive, or send it over a network, or encrypt it, etc. The term doorbell interrupt is usually a misnomer. It’s similar to an interrupt because it causes some work to be done by the device, however the doorbell region is sometimes implemented as a polled region, sometimes the doorbell region writes through to physical device registers, and sometimes the doorbell region is hardwired directly to physical device registers. When either writing through or directly to physical device registers, this may, but not necessarily, cause a real interrupt to occur at the device’s central processor unit (CPU), if it has one. Doorbell interrupts can be compared to Message Signaled Interrupts, as they have some similarities.

4.5.3

Difficulty with Sharing Interrupt Lines

Multiple devices sharing an interrupt line (of any triggering style) all act as spurious interrupt sources with respect to each other. With many devices on one line the workload in servicing interrupts grows in proportion to the square of the number of devices. It is therefore preferred to spread devices evenly across the available interrupt lines. Shortage of interrupt lines is a problem in older system designs where the interrupt lines are distinct physical conductors. Message-signalled interrupts, where the interrupt line is virtual, are favoured in new system architectures (such as PCI Express) and relieve this problem to a considerable extent. Some devices with a badly-designed programming interface provide no way to determine whether they have requested service. They may lock up or otherwise misbehave if serviced when they do not want it. Such devices cannot tolerate spurious interrupts, and so also cannot tolerate sharing an interrupt line. ISA cards, due to often cheap design and construction, are notorious for this problem. Such devices are becoming much rarer, as hardware logic becomes cheaper and new system architectures mandate shareable interrupts.

CHAPTER 4. HOW THE MACHINE DESIGNED

4.5.4

72

Performance Issues

Interrupts provide low overhead and good latency at low offered load, but degrade significantly at high interrupt rate unless care is taken to prevent several pathologies. These are various forms of livelocks, when the system spends all of its time processing interrupts, to the exclusion of other required tasks. Under extreme conditions, a large number of interrupts (like very high network traffic) may completely stall the system. To avoid such problems, an operating system must schedule network interrupt handling as carefully as it schedules process execution.

4.5.5

Typical Uses

Typical uses of interrupts include the following: system timers, disks I/O, poweroff signals, and traps. Other interrupts exist to transfer data bytes using UARTs or Ethernet; sense key-presses; control motors; or anything else the equipment must do. A classic system timer interrupt interrupts periodically from a counter or the power-line. The interrupt handler counts the interrupts to keep time. The timer interrupt may also be used by the OS’s task scheduler to reschedule the priorities of running processes. Counters are popular, but some older computers used the power line frequency instead, because power companies in most countries control the power-line frequency with a very accurate atomic clock. A disk interrupt signals the completion of a data transfer from or to the disk peripheral. A process waiting to read or write a file starts up again. A power-off interrupt predicts or requests a loss of power. It allows the computer equipment to perform an orderly shutdown. Interrupts are also used in typeahead features for buffering events like keystrokes.

4.5.6

Interrupt Handler

An interrupt handler, also known as an interrupt service routine (ISR), is a callback subroutine in an operating system or device driver whose execution is triggered by the reception of an interrupt. Interrupt handlers have a multitude of functions, which vary based on the reason the interrupt was generated and the speed at which the interrupt handler completes its task. An interrupt handler is a low-level counterpart of event handlers. These handlers are initiated by either hardware interrupts or interrupt instructions in software, and are used for servicing hardware devices and transitions between protected modes of operation such as system calls.

CHAPTER 4. HOW THE MACHINE DESIGNED

4.5.6.1

73

Classification of Interrupt Handlers

In modern operating systems, interrupt handlers are divided into two parts: the First-Level Interrupt Handler (FLIH) and the Second-Level Interrupt Handlers (SLIH). FLIHs are also known as hard interrupt handlers, fast interrupt handlers and top-half of interrupt, and SLIHs are also known as interrupt threads, slow/soft interrupt handlers and bottom-half of interrupt. A FLIH implements at minimum platform-specific interrupt handling similarly to interrupt routines. In response to an interrupt, there is a context switch, and the code for the interrupt is loaded and executed. The job of a FLIH is to quickly service the interrupt, or to record platform-specific critical information which is only available at the time of the interrupt, and schedule the execution of a SLIH for further long-lived interrupt handling. FLIHs cause jitter in process execution. FLIHs also mask interrupts. Reducing the jitter is most important for real-time operating systems, since they must maintain a guarantee that execution of specific code will complete within an agreed amount of time. To reduce jitter and to reduce the potential for losing data from masked interrupts, programmers attempt to minimize the execution time of a FLIH, moving as much as possible to the SLIH. With the speed of modern computers, FLIHs may implement all device and platform-dependent handling, and use a SLIH for further platform-independent long-lived handling. FLIHs which service hardware typically mask their associated interrupt (or keep it masked as the case may be) until they complete their execution. An (unusual) FLIH which unmasks its associated interrupt before it completes is called a reentrant interrupt handler. Reentrant interrupt handlers might cause a stack overflow from multiple preemptions by the same interrupt vector, and so they are usually avoided. In a priority interrupt system, the FLIH also (briefly) masks other interrupts of equal or lesser priority. A SLIH completes long interrupt processing tasks similarly to a process. SLIHs either have a dedicated kernel thread for each handler, or are executed by a pool of kernel worker threads. These threads sit on a run queue in the operating system until processor time is available for them to perform processing for the interrupt. SLIHs may have a long-lived execution time, and thus are typically scheduled similarly to threads and processes. It is worth noting that in many systems the FLIH and SLIH are referred to as upper halves and lower halves, hardware and software interrupts, or a derivation of those names. 4.5.6.2

Interrupt Threads

Several operating systems - Solaris, NetBSD, Mac OS X, WinCE and FreeBSD, for example - use different scheme known as interrupt threads: interrupt handler is just a high-priority thread which runs with interrupts enabled and, more importantly, may block on mutex. This greatly simplifies locking in

CHAPTER 4. HOW THE MACHINE DESIGNED

74

the kernel. Also, interrupt thread may be preempted by higher-priority interrupt thread.

4.5.7

Interrupt Latency

In real-time operating systems, interrupt latency is the time between the generation of an interrupt by a device and the servicing of the device which generated the interrupt. For many operating systems, devices are serviced as soon as the device’s interrupt handler is executed. Interrupt latency may be affected by interrupt controllers, interrupt masking, and the operating system’s (OS) interrupt handling methods. 4.5.7.1

Background

There is usually a tradeoff between interrupt latency, throughput, and processor utilization. Many of the techniques of CPU and OS design that improve interrupt latency will decrease throughput and increase processor utilization. Techniques that increase throughput may increase interrupt latency and increase processor utilization. Lastly, trying to reduce processor utilization may increase interrupt latency and decrease throughput. Minimum interrupt latency is largely determined by the interrupt controller circuit and its configuration. They can also affect the jitter in the interrupt latency, which can drastically affect the real-time schedulability of the system. The Intel APIC Architecture is well known for producing a huge amount of interrupt latency jitter. Maximum interrupt latency is largely determined by the methods an OS uses for interrupt handling. For example, most processors allow programs to disable interrupts, putting off the execution of interrupt handlers, in order to protect critical sections of code. During the execution of such a critical section, all interrupt handlers that cannot execute safely within a critical section are blocked (they save the minimum amount of information required to restart the interrupt handler after all critical sections have exited). So the interrupt latency for a blocked interrupt is extended to the end of the critical section, plus any interrupts with equal and higher priority that arrived while the block was in place. Many computer systems require low interrupt latencies, especially embedded systems that need to control machinery in real-time. Sometimes these systems use a real-time operating system (RTOS). An RTOS makes the promise that no more than an agreed upon maximum amount of time will pass between executions of subroutines. In order to do this, the RTOS must also guarantee that interrupt latency will never exceed a predefined maximum.

CHAPTER 4. HOW THE MACHINE DESIGNED

4.5.7.2

75

Considerations

There are many methods that hardware may use to increase the interrupt latency that can be tolerated. These include buffers, and flow control. For example, most network cards implement transmit and receive ring buffers, interrupt rate limiting, and hardware flow control. Buffers allow data to be stored until it can be transferred, and flow control allows the network card to pause communications without having to discard data if the buffer is full. Modern hardware also implements interrupt rate limiting. This helps prevent interrupt storms or live lock by having the hardware wait a programmable minimum amount of time between each interrupt it generates. Interrupt rate limiting reduces the amount of time spent servicing interrupts, allowing the processor to spend more time doing useful work. Exceeding this time results in a soft (recoverable) or hard (non-recoverable) error.

Chapter 5

The Extended Machine 5.1

The Instruction Set

The instruction set of the TM is given together with a brief description of the effect of each instruction. There are two basic instruction formats: register-only, or RO instructions, and register-memory, or RM instructions.

5.1.1

RO-Instruction Set

A register-only instruction has the format opcode r, s, t where the operands r, s, t are legal registers (checked at load time). Thus, such instructions are three address, and all three addresses must be registers. All arithmetic instructions are limited to this format. There are totally 42 RO instructions. Among them only 12 instructions are basic instructions from the basic machine. The rest of 30 instructions are operating system kernel related which are the extension of the basic one. 5.1.1.1

The Basic RO-Instruction Set

• IRET: Return from ISR • HALT: Stop execution (operands ignored) • ADD: reg[r] T -> T T];

5.1.1.5

-> -> -> -> -> ->

T T T T T T

-> -> -> -> -> ->

T T T T T T

-> -> -> -> -> ->

T T T T T T

-> -> -> -> -> ->

T -> T ->

T -> T -> T -> T ->

Basic Instructions for Computing and Control

dec dec dec dec dec dec

IRET HALT TMADD TMSUB TMMUL TMDIV

: : : : : :

ROOpcode; ROOpcode; ROOpcode; ROOpcode; ROOpcode; ROOpcode;

dec dec dec dec dec

TMBITAND TMBITOR TMBITMASK TMBITANDMATCH TMBITORMATCH

: : : : :

ROOpcode; ROOpcode; ROOpcode; ROOpcode; ROOpcode;

CHAPTER 5. THE EXTENDED MACHINE

dec TMBITSHIFTL dec TMBITSHIFTR

5.1.1.6 dec dec dec dec dec dec

dec dec dec dec dec dec dec dec

dec dec dec dec dec dec

: : : : : :

ROOpcode; ROOpcode; ROOpcode; ROOpcode; ROOpcode; ROOpcode;

Instructions for Virtual Interruption Management

VIRET EPIC DPIC SSINT VAE TVI INTP IVTI

5.1.1.8

: ROOpcode; : ROOpcode;

Instructions for VMK Manager

MAN_GET MAN_SET VM_GET VM_SET TTS_GET TTS_SET

5.1.1.7

80

: : : : : : : :

ROOpcode; ROOpcode; ROOpcode; ROOpcode; ROOpcode; ROOpcode; ROOpcode; ROOpcode;

Instructions for Scheduling

SCHEDULE SET_VM_READY CLEAR_VM_READY EXACT_VM_WAIT CLEAR_VM_WAIT TICK_NOTIFY

: : : : : :

ROOpcode; ROOpcode; ROOpcode; ROOpcode; ROOpcode; ROOpcode;

The SCHEDULE can be splitted further into the following five instructions, if we will not consider the SCHEDULE instruction as an atomic operation. dec dec dec dec dec

SV_CONT SW_CONT CL_PQ GT_PQ AD_PQ

: : : : :

ROOpcode; ROOpcode; ROOpcode; ROOpcode; ROOpcode;

CHAPTER 5. THE EXTENDED MACHINE

5.1.1.9 dec dec dec dec dec dec dec dec dec

Instructions for Location List

INSERT_WVM VLOC_IN VLOC_GET VLOC_SET VLOC_DEL VLOC_EMPY VLOC_HEAD VLOC_TAIL VLOC_CONS

5.1.1.10

81

: : : : : : : : :

ROOpcode; ROOpcode; ROOpcode; ROOpcode; ROOpcode; ROOpcode; ROOpcode; ROOpcode; ROOpcode;

The Definition of ROInstr

In terms of PowerEpsilon, ROInstr are defined as the following. def ROInstr = !(T : Prop) [[ROOpcode -> Nat -> Nat -> Nat -> T] -> T]; dec MK_ROINST : [ROOpcode -> Nat -> Nat -> Nat -> ROInstr]; def MK_ROINST = \(o : ROOpcode, r : Nat, s : Nat, t : Nat) \(T : Prop) \(i : [ROOpcode -> Nat -> Nat -> Nat -> T]) @(i, o, r, s, t);

5.1.2

RM-Instruction Set

A register-memory instruction has the format opcode r, d(s) In this code r and s must be legal registers (checked at load time), and d is a positive or negative integer representing an offset. This instruction is a two-address instruction, where the first address is always a register and the second address is a memory address a given by a = d + reg[r], where a must be a legal address (0 ≤ a < DADDR SIZE). If a is out of the legal range, then DMEM ADDR is generated during execution. • LD: reg[r] = dMEM[a] (load r with memory value at a) • LDA: reg[r] = a (load address a directly into r)

CHAPTER 5. THE EXTENDED MACHINE

82

• LDC: reg[r] = d (load constant d directly into r - s is ignored) • ST: dMEM[a] = reg[r] (store value in r to memory location a) • JLT: If (reg[r] < 0) reg[PC REG] = a (jump to instruction a if r is negative, similarly for the following) • JLE: If (reg[r] ≤ 0) reg[PC REG] = a • JGT: If (reg[r] > 0) reg[PC REG] = a • JGE: If (reg[r] ≥ 0) reg[PC REG] = a • JEQ: If (reg[r] = 0) reg[PC REG] = a • JNE: If (reg[r] ̸= 0) reg[PC REG] = a where a = d + reg[s]; any reference to dMEM[a] generates DMEM ERR if a ≤ 0 or a ≥ DADDR SIZE. The RM instruction set is defined as same as in the basic machine. The differences will be seen in the semantic definitions for LD, LDA, LDC and ST. 5.1.2.1

Instructions for Computing and Control

def RMOpcode = !(T : Prop) [T -> T -> T -> T -> T -> T -> T -> T -> T -> T -> T];

dec dec dec dec dec dec dec dec dec dec

LD LDA LDC ST JLT JLE JGE JGT JEQ JNE

: : : : : : : : : :

RMOpcode; RMOpcode; RMOpcode; RMOpcode; RMOpcode; RMOpcode; RMOpcode; RMOpcode; RMOpcode; RMOpcode;

dec dec dec dec

IS_LD IS_LDA IS_LDC IS_ST

: : : :

[RMOpcode [RMOpcode [RMOpcode [RMOpcode

-> -> -> ->

Bool]; Bool]; Bool]; Bool];

CHAPTER 5. THE EXTENDED MACHINE

5.1.2.2

83

The Definition of RMInstr

In terms of PowerEpsilon, RMInstr are defined as the following. def RMInstr = !(T : Prop) [[RMOpcode -> Nat -> Int -> Nat -> T] -> T]; dec MK_RMINST : [RMOpcode -> Nat -> Int -> Nat -> RMInstr]; def MK_RMINST = \(o : RMOpcode, r : Nat, d : Int, s : Nat) \(T : Prop) \(i : [RMOpcode -> Nat -> Int -> Nat -> T]) @(i, o, r, d, s); dec dec dec dec

GET_RMINST_OP GET_RMINST_R GET_RMINST_D GET_RMINST_S

5.1.3

: : : :

[RMInstr [RMInstr [RMInstr [RMInstr

-> -> -> ->

RMOpcode]; Nat]; Int]; Nat];

Instruction Set

We then will have 52 instructions for TM-2. There are 23 instructions are from the basic machine TM and the rest of 29 are designed for describing the functionality of operating system. An instruction is either a RO instruction or a RM instruction. 5.1.3.1

Type Definition of Instr

def Instr = !(T : Prop) [[ROInstr -> T] -> [RMInstr -> T] -> T];

5.1.3.2

Constructors of Instr

def MK_TMRO = \(i : ROInstr) \(T : Prop) \(x : [ROInstr -> T], y : [RMInstr -> T]) @(x, i); def MK_TMRM = \(i : RMInstr)

CHAPTER 5. THE EXTENDED MACHINE

84

\(T : Prop) \(x : [ROInstr -> T], y : [RMInstr -> T]) @(y, i); dec NIL_INSTR : Instr;

5.1.3.3

Predicate Functions of Instr

dec IS_TMRO : [Instr -> Bool]; dec IS_TMRM : [Instr -> Bool];

dec dec dec dec

IS_HALT_INSTR IS_LD_INSTR IS_LDA_INSTR IS_ST_INSTR

: : : :

[Instr [Instr [Instr [Instr

-> -> -> ->

Bool]; Bool]; Bool]; Bool];

dec IS_NIL_INSTR : [Instr -> Bool];

5.1.3.4

Projectors of Instr

dec GET_TMRO : [Instr -> ROInstr]; dec GET_TMRM : [Instr -> RMInstr];

5.1.4

TM Instructions

5.1.4.1

Definition of TM Instruction

A TM instruction is an instruction together with a location number attached. def TMInstr = !(T : Prop) [[Nat -> Instr -> T] -> T]; def MK_TMINST = \(loc : Nat, ins : Instr) \(T : Prop) \(m : [Nat -> Instr -> T]) @(m, loc, ins); dec GET_TMINST_NUMB : [TMInstr -> Nat]; dec GET_TMINST_INST : [TMInstr -> Instr];

CHAPTER 5. THE EXTENDED MACHINE

5.1.4.2

TM Instruction Sequence

def TMInstrList = @(List, TMInstr); dec EMPTY_TLST : TMInstrList; dec ENTER_TLST : [TMInstr -> TMInstrList -> TMInstrList]; dec IS_EMPTY_TLST : [TMInstrList -> Bool]; dec HEAD_TLST : [TMInstrList -> TMInstr]; dec TAIL_TLST : [TMInstrList -> TMInstrList];

5.1.5

Translation from C to TM-2

We have the following service routine for starting a VM: #include "vmkBase.h" #include "vmkHal.h" T_VMK_ReturnCode vmkStartVM(T_UWORD vmID, T_VMK_SchedType type) { T_VMK_VMControlBlock *vm; KBSP_MSR_TYPE msr; /* Only VMM can use this interface */ if (vmkManager.runningVM->object.id != VMK_VMM_ID) return VMK_INVALID_USER; /* vmkManager.vmNumber is the maximal number of VMs, */ /* the number of VMs is starting from 0 */ else if (vmID >= vmkManager.vmNumber) return VMK_INVALID_ID; else { vm = &((vmkManager.vmTable + vmID)->vm); /* VM has not been started */ if (vm->status != VMK_VM_DORMANT) return VMK_INVALID_STATE; /* There are only two scheduling type - time table and priority */ else if ((type != VMK_SCHED_TIME_TABLE) && (type != VMK_SCHED_PRIORITY)) return VMK_INVALID_TYPE; else { /* Start VM */ vm->schedType = type; vm->status = VMK_VM_FIRSTRUN; /* Need to disable the interrupt for the operations on */ /* priority bit map, ready VM linked list and time table */

85

CHAPTER 5. THE EXTENDED MACHINE

KBSP_GLOBALINT_DISABLE(msr); vmkSetVMReady(vm); KBSP_GLOBALINT_ENABLE(msr); /* There will be additional VMs ready, need to re-scheduling */ vmkSchedule(); return VMK_OK; } } }

The main part of code in this function is the following /* Start VM */ vm->schedType = type; vm->status = VMK_VM_FIRSTRUN; /* Need to disable the interrupt for the operations on */ /* priority bit map, ready VM linked list and time table */ KBSP_GLOBALINT_DISABLE(msr); vmkSetVMReady(vm); KBSP_GLOBALINT_ENABLE(msr); /* There will be additional VMs ready, need to re-scheduling */ vmkSchedule();

The part of code can be translated into the following TM-2 code. LD AC_REG, 0(MP_REG) VMCB_GET VM_SCTY_REG, AC_REG, +5(FP_REG) VMCB_GET VM_STAT_REG, AC_REG, d1(GP_REG) SET_VM_READY AC_REG, AC_REG, AC_REG SCHEDULE LD AC_REG, d2(GP_REG) ST AC_REG, +4(FP_REG)

5.2 5.2.1

SVM Manager SVM Status

def SVMKStatus = Nat; dec MkColdStart : Nat; dec MkWarmStart : Nat;

86

CHAPTER 5. THE EXTENDED MACHINE

dec MkNormal dec MkFault dec MkShutdown

5.2.2

: Nat; : Nat; : Nat;

Interrupt Dispatch Table

def VMKLocation = Nat; dec IntDispatchTable : Prop; def IntDispatchTable = @(List, VMKLocation);

5.2.3

Registers of SVM Manager

dec TMReg : Prop; dec VMKMAN_REG_SIZE : Nat; dec dec dec dec dec dec dec dec dec

VMK_STA_REG VMK_TIC_REG VMK_RVM_REG VMK_TVM_REG VMK_PVM_REG VMK_IVM_REG VMK_CTS_REG VMK_VMN_REG VMK_TSN_REG

: : : : : : : : :

Nat; Nat; Nat; Nat; Nat; Nat; Nat; Nat; Nat;

def VMKManReg = @(Array, Bit32Word, VMKMAN_REG_SIZE); def VMKMAN_REG_ASSIGN = \(reg : VMKManReg, indx : Nat, val : Bit32Word) @(ASSIGN, Bit32Word, VMKMAN_REG_SIZE, reg, indx, val); def VMKMAN_REG_RETRIEVE = \(reg : VMKManReg, indx : Nat) @(RETRIEVE, Bit32Word, VMKMAN_REG_SIZE, reg, indx);

5.2.4

Priority VM Queues

dec VMK_PRIORITY_NUMBER : Nat;

87

CHAPTER 5. THE EXTENDED MACHINE

def PriorityVMQueue = @(Array, @(List, VMKLocation), VMK_PRIORITY_NUMBER);

5.2.5

SVM Manager

5.2.5.1

Type Definition of VMKManager

def VMKManager = !(T : Prop) [[VMKManReg -> IntDispatchTable -> @(List, VMKLocation) -> @(List, VMKLocation) -> PriorityVMQueue -> @(List, VMKLocation) -> T] -> T];

5.2.5.2

Constructor of VMKManager

def MkVMKManager = \(vmkmanreg : VMKManReg, intdisptable : IntDispatchTable, tickwaitedVM : @(List, VMKLocation), exceptionVM : @(List, VMKLocation), priorityQ : PriorityVMQueue, flowlist : @(List, VMKLocation)) \(T : Prop) \(f : [VMKManReg -> IntDispatchTable -> @(List, VMKLocation) -> @(List, VMKLocation) -> PriorityVMQueue -> @(List, VMKLocation) -> T]) @(f, vmkmanreg, intdisptable, tickwaitedVM, exceptionVM, priorityQ, flowlist);

88

CHAPTER 5. THE EXTENDED MACHINE

5.2.5.3

89

Selectors of VMKManager

dec dec dec dec dec dec

GET_VMKMAN_MANREG GET_VMKMAN_INTDIS GET_VMKMAN_TICKWT GET_VMKMAN_EXCPVM GET_VMKMAN_PRIOTQ GET_VMKMAN_FLOWLT

: : : : : :

[VMKManager [VMKManager [VMKManager [VMKManager [VMKManager [VMKManager

-> -> -> -> -> ->

VMKManReg]; IntDispatchTable]; @(List, VMKLocation)]; @(List, VMKLocation)]; PriorityVMQueue]; @(List, VMKLocation)];

dec dec dec dec dec dec dec dec dec

GET_VMKMAN_STATUS GET_VMKMAN_TICKCN GET_VMKMAN_RUNVM GET_VMKMAN_TTSVM GET_VMKMAN_PQUEVM GET_VMKMAN_IDLEVM GET_VMKMAN_CURTTS GET_VMKMAN_VMNUMB GET_VMKMAN_TTSNUM

: : : : : : : : :

[VMKManager [VMKManager [VMKManager [VMKManager [VMKManager [VMKManager [VMKManager [VMKManager [VMKManager

-> -> -> -> -> -> -> -> ->

SVMKStatus]; Nat]; VMKLocation]; VMKLocation]; VMKLocation]; VMKLocation]; VMKLocation]; Nat]; Nat];

5.2.5.4

Modifiers of VMKManager

dec dec dec dec dec dec

SET_VMKMAN_MANREG SET_VMKMAN_INTDIS SET_VMKMAN_TICKWT SET_VMKMAN_EXCPVM SET_VMKMAN_PRIOTQ SET_VMKMAN_FLOWLT

: : : : : :

[VMKManager [VMKManager [VMKManager [VMKManager [VMKManager [VMKManager

-> -> -> -> -> ->

VMKManReg IntDispatchTable @(List, VMKLocation) @(List, VMKLocation) PriorityVMQueue @(List, VMKLocation)

dec dec dec dec dec dec dec dec dec

SET_VMKMAN_STATUS SET_VMKMAN_TICKCN SET_VMKMAN_RUNVM SET_VMKMAN_TTSVM SET_VMKMAN_PQUEVM SET_VMKMAN_IDLEVM SET_VMKMAN_CURTTS SET_VMKMAN_VMNUMB SET_VMKMAN_TTSNUM

: : : : : : : : :

[VMKManager [VMKManager [VMKManager [VMKManager [VMKManager [VMKManager [VMKManager [VMKManager [VMKManager

-> -> -> -> -> -> -> -> ->

SVMKStatus Nat VMKLocation VMKLocation VMKLocation VMKLocation VMKLocation Nat Nat

5.3

-> -> -> -> -> -> -> -> ->

-> -> -> -> -> ->

VMKManager]; VMKManager]; VMKManager]; VMKManager]; VMKManager]; VMKManager];

VMKManager]; VMKManager]; VMKManager]; VMKManager]; VMKManager]; VMKManager]; VMKManager]; VMKManager]; VMKManager];

VM Control Blocks

The only assumption made on VM is that the virtual interruption mechanism contained in each VM.

CHAPTER 5. THE EXTENDED MACHINE

5.3.1

Types of Health Monitoring

dec TMReg : Prop; def HMType = Nat; dec HM_NULL : HMType; dec dec dec dec dec dec

HM_VINT_ISR HM_VINT_SYSCALL HM_VINT_VIRET HM_VINT_EXCEPTION HM_EXCEPTION HM_ERROR_ACTION

dec dec dec dec dec dec

IS_HM_VINT_ISR IS_HM_VINT_SYSCALL IS_HM_VINT_VIRET IS_HM_VINT_EXCEPTION IS_HM_EXCEPTION IS_HM_ERROR_ACTION

5.3.2

: : : : : :

HMType; HMType; HMType; HMType; HMType; HMType; : : : : : :

[HMType [HMType [HMType [HMType [HMType [HMType

-> -> -> -> -> ->

Bool]; Bool]; Bool]; Bool]; Bool]; Bool];

Actions of Health Monitoring

def HMAction = Nat; dec HM_ACTION_NULL : HMAction; dec dec dec dec dec

HM_ACTION_RESET HM_ACTION_SHUTDOWN HM_ACTION_IGNORE HM_ACTION_UPGRADE HM_ACTION_DELIVER

: : : : :

HMAction; HMAction; HMAction; HMAction; HMAction;

dec dec dec dec dec

IS_HM_ACT_RESET IS_HM_ACT_SHUTDOWN IS_HM_ACT_IGNORE IS_HM_ACT_UPGRADE IS_HM_ACT_DELIVER

: : : : :

[HMAction [HMAction [HMAction [HMAction [HMAction

def ExcpCont = @(And, Nat, TMReg); dec NullExcpCont : ExcpCont;

-> -> -> -> ->

Bool]; Bool]; Bool]; Bool]; Bool];

90

CHAPTER 5. THE EXTENDED MACHINE

5.3.3

VM Status

def VMStatus = Bit32Word; dec dec dec dec dec dec dec

VMREADY VMSLEEP VMRUNNING VMSUSPEND VMWAIT VMFIRSTRUN VMDEBUG

: : : : : : :

VMStatus; VMStatus; VMStatus; VMStatus; VMStatus; VMStatus; VMStatus;

dec dec dec dec dec dec dec

IS_VMREADY IS_VMSLEEP IS_VMRUNNING IS_VMSUSPEND IS_VMWAIT IS_VMFIRSTRUN IS_VMDEBUG

: : : : : : :

[VMStatus [VMStatus [VMStatus [VMStatus [VMStatus [VMStatus [VMStatus

-> -> -> -> -> -> ->

Bool]; Bool]; Bool]; Bool]; Bool]; Bool]; Bool];

dec dec dec dec dec dec dec

SetVMREADY SetVMSLEEP SetVMRUNNING SetVMSUSPEND SetVMWAIT SetVMFIRSTRUN SetVMDEBUG

: : : : : : :

[VMStatus [VMStatus [VMStatus [VMStatus [VMStatus [VMStatus [VMStatus

-> -> -> -> -> -> ->

VMStatus]; VMStatus]; VMStatus]; VMStatus]; VMStatus]; VMStatus]; VMStatus];

dec dec dec dec dec dec dec

SetVMNotREADY SetVMNotSLEEP SetVMNotRUNNING SetVMNotSUSPEND SetVMNotWAIT SetVMNotFIRSTRUN SetVMNotDEBUG

: : : : : : :

[VMStatus [VMStatus [VMStatus [VMStatus [VMStatus [VMStatus [VMStatus

-> -> -> -> -> -> ->

VMStatus]; VMStatus]; VMStatus]; VMStatus]; VMStatus]; VMStatus]; VMStatus];

dec InclOrVMStatus : [VMStatus -> VMStatus -> VMStatus]; dec BitAndVMStatus : [VMStatus -> VMStatus -> VMStatus];

5.3.4

VM Scheduling Type

dec VMScheduleType : Prop; def VMScheduleType = Bool;

91

CHAPTER 5. THE EXTENDED MACHINE

def VMScheduleTT = TT; def VMSchedulePr = FF; dec IsVMScheduleTT : [VMScheduleType -> Bool]; dec IsVMSchedulePr : [VMScheduleType -> Bool];

5.3.4.1

VM Wakeup Type

def VMWakeupType = Bit32Word; dec dec dec dec dec

VMWUNull VMWUBasic VMWUTimed VMWUTTSWin VMWUTTSStart

: : : : :

VMWakeupType; VMWakeupType; VMWakeupType; VMWakeupType; VMWakeupType;

dec dec dec dec dec

IS_VMWUNull IS_VMWUBasic IS_VMWUTimed IS_VMWUTTSWin IS_VMWUTTSStart

: : : : :

[VMWakeupType [VMWakeupType [VMWakeupType [VMWakeupType [VMWakeupType

-> -> -> -> ->

Bool]; Bool]; Bool]; Bool]; Bool];

dec dec dec dec dec

SetVMWUNull SetVMWUBasic SetVMWUTimed SetVMWUTTSWin SetVMWUTTSStart

: : : : :

[VMWakeupType [VMWakeupType [VMWakeupType [VMWakeupType [VMWakeupType

-> -> -> -> ->

VMWakeupType]; VMWakeupType]; VMWakeupType]; VMWakeupType]; VMWakeupType];

dec InclOrWUType : [VMWakeupType -> VMWakeupType -> VMWakeupType];

5.3.5

Other Attributes of VM

def VMPriority = Nat; def VMResetCont = TMReg; def def def def def

VMTickUsage VMTickSliceSize VMTickSlice VMWaitedTicks VMLeaveTicks

= = = = =

Nat; Nat; Nat; Nat; Nat;

92

CHAPTER 5. THE EXTENDED MACHINE

def ExportVarList = @(List, VMKLocation);

5.3.6 dec dec dec dec dec dec dec dec dec dec dec dec

Registers of VMs VM_NAME_REG VM_STAT_REG VM_SCTY_REG VM_WKTY_REG VM_PRIO_REG VM_TCUS_REG VM_TCSS_REG VM_TCSL_REG VM_WTTC_REG VM_LVTC_REG VM_HMTY_REG VM_SGID_REG

: : : : : : : : : : : :

Nat; Nat; Nat; Nat; Nat; Nat; Nat; Nat; Nat; Nat; Nat; Nat;

dec VMCB_REG_SIZE : Nat; def VMCBReg = @(Array, Bit32Word, VMCB_REG_SIZE); def VMCB_REG_ASSIGN = \(reg : VMCBReg, indx : Nat, val : Bit32Word) @(ASSIGN, Bit32Word, VMCB_REG_SIZE, reg, indx, val); def VMCB_REG_RETRIEVE = \(reg : VMCBReg, indx : Nat) @(RETRIEVE, Bit32Word, VMCB_REG_SIZE, reg, indx);

5.3.7

VM Control Blocks

5.3.7.1

Type Definition of VMCB

def VMCB = !(T : Prop) [[VMCBReg -> TMReg -> VMVIntCBlock -> TMReg -> ExcpCont -> ExportVarList -> T] -> T];

93

CHAPTER 5. THE EXTENDED MACHINE

5.3.7.2

94

Constructor of VMCB

dec MkVMCB : [VMCBReg -> TMReg -> VMVIntCBlock -> TMReg -> ExcpCont -> ExportVarList -> VMCB];

5.3.7.3

Selectors of VMCB

dec dec dec dec dec dec

GetVMCBReg GetVMCBResetCont GetVMCBVIntCBlck GetVMCBIntContxt GetVMCBHmContxt GetVMCBExportVar

: : : : : :

[VMCB [VMCB [VMCB [VMCB [VMCB [VMCB

-> -> -> -> -> ->

VMCBReg]; TMReg]; VMVIntCBlock]; TMReg]; ExcpCont]; ExportVarList];

dec dec dec dec dec dec dec dec dec dec dec dec

GetVMCBName GetVMCBStatus GetVMCBSchedType GetVMCBWakeType GetVMCBPriority GetVMCBTickUsage GetVMCBTickSlSiz GetVMCBTickSlice GetVMCBWaitTick GetVMCBLeaveTick GetVMCBHmType GetVMCBMemoIndex

: : : : : : : : : : : :

[VMCB [VMCB [VMCB [VMCB [VMCB [VMCB [VMCB [VMCB [VMCB [VMCB [VMCB [VMCB

-> -> -> -> -> -> -> -> -> -> -> ->

Nat]; VMStatus]; VMScheduleType]; VMWakeupType]; VMPriority]; VMTickUsage]; VMTickSliceSize]; VMTickSlice]; VMWaitedTicks]; VMLeaveTicks]; HMType]; Nat];

-> -> -> -> -> ->

VMCBReg TMReg VMVIntCBlock TMReg ExcpCont ExportVarList

5.3.7.4 dec dec dec dec dec dec

Modifiers of VMCB

SetVMCBReg SetVMCBResetCont SetVMCBVIntCBlck SetVMCBIntContxt SetVMCBHmContxt SetVMCBExportVar

dec SetVMCBName

: : : : : :

[VMCB [VMCB [VMCB [VMCB [VMCB [VMCB

: [VMCB -> Nat

-> -> -> -> -> ->

VMCB]; VMCB]; VMCB]; VMCB]; VMCB]; VMCB]; -> VMCB];

CHAPTER 5. THE EXTENDED MACHINE

dec dec dec dec dec dec dec dec dec dec dec

5.4 5.4.1

SetVMCBStatus SetVMCBSchedType SetVMCBWakeType SetVMCBPriority SetVMCBTickUsage SetVMCBTickSlSiz SetVMCBTickSlice SetVMCBWaitTick SetVMCBLeaveTick SetVMCBHmType SetVMCBMemoIndex

: : : : : : : : : : :

[VMCB [VMCB [VMCB [VMCB [VMCB [VMCB [VMCB [VMCB [VMCB [VMCB [VMCB

-> -> -> -> -> -> -> -> -> -> ->

VMStatus VMScheduleType VMWakeupType VMPriority VMTickUsage VMTickSliceSize VMTickSlice VMWaitedTicks VMLeaveTicks HMType Nat

95

-> -> -> -> -> -> -> -> -> -> ->

VMCB]; VMCB]; VMCB]; VMCB]; VMCB]; VMCB]; VMCB]; VMCB]; VMCB]; VMCB]; VMCB];

TTS Control Blocks TTS Nodes

def TTSNode = !(T : Prop) [[VMKLocation -> Nat -> Nat -> T] -> T]; dec MkTTSNode : [VMKLocation -> Nat -> Nat -> TTSNode]; dec GetTTSNodId : [TTSNode -> VMKLocation]; dec GetTTSNodStart : [TTSNode -> Nat]; dec GetTTSNodDuring : [TTSNode -> Nat]; dec SetTTSNodId : [TTSNode -> VMKLocation -> TTSNode]; dec SetTTSNodStart : [TTSNode -> Nat -> TTSNode]; dec SetTTSNodDuring : [TTSNode -> Nat -> TTSNode];

5.4.2

TTS Status Types

def TTSStatusType = Nat; dec dec dec dec dec

TTSIdle TTSRunning TTSWaitFrame TTSWaitStatus TTSAbort

: : : : :

dec IsTTSIdle dec IsTTSRunning dec IsTTSWaitFrame

TTSStatusType; TTSStatusType; TTSStatusType; TTSStatusType; TTSStatusType; : [TTSStatusType -> Bool]; : [TTSStatusType -> Bool]; : [TTSStatusType -> Bool];

CHAPTER 5. THE EXTENDED MACHINE

dec IsTTSWaitStatus : [TTSStatusType -> Bool]; dec IsTTSAbort : [TTSStatusType -> Bool];

5.4.3

Tick Notify Type

def TickNotifyType = Bit32Word; dec VMK_WINDOWTICK : TickNotifyType; dec VMK_SYSTICK : TickNotifyType; dec VMK_FRAMETICK : TickNotifyType; dec IS_VMK_WINDOWTICK : [TickNotifyType -> Bool]; dec IS_VMK_SYSTICK : [TickNotifyType -> Bool]; dec IS_VMK_FRAMETICK : [TickNotifyType -> Bool]; dec SET_VMK_WINDOWTICK : [TickNotifyType -> TickNotifyType]; dec SET_VMK_SYSTICK : [TickNotifyType -> TickNotifyType]; dec SET_VMK_FRAMETICK : [TickNotifyType -> TickNotifyType]; dec InclTickNotifyType : [TickNotifyType -> TickNotifyType -> TickNotifyType];

5.4.4 dec dec dec dec dec dec dec dec dec

Registers of TTS TTS_NAME_REG TTS_STAT_REG TTS_NODM_REG TTS_IDEN_REG TTS_MFTC_REG TTS_WDTC_REG TTS_FMTC_REG TTS_FRME_REG TTS_CRWD_REG

: : : : : : : : :

Nat; Nat; Nat; Nat; Nat; Nat; Nat; Nat; Nat;

dec TTSCB_REG_SIZE : Nat; def TTSCBReg = @(Array, Bit32Word, TTSCB_REG_SIZE); def TTSCB_REG_ASSIGN = \(reg : TTSCBReg, indx : Nat, val : Bit32Word) @(ASSIGN, Bit32Word, TTSCB_REG_SIZE, reg, indx, val); def TTSCB_REG_RETRIEVE = \(reg : TTSCBReg, indx : Nat)

96

CHAPTER 5. THE EXTENDED MACHINE

97

@(RETRIEVE, Bit32Word, TTSCB_REG_SIZE, reg, indx);

5.4.5

TTS Control Blocks

dec MAX_TTSCB_SIZE : Nat; def TTSCB = !(T : Prop) [[TTSCBReg -> @(Array, TTSNode, MAX_TTSCB_SIZE) -> T] -> T]; dec MkTTSCB : [TTSCBReg -> @(Array, TTSNode, MAX_TTSCB_SIZE) -> TTSCB]; def MkTTSCB = \(ttscbreg : TTSCBReg, nodes : @(Array, TTSNode, MAX_TTSCB_SIZE)) \(T : Prop) \(f : [TTSCBReg -> @(Array, TTSNode, MAX_TTSCB_SIZE) -> T]) @(f, ttscbreg, nodes); dec GetTTSReg : [TTSCB -> TTSCBReg]; dec GetTTSNodes : [TTSCB -> @(Array, TTSNode, MAX_TTSCB_SIZE)]; dec dec dec dec dec dec dec dec dec

GetTTSName GetTTSStatus GETTTSNodeMax GetTTSId GetTTSMFrameTick GetTTSWindowTick GetTTSFrameTick GetTTSFrames GetTTSCurrentWin

: : : : : : : : :

[TTSCB [TTSCB [TTSCB [TTSCB [TTSCB [TTSCB [TTSCB [TTSCB [TTSCB

-> -> -> -> -> -> -> -> ->

Nat]; TTSStatusType]; Nat]; VMKLocation]; Nat]; Nat]; Nat]; Nat]; Nat];

dec SetTTSReg : [TTSCB -> TTSCBReg -> TTSCB]; dec SetTTSNodes : [TTSCB -> @(Array, TTSNode, MAX_TTSCB_SIZE) -> TTSCB]; dec dec dec dec dec dec dec dec dec

SetTTSName SetTTSStatus SETTTSNodeMax SetTTSId SetTTSMFrameTick SetTTSWindowTick SetTTSFrameTick SetTTSFrames SetTTSCurrentWin

: : : : : : : : :

[TTSCB [TTSCB [TTSCB [TTSCB [TTSCB [TTSCB [TTSCB [TTSCB [TTSCB

-> -> -> -> -> -> -> -> ->

Nat TTSStatusType Nat VMKLocation Nat Nat Nat Nat Nat

-> -> -> -> -> -> -> -> ->

TTSCB]; TTSCB]; TTSCB]; TTSCB]; TTSCB]; TTSCB]; TTSCB]; TTSCB]; TTSCB];

CHAPTER 5. THE EXTENDED MACHINE

5.5 5.5.1

98

Virtual Interrupt Control Blocks When Virtual Interrupt Delivered

There are three cases for delivery of virtual interrupts: 1. The returning from external interrupt handler to VM. 2. The returning from system service call to VM. 3. The returning from exception handler to VM. Before returning to VM from the external interrupt handlers, the system service calls and exception handlers, if there is virtual interrupts needed to be delivered, then the current context and virtual interrupt will be saved in the current stack of VM, the virtual interrupt service routine in the VMCB will be invoked for processing of corresponding virtual interrupts. • To return from the virtual ISRs, the instruction VIRET will be invoked, it will cause the execution return to the point of program being interrupted. • For exceptions, there is a need to invoke VAE for acknowledging the system that an exception has been handled already after the exception handling has completed its execution. The interrupt-service routine should be defined on VMKState instead of VMState.

5.5.2

Types of Virtual Interrupts

dec TMReg : Prop; def VMKLocation = Nat; def VIntType = Nat; def def def def

VTickIntType VExcpIntType VExtrIntType VServIntType

= = = =

OO; II; I2; I3;

dec VNilIntType : VIntType;

CHAPTER 5. THE EXTENDED MACHINE

5.5.3

Tick Interrupt Control Blocks

dec VMVTINT_MASK_REG : Nat; dec VMVTINT_FIRE_REG : Nat; dec VMVTINT_COUN_REG : Nat; dec VMVTINT_REG_SIZE : Nat; def VMVTIntReg = @(Array, Bit32Word, VMVTINT_REG_SIZE); def VMVTickIntCB = !(T : Prop) [[VMVTIntReg -> TMReg -> T] -> T]; dec MkVMVTickIntCB : [VMVTIntReg -> TMReg -> VMVTickIntCB]; dec GetVMVTIntCBReg : [VMVTickIntCB -> VMVTIntReg]; dec GetVMVTIntCBHand : [VMVTickIntCB -> TMReg]; dec GetVMVTIntCBMask : [VMVTickIntCB -> Bool]; dec GetVMVTIntCBFire : [VMVTickIntCB -> Bool]; dec GetVMVTIntCBCoun : [VMVTickIntCB -> Nat]; dec SetVMVTIntCBReg : [VMVTickIntCB -> VMVTIntReg -> VMVTickIntCB]; dec SetVMVTIntCBHand : [VMVTickIntCB -> TMReg -> VMVTickIntCB]; dec SetVMVTIntCBMask : [VMVTickIntCB -> Bool -> VMVTickIntCB]; dec SetVMVTIntCBFire : [VMVTickIntCB -> Bool -> VMVTickIntCB]; dec SetVMVTIntCBCoun : [VMVTickIntCB -> Nat -> VMVTickIntCB];

5.5.4

Other Interrupt Control Blocks

dec VMVINT_MASK_REG : Nat; dec VMVINT_FIRE_REG : Nat; dec VMVINT_REG_SIZE : Nat; def VMVIntReg = @(Array, Bit32Word, VMVINT_REG_SIZE); def VMVIntCB = !(T : Prop) [[VMVIntReg -> TMReg -> T] -> T]; dec ERR_VMVINTCB : VMVIntCB;

99

CHAPTER 5. THE EXTENDED MACHINE

100

dec MkVMVIntCB : [VMVIntReg -> TMReg -> VMVIntCB]; dec GetVMVIntCBReg : [VMVIntCB -> VMVIntReg]; dec GetVMVIntCBHand : [VMVIntCB -> TMReg]; dec GetVMVIntCBMask : [VMVIntCB -> Bool]; dec GetVMVIntCBFire : [VMVIntCB -> Bool]; dec SetVMVIntCBReg : [VMVIntCB -> VMVIntReg -> VMVIntCB]; dec SetVMVIntCBHand : [VMVIntCB -> TMReg -> VMVIntCB]; dec SetVMVIntCBMask : [VMVIntCB -> Bool -> VMVIntCB]; dec SetVMVIntCBFire : [VMVIntCB -> Bool -> VMVIntCB];

5.5.5

List of Virtual Interruption Control Blocks

def VMVIntCBList = @(List, VMVIntCB); dec IS_IN_INT_LIST : [VMKLocation -> @(List, VMVIntCB) -> Bool];

5.5.6

Virtual Interrupt Management System

There are four set of different virtual interruptions. • Virtual Tick Interrupt • Virtual Exception Interrupt • Virtual External Interrupt: • Virtual Service Interrupt: The interrupts are used for communication in between VMs. def VMVIntCBlock = !(T : Prop) [[Bool -> Nat -> VMVTickIntCB -> VMVIntCBList -> VMVIntCBList -> VMVIntCBList -> T] -> T]; dec MkVMVIntCBlock : [Bool -> Nat ->

CHAPTER 5. THE EXTENDED MACHINE

101

VMVTickIntCB -> VMVIntCBList -> VMVIntCBList -> VMVIntCBList -> VMVIntCBlock]; dec dec dec dec dec dec

GetVMVIntInit GetVMVIntExcpNum GetVMVIntTickCB GetVMVIntExcpCB GetVMVIntExtrCB GetVMVIntServCB

: : : : : :

[VMVIntCBlock [VMVIntCBlock [VMVIntCBlock [VMVIntCBlock [VMVIntCBlock [VMVIntCBlock

-> -> -> -> -> ->

Bool]; Nat]; VMVTickIntCB]; VMVIntCBList]; VMVIntCBList]; VMVIntCBList];

dec dec dec dec dec dec

SetVMVIntInit SetVMVIntExcpNum SetVMVIntTickCB SetVMVIntExcpCB SetVMVIntExtrCB SetVMVIntServCB

: : : : : :

[VMVIntCBlock [VMVIntCBlock [VMVIntCBlock [VMVIntCBlock [VMVIntCBlock [VMVIntCBlock

-> -> -> -> -> ->

Bool Nat VMVTickIntCB VMVIntCBList VMVIntCBList VMVIntCBList

5.6 5.6.1

-> -> -> -> -> ->

VMVIntCBlock]; VMVIntCBlock]; VMVIntCBlock]; VMVIntCBlock]; VMVIntCBlock]; VMVIntCBlock];

TM State Nested Interrupt Handling Model

TM consists of a read-only instruction memory, a data memory, and a set of eight general-purpose registers. These all use natural number addresses beginning at 0. Register 7 is the program counter and is the only special register.

5.6.2

Basic Utilities

def NEQ = EQUAL; dec NGT : [Nat -> Nat -> Bool]; dec INT2B32 : [Int -> Bit32Word]; dec B322INT : [Bit32Word -> Int]; dec INT2NAT : [Int -> Nat]; dec NAT2INT : [Nat -> Int]; dec NAT2B32 : [Nat -> Bit32Word]; dec B322NAT : [Bit32Word -> Nat]; dec N14 : Nat; dec N32 : Nat; dec IS_IN_LOC_LIST : [VMKLocation -> @(List, VMKLocation) -> Bool];

CHAPTER 5. THE EXTENDED MACHINE

dec GET_LOC_LIST : [VMKLocation -> @(List, VMKLocation) -> VMKLocation]; dec SET_LOC_LIST : [VMKLocation -> @(List, VMKLocation) -> VMKLocation -> @(List, VMKLocation)]; dec DEL_LOC_LIST : [VMKLocation -> @(List, VMKLocation) -> @(List, VMKLocation)]; def TMREG_SIZE = N14; def TMIOVECTOR_SIZE = N32; dec DADDR_SIZE : Nat; dec IADDR_SIZE : Nat; dec SEGMENT_SIZE : Nat;

5.6.3

Registers of TM

5.6.3.1

PC - Program Counter

dec PC_REG : Nat;

5.6.3.2

Memory Pointer

Point to the top of memory dec MP_REG : Nat;

5.6.3.3

Global Pointer

Point to the bottom of memory dec GP_REG : Nat;

5.6.3.4

Accumulator

dec AC_REG

: Nat;

102

CHAPTER 5. THE EXTENDED MACHINE

5.6.3.5

103

2nd Accumulator

dec AC1_REG : Nat;

5.6.3.6

Frame Pointer

dec FP_REG : Nat;

5.6.3.7

Static Chain Register

dec ST_REG : Nat;

5.6.3.8

Interrupt Control Register

dec IC_REG : Nat;

5.6.3.9

Interrupt Enable Register

dec IE_REG : Nat;

5.6.3.10

Interrupt Service Register

5.6.3.11

May We Need An Interrupt Service Register?

It will be used for the special treatment of dynamic capability checking for interrupt service routines. dec IS_REG : Nat; dec IS_INT_SERVICED : [Bit32Word -> Bool];

5.6.3.12

Interrupt Mask Register

dec IM_REG : Nat;

CHAPTER 5. THE EXTENDED MACHINE

5.6.3.13

Interrupt Handler Register

dec IH_REG : Nat;

5.6.3.14

Segment Register

dec SG_REG : Nat;

5.6.3.15

Mode Register

dec MD_REG : Nat; dec SUP_MODE : Bit32Word; dec USE_MODE : Bit32Word; dec IS_SUP_MODE : [Bit32Word -> Bool]; dec IS_USE_MODE : [Bit32Word -> Bool];

5.6.3.16

Virtual Interrupt Type Register

dec VT_REG : Nat; dec IS_VINT_SERVICED : [Bit32Word -> Bool];

5.6.3.17

Virtual Interrupt Service Register

dec VS_REG : Nat;

5.6.3.18

Segment Number of SVM Manager

dec VMK_MANAGER_IDX : Nat;

5.6.3.19

Register Set

def TMReg = @(Array, Bit32Word, TMREG_SIZE);

104

CHAPTER 5. THE EXTENDED MACHINE

dec ERR_TMREG : TMReg; def TMREG_NEW = @(CREATE, Bit32Word, TMREG_SIZE); def TMREG_ASSIGN = \(reg : TMReg, indx : Nat, val : Bit32Word) @(ASSIGN, Bit32Word, TMREG_SIZE, reg, indx, val); def TMREG_RETRIEVE = \(reg : TMReg, indx : Nat) @(RETRIEVE, Bit32Word, TMREG_SIZE, reg, indx);

5.6.4

IO Vector

def TMIOVector = @(Array, Bit32Word, TMIOVECTOR_SIZE); def TMIOVECT_ASSIGN = \(reg : TMIOVector, indx : Nat, val : Bit32Word) @(ASSIGN, Bit32Word, TMIOVECTOR_SIZE, reg, indx, val); def TMIOVECT_RETRIEVE = \(reg : TMIOVector, indx : Nat) @(RETRIEVE, Bit32Word, TMIOVECTOR_SIZE, reg, indx);

5.6.5

Data Memory

def DMemory = @(Array, Bit32Word, DADDR_SIZE); def DMEM_ASSIGN = \(dm : DMemory, indx : Nat, val : Bit32Word) @(ASSIGN, Bit32Word, DADDR_SIZE, dm, indx, val); def DMEM_RETRIEVE = \(dm : DMemory, indx : Nat) @(RETRIEVE, Bit32Word, DADDR_SIZE, dm, indx);

5.6.6

Instruction Memory

def IMemory = @(Array, Instr, IADDR_SIZE);

105

CHAPTER 5. THE EXTENDED MACHINE

def IMEM_ASSIGN = \(im : IMemory, indx : Nat, val : Instr) @(ASSIGN, Instr, IADDR_SIZE, im, indx, val); def IMEM_RETRIEVE = \(im : IMemory, indx : Nat) @(RETRIEVE, Instr, IADDR_SIZE, im, indx);

5.6.7

Context Stack

def TMRegStack = @(Stack, TMReg);

5.6.8

Segments

def TMSegment = !(T : Prop) [[IMemory -> DMemory -> T] -> T]; def MK_TMSEGMENT = \(i : IMemory, d : DMemory) \(T : Prop) \(s : [IMemory -> DMemory -> T]) @(s, i, d); dec ERR_TMSEG : TMSegment; dec ZERO_DIV_TMSEG : TMSegment; dec DMEM_ERR_TMSEG : TMSegment; dec GET_TMSG_IMEM : [TMSegment -> IMemory]; dec GET_TMSG_DMEM : [TMSegment -> DMemory]; dec SET_TMSG_IMEM : [TMSegment -> IMemory -> TMSegment]; dec SET_TMSG_DMEM : [TMSegment -> DMemory -> TMSegment];

5.6.9

Set of VMCBs

dec MAX_VMCB_NUMB : Nat; dec MAX_TTSCB_NUMB : Nat; def VMCBSet

= @(Array, VMCB, MAX_VMCB_NUMB);

106

CHAPTER 5. THE EXTENDED MACHINE

def VMCBSetAssign = \(z : @(Array, VMCB, MAX_VMCB_NUMB), indx : Nat, vmcb : VMCB) @(ASSIGN, VMCB, MAX_VMCB_NUMB, z, indx, vmcb); def VMCBSetRetrieve = \(z : @(Array, VMCB, MAX_VMCB_NUMB), indx : Nat) @(RETRIEVE, VMCB, MAX_VMCB_NUMB, z, indx);

5.6.10

Set of TTSCBs

def TTSCBSet = @(Array, TTSCB, MAX_TTSCB_NUMB); def TTSCBSetAssign = \(z : @(Array, TTSCB, MAX_TTSCB_NUMB), indx : Nat, ttscb : TTSCB) @(ASSIGN, TTSCB, MAX_TTSCB_NUMB, z, indx, ttscb); def TTSCBSetRetrieve = \(z : @(Array, TTSCB, MAX_TTSCB_NUMB), indx : Nat) @(RETRIEVE, TTSCB, MAX_TTSCB_NUMB, z, indx);

5.6.11

TM State

5.6.11.1

Type Definition of TMState

def TMState = !(T : Prop) [[@(Array, TMSegment, SEGMENT_SIZE) -> TMReg -> TMRegStack -> TMIOVector -> VMKManager -> VMCBSet -> TTSCBSet -> T] -> T];

5.6.11.2

Constructor of TMState

def MK_TMSTATE = \(seg : @(Array, TMSegment, SEGMENT_SIZE), r : TMReg, savr : TMRegStack, io : TMIOVector,

107

CHAPTER 5. THE EXTENDED MACHINE

108

vmkman : VMKManager, vmcbs : VMCBSet, ttscbs : TTSCBSet) \(T : Prop) \(s : [@(Array, TMSegment, SEGMENT_SIZE) -> TMReg -> TMRegStack -> TMIOVector -> VMKManager -> VMCBSet -> TTSCBSet -> T]) @(s, seg, r, savr, io, vmkman, vmcbs, ttscbs);

5.6.11.3 dec dec dec dec dec dec dec

Selectors of TMState

GET_TMST_TMSEG GET_TMST_TMREG GET_TMST_TMSREG GET_TMST_TMVECT GET_TMST_VMKMAN GET_TMST_VMCBLT GET_TMST_TTSCBL

: : : : : : :

[TMState [TMState [TMState [TMState [TMState [TMState [TMState

-> -> -> -> -> -> ->

@(Array, TMSegment, SEGMENT_SIZE)]; TMReg]; TMRegStack]; TMIOVector]; VMKManager]; @(Array, VMCB, MAX_VMCB_NUMB)]; @(Array, TTSCB, MAX_TTSCB_NUMB)];

dec GET_TMST_IMEM : [TMState -> IMemory]; dec GET_TMST_DMEM : [TMState -> DMemory]; def GET_TMST_DMEM = \(z : TMState) let spc = @(GET_TMST_TMSEG, z) in let seg = @(SEG_RETRIEVE, spc, SG_REG) in @(GET_TMSG_DMEM, seg);

5.6.11.4

Modifiers of TMState

dec SET_TMST_IMEM : [TMState -> IMemory -> TMState]; dec SET_TMST_DMEM : [TMState -> DMemory -> TMState]; dec dec dec dec dec dec dec

SET_TMST_TMSEG SET_TMST_TMREG SET_TMST_TMSREG SET_TMST_TMVECT SET_TMST_VMKMAN SET_TMST_VMCBLT SET_TMST_TTSCBL

: : : : : : :

[TMState [TMState [TMState [TMState [TMState [TMState [TMState

-> -> -> -> -> -> ->

@(Array, TMSegment, SEGMENT_SIZE) TMReg TMRegStack TMIOVector VMKManager @(Array, VMCB, MAX_VMCB_NUMB) @(Array, TTSCB, MAX_TTSCB_NUMB)

-> -> -> -> -> -> ->

TMState]; TMState]; TMState]; TMState]; TMState]; TMState]; TMState];

CHAPTER 5. THE EXTENDED MACHINE

5.6.11.5

Data Memory Access for TMState

dec GET : [TMState -> VMKLocation -> Bit32Word]; def GET = \(z : TMState, l : VMKLocation) let dm = @(GET_TMST_DMEM, z) in @(DMEM_RETRIEVE, dm, l); dec SET : [TMState -> VMKLocation -> Bit32Word -> TMState];

5.6.11.6

VMCB Access for TMState

dec VMCB_GET : [TMState -> VMKLocation -> VMCB]; dec VMCB_SET : [TMState -> VMKLocation -> VMCB -> TMState]; def VMCB_GET = \(z : TMState, i : VMKLocation) let vmcb_list = @(GET_TMST_VMCBLT, z) in @(RETRIEVE, VMCB, MAX_VMCB_NUMB, vmcb_list, i); def VMCB_SET = \(z : TMState, i : VMKLocation, vmcb : VMCB) let vmcb_list = @(GET_TMST_VMCBLT, z) in let nvmcb_list = @(ASSIGN, VMCB, MAX_VMCB_NUMB, vmcb_list, i, vmcb) in @(SET_TMST_VMCBLT, z, nvmcb_list);

5.6.11.7

TTSCB Access for TMState

dec TTSCB_GET : [TMState -> VMKLocation -> TTSCB]; dec TTSCB_SET : [TMState -> VMKLocation -> TTSCB -> TMState]; def TTSCB_GET = \(z : TMState, i : VMKLocation) let ttscb_list = @(GET_TMST_TTSCBL, z) in @(RETRIEVE, TTSCB, MAX_TTSCB_NUMB, ttscb_list, i); def TTSCB_SET = \(z : TMState, i : VMKLocation, ttscb : TTSCB) let ttscb_list = @(GET_TMST_TTSCBL, z) in let nttscb_list = @(ASSIGN, TTSCB, MAX_TTSCB_NUMB, ttscb_list, i, ttscb) in @(SET_TMST_TTSCBL, z, nttscb_list);

109

CHAPTER 5. THE EXTENDED MACHINE

5.6.11.8

Segment Access for TMState

def SEG_ASSIGN = \(z : @(Array, TMSegment, SEGMENT_SIZE), indx : Nat, seg : TMSegment) @(ASSIGN, TMSegment, SEGMENT_SIZE, z, indx, seg); def SEG_RETRIEVE = \(z : @(Array, TMSegment, SEGMENT_SIZE), indx : Nat) @(RETRIEVE, TMSegment, SEGMENT_SIZE, z, indx);

5.6.11.9

SVM Manager Register Access for TMState

def MAN_REG_GET = \(z : TMState, index : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z), vm = @(GET_TMST_VMCBLT, z), ts = @(GET_TMST_TTSCBL, z) in let man_reg = @(GET_VMKMAN_MANREG, mn) in @(VMKMAN_REG_RETRIEVE, man_reg, index); def MAN_REG_SET = \(z : TMState, index : Nat, v : Bit32Word) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z), vm = @(GET_TMST_VMCBLT, z), ts = @(GET_TMST_TTSCBL, z) in let man_reg = @(GET_VMKMAN_MANREG, mn) in let nman_reg = @(VMKMAN_REG_ASSIGN, man_reg, index, v) in let nmn = @(SET_VMKMAN_MANREG, mn, nman_reg) in @(SET_TMST_VMKMAN, z, nmn); def VMCB_REG_GET = \(z : TMState, vm_index : Nat, reg_index : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z), vm = @(GET_TMST_VMCBLT, z),

110

CHAPTER 5. THE EXTENDED MACHINE

ts = @(GET_TMST_TTSCBL, z) in let vmcb = @(VMCBSetRetrieve, vm, vm_index) in let vmcb_reg = @(GetVMCBReg, vmcb) in @(VMCB_REG_RETRIEVE, vmcb_reg, reg_index); def VMCB_REG_SET = \(z : TMState, vm_index : Nat, reg_index : Nat, v : Bit32Word) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z), vm = @(GET_TMST_VMCBLT, z), ts = @(GET_TMST_TTSCBL, z) in let vmcb = @(VMCBSetRetrieve, vm, vm_index) in let vmcb_reg = @(GetVMCBReg, vmcb) in let nvmcb_reg = @(VMCB_REG_ASSIGN, vmcb_reg, reg_index, v) in let nvmcb = @(SetVMCBReg, vmcb, nvmcb_reg) in let nvm = @(VMCBSetAssign, vm, vm_index, nvmcb) in @(SET_TMST_VMCBLT, z, nvm); def TTSCB_REG_GET = \(z : TMState, tts_index : Nat, reg_index : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z), vm = @(GET_TMST_VMCBLT, z), ts = @(GET_TMST_TTSCBL, z) in let ttscb = @(TTSCBSetRetrieve, ts, tts_index) in let ttscb_reg = @(GetTTSReg, ttscb) in @(TTSCB_REG_RETRIEVE, ttscb_reg, reg_index); def TTSCB_REG_SET = \(z : TMState, tts_index : Nat, reg_index : Nat, v : Bit32Word) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z), vm = @(GET_TMST_VMCBLT, z), ts = @(GET_TMST_TTSCBL, z) in let ttscb = @(TTSCBSetRetrieve, ts, tts_index) in let ttscb_reg = @(GetTTSReg, ttscb) in let nttscb_reg = @(TTSCB_REG_ASSIGN, ttscb_reg, reg_index, v) in let nttscb = @(SetTTSReg, ttscb, nttscb_reg) in let nts = @(TTSCBSetAssign, ts, tts_index, nttscb) in

111

CHAPTER 5. THE EXTENDED MACHINE

@(SET_TMST_TTSCBL, z, nts);

5.6.11.10

Location List Access for TMState

dec DoInsertWaitedVM : [TMState -> @(List, VMKLocation) -> VMKLocation -> @(Product, TMState, @(List, VMKLocation))]; def DoInsertWaitedVM = \(z : TMState, vml : @(List, VMKLocation), l : VMKLocation) let vm = @(VMCB_GET, z, l) in @(GIF_THEN_ELSE, @(Product, TMState, @(List, VMKLocation)), @(IS_EMPTY, VMKLocation, vml), @(PRODUCT, TMState, @(List, VMKLocation), z, @(CONS, VMKLocation, l, vml)), let hvml = @(HEAD, VMKLocation, vml), tvml = @(TAIL, VMKLocation, vml) in let vm_waited = @(VMCB_GET, z, hvml) in @(GIF_THEN_ELSE, @(Product, TMState, @(List, VMKLocation)), @(NGT, @(GetVMCBWaitTick, vm), @(GetVMCBWaitTick, vm_waited)), let vm1 = @(SetVMCBWaitTick, vm, @(MINUS, @(GetVMCBWaitTick, vm), @(GetVMCBWaitTick, vm_waited))) in let z1 = @(VMCB_SET, z, l, vm1) in let z2vml = @(DoInsertWaitedVM, z1, tvml, l) in let z2 = @(PJ1, TMState, @(List, VMKLocation), z2vml), vml2 = @(PJ2, TMState, @(List, VMKLocation), z2vml) in @(PRODUCT, TMState, @(List, VMKLocation), z2, @(CONS, VMKLocation, hvml, vml2)), let nvm_waited = @(SetVMCBWaitTick, vm_waited, @(MINUS, @(GetVMCBWaitTick, vm_waited), @(GetVMCBWaitTick, vm))) in let z1 = @(VMCB_SET, z, hvml, nvm_waited) in @(PRODUCT, TMState, @(List, VMKLocation), z1, @(CONS, VMKLocation, l, vml)))); dec InsertWaitedVM : [TMState -> VMKLocation -> Nat -> TMState];

112

CHAPTER 5. THE EXTENDED MACHINE

def InsertWaitedVM = \(z : TMState, vm_loc : VMKLocation, tick : Nat) let vm = @(VMCB_GET, z, vm_loc) in let nvm = @(SetVMCBWaitTick, vm, tick) in let vmk_manager = @(GET_TMST_VMKMAN, z) in let tickwaitvml = @(GET_VMKMAN_TICKWT, vmk_manager) in let z2vml = @(DoInsertWaitedVM, z, tickwaitvml, vm_loc) in let nz0 = @(PJ1, TMState, @(List, VMKLocation), z2vml), ntickwaitvml = @(PJ2, TMState, @(List, VMKLocation), z2vml) in let nvmk_manager = @(SET_VMKMAN_TICKWT, vmk_manager, ntickwaitvml) in let nz1 = @(VMCB_SET, nz0, vm_loc, nvm) in @(SET_TMST_VMKMAN, nz1, nvmk_manager); dec VMLOC_IN : [TMState -> Nat -> Nat -> Bool]; def VMLOC_IN = \(z : TMState, list_index : Nat, vloc_index : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z), vm = @(GET_TMST_VMCBLT, z), ts = @(GET_TMST_TTSCBL, z) in let vmk_manager = @(GET_TMST_VMKMAN, z) in let l = @(GIF_THEN_ELSE, @(List, VMKLocation), @(NEQ, list_index, OO), @(GET_VMKMAN_INTDIS, vmk_manager), @(GIF_THEN_ELSE, @(List, VMKLocation), @(NEQ, list_index, II), @(GET_VMKMAN_TICKWT, vmk_manager), @(GET_VMKMAN_EXCPVM, vmk_manager))) in @(IS_IN_LOC_LIST, vloc_index, l); dec VMLOC_GET : [TMState -> Nat -> Nat -> VMKLocation]; def VMLOC_GET = \(z : TMState, list_index : Nat, vloc_index : Nat) let vmk_manager = @(GET_TMST_VMKMAN, z) in let l = @(GIF_THEN_ELSE, @(List, VMKLocation), @(NEQ, list_index, OO), @(GET_VMKMAN_INTDIS, vmk_manager), @(GIF_THEN_ELSE, @(List, VMKLocation), @(NEQ, list_index, II), @(GET_VMKMAN_TICKWT, vmk_manager), @(GET_VMKMAN_EXCPVM, vmk_manager))) in

113

CHAPTER 5. THE EXTENDED MACHINE

@(GET_LOC_LIST, vloc_index, l); dec VMLOC_SET : [TMState -> Nat -> Nat -> VMKLocation -> TMState]; def VMLOC_SET = \(z : TMState, list_index : Nat, vloc_index : Nat, loc : VMKLocation) let vmk_manager = @(GET_TMST_VMKMAN, z) in @(GIF_THEN_ELSE, TMState, @(NEQ, list_index, OO), let l = @(GET_VMKMAN_INTDIS, vmk_manager) in let nl = @(SET_LOC_LIST, vloc_index, l, loc) in let nvmk_manager = @(SET_VMKMAN_INTDIS, vmk_manager, nl) in @(SET_TMST_VMKMAN, z, nvmk_manager), @(GIF_THEN_ELSE, TMState, @(NEQ, list_index, II), let l = @(GET_VMKMAN_TICKWT, vmk_manager) in let nl = @(SET_LOC_LIST, vloc_index, l, loc) in let nvmk_manager = @(SET_VMKMAN_TICKWT, vmk_manager, nl) in @(SET_TMST_VMKMAN, z, nvmk_manager), let l = @(GET_VMKMAN_EXCPVM, vmk_manager) in let nl = @(SET_LOC_LIST, vloc_index, l, loc) in let nvmk_manager = @(SET_VMKMAN_EXCPVM, vmk_manager, nl) in @(SET_TMST_VMKMAN, z, nvmk_manager))); def VMLOC_DEL = \(z : TMState, list_index : Nat, vloc_index : Nat) let vmk_manager = @(GET_TMST_VMKMAN, z) in @(GIF_THEN_ELSE, TMState, @(NEQ, list_index, OO), let l = @(GET_VMKMAN_INTDIS, vmk_manager) in let nl = @(DEL_LOC_LIST, vloc_index, l) in let nvmk_manager = @(SET_VMKMAN_INTDIS, vmk_manager, nl) in @(SET_TMST_VMKMAN, z, nvmk_manager), @(GIF_THEN_ELSE, TMState, @(NEQ, list_index, II), let l = @(GET_VMKMAN_TICKWT, vmk_manager) in let nl = @(DEL_LOC_LIST, vloc_index, l) in let nvmk_manager = @(SET_VMKMAN_TICKWT, vmk_manager, nl) in @(SET_TMST_VMKMAN, z, nvmk_manager), let l = @(GET_VMKMAN_EXCPVM, vmk_manager) in let nl = @(DEL_LOC_LIST, vloc_index, l) in let nvmk_manager = @(SET_VMKMAN_EXCPVM, vmk_manager, nl) in @(SET_TMST_VMKMAN, z, nvmk_manager))); dec VMLOC_EMPY : [TMState -> Nat -> Bool]; def VMLOC_EMPY = \(z : TMState, list_index : Nat)

114

CHAPTER 5. THE EXTENDED MACHINE

let vmk_manager = @(GET_TMST_VMKMAN, z) in @(GIF_THEN_ELSE, Bool, @(NEQ, list_index, OO), let l = @(GET_VMKMAN_INTDIS, vmk_manager) in @(IS_EMPTY, VMKLocation, l), @(GIF_THEN_ELSE, Bool, @(NEQ, list_index, II), let l = @(GET_VMKMAN_TICKWT, vmk_manager) in @(IS_EMPTY, VMKLocation, l), let l = @(GET_VMKMAN_EXCPVM, vmk_manager) in @(IS_EMPTY, VMKLocation, l))); dec VMLOC_HEAD : [TMState -> Nat -> VMKLocation]; def VMLOC_HEAD = \(z : TMState, list_index : Nat) let vmk_manager = @(GET_TMST_VMKMAN, z) in @(GIF_THEN_ELSE, VMKLocation, @(NEQ, list_index, OO), let l = @(GET_VMKMAN_INTDIS, vmk_manager) in @(HEAD, VMKLocation, l), @(GIF_THEN_ELSE, VMKLocation, @(NEQ, list_index, II), let l = @(GET_VMKMAN_TICKWT, vmk_manager) in @(HEAD, VMKLocation, l), let l = @(GET_VMKMAN_EXCPVM, vmk_manager) in @(HEAD, VMKLocation, l))); dec VMLOC_TAIL : [TMState -> Nat -> TMState]; def VMLOC_TAIL = \(z : TMState, list_index : Nat) let vmk_manager = @(GET_TMST_VMKMAN, z) in @(GIF_THEN_ELSE, TMState, @(NEQ, list_index, OO), let l = @(GET_VMKMAN_INTDIS, vmk_manager) in let nl = @(TAIL, VMKLocation, l) in let nvmk_manager = @(SET_VMKMAN_INTDIS, vmk_manager, nl) in @(SET_TMST_VMKMAN, z, nvmk_manager), @(GIF_THEN_ELSE, TMState, @(NEQ, list_index, II), let l = @(GET_VMKMAN_TICKWT, vmk_manager) in let nl = @(TAIL, VMKLocation, l) in let nvmk_manager = @(SET_VMKMAN_TICKWT, vmk_manager, nl) in @(SET_TMST_VMKMAN, z, nvmk_manager), let l = @(GET_VMKMAN_EXCPVM, vmk_manager) in

115

CHAPTER 5. THE EXTENDED MACHINE

let nl = @(TAIL, VMKLocation, l) in let nvmk_manager = @(SET_VMKMAN_EXCPVM, vmk_manager, nl) in @(SET_TMST_VMKMAN, z, nvmk_manager))); dec VMLOC_CONS : [TMState -> Nat -> VMKLocation -> TMState]; def VMLOC_CONS = \(z : TMState, list_index : Nat, loc : VMKLocation) let vmk_manager = @(GET_TMST_VMKMAN, z) in @(GIF_THEN_ELSE, TMState, @(NEQ, list_index, OO), let l = @(GET_VMKMAN_INTDIS, vmk_manager) in let nl = @(CONS, VMKLocation, loc, l) in let nvmk_manager = @(SET_VMKMAN_INTDIS, vmk_manager, nl) in @(SET_TMST_VMKMAN, z, nvmk_manager), @(GIF_THEN_ELSE, TMState, @(NEQ, list_index, II), let l = @(GET_VMKMAN_TICKWT, vmk_manager) in let nl = @(CONS, VMKLocation, loc, l) in let nvmk_manager = @(SET_VMKMAN_TICKWT, vmk_manager, nl) in @(SET_TMST_VMKMAN, z, nvmk_manager), let l = @(GET_VMKMAN_EXCPVM, vmk_manager) in let nl = @(CONS, VMKLocation, loc, l) in let nvmk_manager = @(SET_VMKMAN_EXCPVM, vmk_manager, nl) in @(SET_TMST_VMKMAN, z, nvmk_manager)));

5.6.11.11

VMVIntCB Access for TMState

dec GET_INT_LIST : [VMKLocation -> VMVIntCBList -> VMVIntCB]; dec SET_INT_LIST : [VMKLocation -> VMVIntCBList -> VMVIntCB -> VMVIntCBList]; dec VMVTICKINT_GET : [TMState -> Nat -> Nat -> Bit32Word]; def VMVTICKINT_GET = \(z : TMState, vm_index : Nat, reg_index : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z), vm = @(GET_TMST_VMCBLT, z), ts = @(GET_TMST_TTSCBL, z) in let vmcb = @(VMCB_GET, z, vm_index), vintcblock = @(GetVMCBVIntCBlck, vmcb), vintcb = @(GetVMVIntTickCB, vintcblock), vintreg = @(GetVMVTIntCBReg, vintcb) in @(RETRIEVE, Bit32Word, VMVTINT_REG_SIZE, vintreg, reg_index);

116

CHAPTER 5. THE EXTENDED MACHINE

dec VMVTICKINT_SET : [TMState -> Nat -> Nat -> Bit32Word -> TMState]; def VMVTICKINT_SET = \(z : TMState, vm_index : Nat, reg_index : Nat, v : Bit32Word) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z), vm = @(GET_TMST_VMCBLT, z), ts = @(GET_TMST_TTSCBL, z) in let vmcb = @(VMCB_GET, z, vm_index), vintcblock = @(GetVMCBVIntCBlck, vmcb), vintcb = @(GetVMVIntTickCB, vintcblock), vintreg = @(GetVMVTIntCBReg, vintcb) in let nvintreg = @(ASSIGN, Bit32Word, VMVTINT_REG_SIZE, vintreg, reg_index, v), nvintcb = @(SetVMVTIntCBReg, vintcb, nvintreg), nvintcblock = @(SetVMVIntTickCB, vintcblock, nvintcb), nvmcb = @(SetVMCBVIntCBlck, vmcb, nvintcblock) in @(VMCB_SET, z, vm_index, nvmcb); dec VMVTICKINT_SWITCH : [TMState -> Nat -> TMState]; def VMVTICKINT_SWITCH = \(z : TMState, vm_index : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z), vm = @(GET_TMST_VMCBLT, z), ts = @(GET_TMST_TTSCBL, z) in let vmcb = @(VMCB_GET, z, vm_index), vintcblock = @(GetVMCBVIntCBlck, vmcb), vintcb = @(GetVMVIntTickCB, vintcblock) in let treg = @(GetVMVTIntCBHand , vintcb) in let nsg = rg, nrg = treg in let nz = @(SET_TMST_TMREG, z, nrg) in @(SET_TMST_TMREG, z, nsg); dec VMVECINT_GET : [TMState -> Nat -> Nat -> Nat -> Bit32Word]; def VMVECINT_GET = \(z : TMState, vm_index : Nat, vint_index : Nat, reg_index : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z),

117

CHAPTER 5. THE EXTENDED MACHINE

io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z), vm = @(GET_TMST_VMCBLT, z), ts = @(GET_TMST_TTSCBL, z) in let vmcb = @(VMCB_GET, z, vm_index), vintcblock = @(GetVMCBVIntCBlck, vmcb), vintcb_list = @(GetVMVIntExcpCB, vintcblock), vintcb = @(GET_INT_LIST, vint_index, vintcb_list), vintreg = @(GetVMVIntCBReg, vintcb) in @(RETRIEVE, Bit32Word, VMVINT_REG_SIZE, vintreg, reg_index); dec VMVECINT_SET : [TMState -> Nat -> Nat -> Nat -> Bit32Word -> TMState]; def VMVECINT_SET = \(z : TMState, vm_index : Nat, vint_index : Nat, reg_index : Nat, v : Bit32Word) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z), vm = @(GET_TMST_VMCBLT, z), ts = @(GET_TMST_TTSCBL, z) in let vmcb = @(VMCB_GET, z, vm_index), vintcblock = @(GetVMCBVIntCBlck, vmcb), vintcb_list = @(GetVMVIntExcpCB, vintcblock), vintcb = @(GET_INT_LIST, vint_index, vintcb_list), vintreg = @(GetVMVIntCBReg, vintcb) in let nvintreg = @(ASSIGN, Bit32Word, VMVINT_REG_SIZE, vintreg, reg_index, v), nvintcb = @(SetVMVIntCBReg, vintcb, nvintreg), nvintcb_list = @(SET_INT_LIST, vint_index, vintcb_list, nvintcb), nvintcblock = @(SetVMVIntExcpCB, vintcblock, nvintcb_list), nvmcb = @(SetVMCBVIntCBlck, vmcb, nvintcblock) in @(VMCB_SET, z, vm_index, nvmcb); dec VMVECINT_SWITCH : [TMState -> Nat -> Nat -> TMState]; def VMVECINT_SWITCH = \(z : TMState, vm_index : Nat, vint_index : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z), vm = @(GET_TMST_VMCBLT, z), ts = @(GET_TMST_TTSCBL, z) in let vmcb = @(VMCB_GET, z, vm_index), vintcblock = @(GetVMCBVIntCBlck, vmcb), vintcb_list = @(GetVMVIntExcpCB, vintcblock), vintcb = @(GET_INT_LIST, vint_index, vintcb_list) in let treg = @(GetVMVIntCBHand , vintcb) in

118

CHAPTER 5. THE EXTENDED MACHINE

let nsg = rg, nrg = treg in let nz = @(SET_TMST_TMREG, z, nrg) in @(SET_TMST_TMREG, z, nsg); dec VMVEXINT_GET : [TMState -> Nat -> Nat -> Nat -> Bit32Word]; def VMVEXINT_GET = \(z : TMState, vm_index : Nat, vint_index : Nat, reg_index : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z), vm = @(GET_TMST_VMCBLT, z), ts = @(GET_TMST_TTSCBL, z) in let vmcb = @(VMCB_GET, z, vm_index), vintcblock = @(GetVMCBVIntCBlck, vmcb), vintcb_list = @(GetVMVIntExtrCB, vintcblock), vintcb = @(GET_INT_LIST, vint_index, vintcb_list), vintreg = @(GetVMVIntCBReg, vintcb) in @(RETRIEVE, Bit32Word, VMVINT_REG_SIZE, vintreg, reg_index); dec VMVEXINT_SET : [TMState -> Nat -> Nat -> Nat -> Bit32Word -> TMState]; def VMVEXINT_SET = \(z : TMState, vm_index : Nat, vint_index : Nat, reg_index : Nat, v : Bit32Word) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z), vm = @(GET_TMST_VMCBLT, z), ts = @(GET_TMST_TTSCBL, z) in let vmcb = @(VMCB_GET, z, vm_index), vintcblock = @(GetVMCBVIntCBlck, vmcb), vintcb_list = @(GetVMVIntExtrCB, vintcblock), vintcb = @(GET_INT_LIST, vint_index, vintcb_list), vintreg = @(GetVMVIntCBReg, vintcb) in let nvintreg = @(ASSIGN, Bit32Word, VMVINT_REG_SIZE, vintreg, reg_index, v), nvintcb = @(SetVMVIntCBReg, vintcb, nvintreg), nvintcb_list = @(SET_INT_LIST, vint_index, vintcb_list, nvintcb), nvintcblock = @(SetVMVIntExtrCB, vintcblock, nvintcb_list), nvmcb = @(SetVMCBVIntCBlck, vmcb, nvintcblock) in @(VMCB_SET, z, vm_index, nvmcb); dec VMVEXINT_SWITCH : [TMState -> Nat -> Nat -> TMState]; def VMVEXINT_SWITCH = \(z : TMState, vm_index : Nat, vint_index : Nat)

119

CHAPTER 5. THE EXTENDED MACHINE

let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z), vm = @(GET_TMST_VMCBLT, z), ts = @(GET_TMST_TTSCBL, z) in let vmcb = @(VMCB_GET, z, vm_index), vintcblock = @(GetVMCBVIntCBlck, vmcb), vintcb_list = @(GetVMVIntExtrCB, vintcblock), vintcb = @(GET_INT_LIST, vint_index, vintcb_list) in let treg = @(GetVMVIntCBHand , vintcb) in let nsg = rg, nrg = treg in let nz = @(SET_TMST_TMREG, z, nrg) in @(SET_TMST_TMREG, z, nsg); dec VMVSVINT_GET : [TMState -> Nat -> Nat -> Nat -> Bit32Word]; def VMVSVINT_GET = \(z : TMState, vm_index : Nat, vint_index : Nat, reg_index : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z), vm = @(GET_TMST_VMCBLT, z), ts = @(GET_TMST_TTSCBL, z) in let vmcb = @(VMCB_GET, z, vm_index), vintcblock = @(GetVMCBVIntCBlck, vmcb), vintcb_list = @(GetVMVIntServCB, vintcblock), vintcb = @(GET_INT_LIST, vint_index, vintcb_list), vintreg = @(GetVMVIntCBReg, vintcb) in @(RETRIEVE, Bit32Word, VMVINT_REG_SIZE, vintreg, reg_index); dec VMVSVINT_SET : [TMState -> Nat -> Nat -> Nat -> Bit32Word -> TMState]; def VMVSVINT_SET = \(z : TMState, vm_index : Nat, vint_index : Nat, reg_index : Nat, v : Bit32Word) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z), vm = @(GET_TMST_VMCBLT, z), ts = @(GET_TMST_TTSCBL, z) in let vmcb = @(VMCB_GET, z, vm_index), vintcblock = @(GetVMCBVIntCBlck, vmcb), vintcb_list = @(GetVMVIntServCB, vintcblock),

120

CHAPTER 5. THE EXTENDED MACHINE

vintcb = @(GET_INT_LIST, vint_index, vintcb_list), vintreg = @(GetVMVIntCBReg, vintcb) in let nvintreg = @(ASSIGN, Bit32Word, VMVINT_REG_SIZE, vintreg, reg_index, v), nvintcb = @(SetVMVIntCBReg, vintcb, nvintreg), nvintcb_list = @(SET_INT_LIST, vint_index, vintcb_list, nvintcb), nvintcblock = @(SetVMVIntServCB, vintcblock, nvintcb_list), nvmcb = @(SetVMCBVIntCBlck, vmcb, nvintcblock) in @(VMCB_SET, z, vm_index, nvmcb); dec VMVSVINT_SWITCH : [TMState -> Nat -> Nat -> TMState]; def VMVSVINT_SWITCH = \(z : TMState, vm_index : Nat, vint_index : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z), vm = @(GET_TMST_VMCBLT, z), ts = @(GET_TMST_TTSCBL, z) in let vmcb = @(VMCB_GET, z, vm_index), vintcblock = @(GetVMCBVIntCBlck, vmcb), vintcb_list = @(GetVMVIntServCB, vintcblock), vintcb = @(GET_INT_LIST, vint_index, vintcb_list) in let treg = @(GetVMVIntCBHand , vintcb) in let nsg = rg, nrg = treg in let nz = @(SET_TMST_TMREG, z, nrg) in @(SET_TMST_TMREG, z, nsg);

5.6.11.12

Error State for TMState

dec ERR_TMSTATE : [TMState -> TMState]; def ERR_TMSTATE = \(z : TMState) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), zg = @(GET_TMST_TMSEG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z) in let seg = @(TMREG_RETRIEVE, rg, SG_REG) in let nzg = @(SEG_ASSIGN, zg, @(B322NAT, seg), ERR_TMSEG) in let nz0 = @(SET_TMST_TMSEG, z, nzg) in @(GIF_THEN_ELSE, TMState, @(EQUAL, @(B322NAT, seg), VMK_MANAGER_IDX),

121

CHAPTER 5. THE EXTENDED MACHINE

let idle_vm_loc = @(GET_VMKMAN_IDLEVM, mn) in let idle_vm = @(VMCB_GET, nz0, idle_vm_loc) in let memoidx = @(GetVMCBMemoIndex, idle_vm), context = @(GetVMCBIntContxt, idle_vm) in let nrg0 = @(TMREG_ASSIGN, context, MD_REG, USE_MODE), nrg1 = @(TMREG_ASSIGN, nrg0, SG_REG, @(NAT2B32, memoidx)) in let nz1 = @(SET_TMST_TMREG, nz0, nrg1) in let nmn = @(SET_VMKMAN_RUNVM, mn, idle_vm_loc) in @(SET_TMST_VMKMAN, nz1, nmn), let run_vm_loc = @(GET_VMKMAN_RUNVM, mn) in let nz1 = @(ClearVMReady, run_vm_loc, nz0) in let vm = @(VMCB_GET, nz1, run_vm_loc), vm_status = @(GetVMCBStatus, vm), nvm_status = VMSLEEP, nvm = @(SetVMCBStatus, vm, nvm_status) in let nz2 = @(VMCB_SET, nz1, run_vm_loc, nvm) in @(SCHEDULE_VM, nz2)); dec ZERO_DIV_TMSTATE : [TMState -> TMState]; def ZERO_DIV_TMSTATE = \(z : TMState) let sgs = @(GET_TMST_TMSEG, z), reg = @(GET_TMST_TMREG, z) in let sg = @(TMREG_RETRIEVE, reg, SG_REG) in let nsgs = @(SEG_ASSIGN, sgs, @(B322NAT, sg), ZERO_DIV_TMSEG) in @(SET_TMST_TMSEG, z, nsgs); dec DMEM_ERR_TMSTATE : [TMState -> TMState]; def DMEM_ERR_TMSTATE = \(z : TMState) let sgs = @(GET_TMST_TMSEG, z), reg = @(GET_TMST_TMREG, z) in let sg = @(TMREG_RETRIEVE, reg, SG_REG) in let nsgs = @(SEG_ASSIGN, sgs, @(B322NAT, sg), DMEM_ERR_TMSEG) in @(SET_TMST_TMSEG, z, nsgs);

122

Chapter 6

Semantics of Extended Target Machine 6.1 6.1.1

Semantics for Computation and Control Semantics of IRET

IRET is a supervisor mode instruction. dec SWITCH_CONTEXT : [TMState -> TMState]; dec IS_INT_FIRED : [Bit32Word -> Bool]; def IRET_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), st = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in @(GIF_THEN_ELSE, TMState, @(IS_USE_MODE, @(TMREG_RETRIEVE, rg, MD_REG)), @(ERR_TMSTATE, z), @(GIF_THEN_ELSE, TMState, @(IS_EMPTY_STACK, TMReg, st), @(SWITCH_CONTEXT, z), let nrg = @(TOP, TMReg, ERR_TMREG, st), nst = @(POP, TMReg, st) in let nz = @(SET_TMST_TMREG, z, nrg) in

123

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

@(SET_TMST_TMSREG, nz, nst)));

6.1.2

Semantics of VIRET

def VIRET_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), st = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in @(GIF_THEN_ELSE, TMState, @(IS_USE_MODE, @(TMREG_RETRIEVE, rg, MD_REG)), @(ERR_TMSTATE, z), @(GIF_THEN_ELSE, TMState, @(IS_EMPTY_STACK, TMReg, st), let nrg = @(TMREG_ASSIGN, rg, VT_REG, @(NAT2B32, VNilIntType)) in let nz = @(SET_TMST_TMREG, z, nrg) in @(SWITCH_CONTEXT, z), let nrg = @(TOP, TMReg, ERR_TMREG, st), nst = @(POP, TMReg, st) in let nrg0 = @(TMREG_ASSIGN, nrg, VT_REG, @(NAT2B32, VNilIntType)) in let nz = @(SET_TMST_TMREG, z, nrg0) in @(SET_TMST_TMSREG, nz, nst)));

6.1.3

Semantics of HALT

def HALT_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) z;

6.1.4

Semantics of ADD

def ADD_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let sval = @(TMREG_RETRIEVE, rg, s), tval = @(TMREG_RETRIEVE, rg, t) in

124

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

let addval = @(ADDBit32Word, sval, tval) in let nrg = @(TMREG_ASSIGN, rg, r, addval) in @(SET_TMST_TMREG, z, nrg);

6.1.5

Semantics of SUB

def SUB_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let sval = @(TMREG_RETRIEVE, rg, s), tval = @(TMREG_RETRIEVE, rg, t) in let subval = @(SUBBit32Word, sval, tval) in let nrg = @(TMREG_ASSIGN, rg, r, subval) in @(SET_TMST_TMREG, z, nrg);

6.1.6

Semantics of MUL

def MUL_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let sval = @(TMREG_RETRIEVE, rg, s), tval = @(TMREG_RETRIEVE, rg, t) in let mulval = @(MULBit32Word, sval, tval) in let nrg = @(TMREG_ASSIGN, rg, r, mulval) in @(SET_TMST_TMREG, z, nrg);

6.1.7

Semantics of DIV

def DIV_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z),

125

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let sval = @(TMREG_RETRIEVE, rg, s), tval = @(TMREG_RETRIEVE, rg, t) in @(GIF_THEN_ELSE, TMState, @(IsZeroBit32Word , tval), @(ZERO_DIV_TMSTATE, z), let divval = @(MULBit32Word, sval, tval) in let nrg = @(TMREG_ASSIGN, rg, r, divval) in @(SET_TMST_TMREG, z, nrg));

6.1.8

Semantics of BITAND

def BITAND_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let sval = @(TMREG_RETRIEVE, rg, s), tval = @(TMREG_RETRIEVE, rg, t) in let bitandval = @(ANDBit32Word, sval, tval) in let nrg = @(TMREG_ASSIGN, rg, r, bitandval) in @(SET_TMST_TMREG, z, nrg);

6.1.9

Semantics of BITOR

def BITOR_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let sval = @(TMREG_RETRIEVE, rg, s), tval = @(TMREG_RETRIEVE, rg, t) in let bitorval = @(ORBit32Word, sval, tval) in let nrg = @(TMREG_ASSIGN, rg, r, bitorval) in @(SET_TMST_TMREG, z, nrg);

126

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

6.1.10

Semantics of BITMASK

def BITMASK_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let sval = @(TMREG_RETRIEVE, rg, s), tval = @(TMREG_RETRIEVE, rg, t) in let bitmaskval = @(MASKBit32Word, sval, tval) in let nrg = @(TMREG_ASSIGN, rg, r, bitmaskval) in @(SET_TMST_TMREG, z, nrg);

6.1.11

Semantics of BITANDMATCH

def BITANDMATCH_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let sval = @(TMREG_RETRIEVE, rg, s), tval = @(TMREG_RETRIEVE, rg, t) in let bitandmatchval = @(BOOL2B32, @(ANDMatchedBit32Word, sval, tval)) in let nrg = @(TMREG_ASSIGN, rg, r, bitandmatchval) in @(SET_TMST_TMREG, z, nrg);

6.1.12

Semantics of BITORMATCH

def BITORMATCH_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let sval = @(TMREG_RETRIEVE, rg, s), tval = @(TMREG_RETRIEVE, rg, t) in let bitormatchval = @(BOOL2B32, @(ORMatchedBit32Word, sval, tval)) in let nrg = @(TMREG_ASSIGN, rg, r, bitormatchval) in @(SET_TMST_TMREG, z, nrg);

127

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

6.1.13

Semantics of BITSHIFTL

def BITSHIFTL_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let sval = @(TMREG_RETRIEVE, rg, s), tval = @(TMREG_RETRIEVE, rg, t) in let bitshiftlval = @(ShiftLeftBit32Word, sval, tval) in let nrg = @(TMREG_ASSIGN, rg, r, bitshiftlval) in @(SET_TMST_TMREG, z, nrg);

6.1.14

Semantics of BITSHIFTR

def BITSHIFTR_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let sval = @(TMREG_RETRIEVE, rg, s), tval = @(TMREG_RETRIEVE, rg, t) in let bitshiftrval = @(ShiftRightBit32Word, sval, tval) in let nrg = @(TMREG_ASSIGN, rg, r, bitshiftrval) in @(SET_TMST_TMREG, z, nrg);

6.1.15

Dynamic Capability Checking Functions

6.1.15.1

Readability Checking

dec IS_IN_EXPORT_LIST : [Nat -> @(List, VMKLocation) -> Bool]; dec dec dec dec

RO WO RW DENY

: : : :

Nat; Nat; Nat; Nat;

dec READABLE : [Nat -> Bool]; dec WRITABLE : [Nat -> Bool];

128

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

dec RFLOWLIST_CHECK : [@(List, VMKLocation) -> Nat -> Nat -> TMState -> Bool]; def RFLOWLIST_CHECK = \(l : @(List, VMKLocation), h : Nat, a : Nat, z : TMState) @(GIF_THEN_ELSE, Bool, @(IS_EMPTY, VMKLocation, l), FF, let hl = @(HEAD, VMKLocation, l), tl = @(TAIL, VMKLocation, l) in let dm = @(GET_TMST_DMEM, z) in let subject = @(B322NAT, @(DMEM_RETRIEVE, dm, hl)), resource = @(B322NAT, @(DMEM_RETRIEVE, dm, @(SS, hl))), mode = @(B322NAT, @(DMEM_RETRIEVE, dm, @(SS, @(SS, hl)))) in @(GIF_THEN_ELSE, Bool, @(AND, @(EQUAL, h, subject), @(EQUAL, a, resource)), @(READABLE, mode), @(RFLOWLIST_CHECK, tl, h, a, z))); dec VarReadCheck : [Nat -> Nat -> TMState -> Bool]; def VarReadCheck = \(h : Nat, a : Nat, z : TMState) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let sm = @(TMREG_RETRIEVE, rg, SG_REG) in let smv = @(B322NAT, sm) in @(GIF_THEN_ELSE, Bool, @(EQUAL, smv, VMK_MANAGER_IDX), let vmcb_list = @(GET_TMST_VMCBLT, z), vmk_manager = @(GET_TMST_VMKMAN, z) in let vmcb = @(VMCBSetRetrieve, vmcb_list, smv) in let exportvar = @(GetVMCBExportVar, vmcb), flowlist = @(GET_VMKMAN_FLOWLT, vmk_manager) in @(AND, @(IS_IN_EXPORT_LIST, a, exportvar), @(RFLOWLIST_CHECK, flowlist, h, a, z)), FF);

6.1.15.2

Writability Checking

dec WFLOWLIST_CHECK : [@(List, VMKLocation) -> Nat -> Nat -> TMState -> Bool];

129

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

130

def WFLOWLIST_CHECK = \(l : @(List, VMKLocation), h : Nat, a : Nat, z : TMState) @(GIF_THEN_ELSE, Bool, @(IS_EMPTY, VMKLocation, l), FF, let hl = @(HEAD, VMKLocation, l), tl = @(TAIL, VMKLocation, l) in let dm = @(GET_TMST_DMEM, z) in let subject = @(B322NAT, @(DMEM_RETRIEVE, dm, hl)), resource = @(B322NAT, @(DMEM_RETRIEVE, dm, @(SS, hl))), mode = @(B322NAT, @(DMEM_RETRIEVE, dm, @(SS, @(SS, hl)))) in @(GIF_THEN_ELSE, Bool, @(AND, @(EQUAL, h, subject), @(EQUAL, a, resource)), @(WRITABLE, mode), @(WFLOWLIST_CHECK, tl, h, a, z))); dec VarWriteCheck : [Nat -> Nat -> TMState -> Bool]; def VarWriteCheck = \(h : Nat, a : Nat, z : TMState) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let sm = @(TMREG_RETRIEVE, rg, SG_REG) in let smv = @(B322NAT, sm) in @(GIF_THEN_ELSE, Bool, @(EQUAL, smv, VMK_MANAGER_IDX), let vmcb_list = @(GET_TMST_VMCBLT, z), vmk_manager = @(GET_TMST_VMKMAN, z) in let vmcb = @(VMCBSetRetrieve, vmcb_list, smv) in let exportvar = @(GetVMCBExportVar, vmcb), flowlist = @(GET_VMKMAN_FLOWLT, vmk_manager) in @(AND, @(IS_IN_EXPORT_LIST, a, exportvar), @(WFLOWLIST_CHECK, flowlist, h, a, z)), FF);

6.1.16

Semantics of LD

There are three instructions dealing with the variable access operations: LD, LDA and ST.

Restriction Rule • The mode register can only be modified in scheduling instruction.

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

131

• The segment register can only be modified in supervisor mode. def DO_LD_SEM = \(z : TMState, r : Nat, aval : Int) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in @(GIF_THEN_ELSE, TMState, @(OR, @(ILS, aval, IOO), @(ILS, @(NAT2INT, DADDR_SIZE), aval)), @(DMEM_ERR_TMSTATE, z), @(GIF_THEN_ELSE, TMState, @(EQUAL, r, MD_REG), @(ERR_TMSTATE, z), @(GIF_THEN_ELSE, TMState, @(EQUAL, r, SG_REG), let mode = @(TMREG_RETRIEVE, rg, MD_REG) in @(GIF_THEN_ELSE, TMState, @(IS_SUP_MODE, mode), let dmval = @(DMEM_RETRIEVE, dm, @(INT2NAT, aval)) in let nrg = @(TMREG_ASSIGN, rg, r, dmval) in @(SET_TMST_TMREG, z, nrg), @(ERR_TMSTATE, z)), let dmval = @(DMEM_RETRIEVE, dm, @(INT2NAT, aval)) in let nrg = @(TMREG_ASSIGN, rg, r, dmval) in @(SET_TMST_TMREG, z, nrg))));

Capability checking will be performed for interrupt service routines when the variables inside of interrupt service routines are accessed (read or write). This is done by checking whether or not the content of interrupt servive register is null or containing the address of the currently active interrupt service routine. def LD_SEM = \(z : TMState, r : Nat, d : Int, s : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let sval = @(TMREG_RETRIEVE, rg, s) in let aval = @(IADD, d, @(B322INT, sval)) in let ix = @(TMREG_RETRIEVE, rg, IS_REG), vs = @(TMREG_RETRIEVE, rg, VS_REG) in @(GIF_THEN_ELSE, TMState, @(NOT, @(EQUAL, @(B322NAT, ix), NIL_VMKLOC)),

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

let res = @(VarReadCheck, @(B322NAT, ix), @(INT2NAT, aval), z) in @(GIF_THEN_ELSE, TMState, res, @(DO_LD_SEM, z, r, aval), @(DMEM_ERR_TMSTATE, z)), @(GIF_THEN_ELSE, TMState, @(NOT, @(EQUAL, @(B322NAT, vs), NIL_VMKLOC)), let res = @(VarReadCheck, @(B322NAT, vs), @(INT2NAT, aval), z) in @(GIF_THEN_ELSE, TMState, res, @(DO_LD_SEM, z, r, aval), @(DMEM_ERR_TMSTATE, z)), @(DO_LD_SEM, z, r, aval)));

6.1.17

Semantics of LDA

def DO_LDA_SEM = \(z : TMState, r : Nat, aval : Int) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in @(GIF_THEN_ELSE, TMState, @(OR, @(ILS, aval, IOO), @(ILS, @(NAT2INT, DADDR_SIZE), aval)), @(DMEM_ERR_TMSTATE, z), @(GIF_THEN_ELSE, TMState, @(EQUAL, r, MD_REG), @(ERR_TMSTATE, z), @(GIF_THEN_ELSE, TMState, @(EQUAL, r, SG_REG), let mode = @(TMREG_RETRIEVE, rg, MD_REG) in @(GIF_THEN_ELSE, TMState, @(IS_SUP_MODE, mode), let nrg = @(TMREG_ASSIGN, rg, r, @(INT2B32, aval)) in @(SET_TMST_TMREG, z, nrg), @(ERR_TMSTATE, z)), let nrg = @(TMREG_ASSIGN, rg, r, @(INT2B32, aval)) in @(SET_TMST_TMREG, z, nrg)))); def LDA_SEM = \(z : TMState, r : Nat, d : Int, s : Nat) let im = @(GET_TMST_IMEM, z),

132

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let sval = @(TMREG_RETRIEVE, rg, s) in let aval = @(IADD, d, @(B322INT, sval)) in let ix = @(TMREG_RETRIEVE, rg, IS_REG), vs = @(TMREG_RETRIEVE, rg, VS_REG) in @(GIF_THEN_ELSE, TMState, @(NOT, @(EQUAL, @(B322NAT, ix), NIL_VMKLOC)), let res = @(VarReadCheck, @(B322NAT, ix), @(INT2NAT, aval), z) in @(GIF_THEN_ELSE, TMState, res, @(DO_LDA_SEM, z, r, aval), @(DMEM_ERR_TMSTATE, z)), @(GIF_THEN_ELSE, TMState, @(NOT, @(EQUAL, @(B322NAT, vs), NIL_VMKLOC)), let res = @(VarReadCheck, @(B322NAT, vs), @(INT2NAT, aval), z) in @(GIF_THEN_ELSE, TMState, res, @(DO_LDA_SEM, z, r, aval), @(DMEM_ERR_TMSTATE, z)), @(DO_LDA_SEM, z, r, aval)));

6.1.18

Semantics of LDC

def LDC_SEM = \(z : TMState, r : Nat, d : Int, s : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in @(GIF_THEN_ELSE, TMState, @(OR, @(ILS, d, IOO), @(ILS, @(NAT2INT, DADDR_SIZE), d)), @(DMEM_ERR_TMSTATE, z), @(GIF_THEN_ELSE, TMState, @(EQUAL, r, MD_REG), @(ERR_TMSTATE, z), @(GIF_THEN_ELSE, TMState, @(EQUAL, r, SG_REG),

133

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

let idx = @(B322NAT, @(TMREG_RETRIEVE, rg, r)) in @(GIF_THEN_ELSE, TMState, @(EQUAL, idx, VMK_MANAGER_IDX), let nrg = @(TMREG_ASSIGN, rg, r, @(INT2B32, d)) in @(SET_TMST_TMREG, z, nrg), @(ERR_TMSTATE, z)), let nrg = @(TMREG_ASSIGN, rg, r, @(INT2B32, d)) in @(SET_TMST_TMREG, z, nrg))));

6.1.19

Semantics of ST

def DO_ST_SEM = \(z : TMState, r : Nat, aval : Int) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in @(GIF_THEN_ELSE, TMState, @(OR, @(ILS, aval, IOO), @(ILS, @(NAT2INT, DADDR_SIZE), aval)), @(DMEM_ERR_TMSTATE, z), let rval = @(TMREG_RETRIEVE, rg, r) in let ndm = @(DMEM_ASSIGN, dm, @(INT2NAT, aval), rval) in @(SET_TMST_DMEM, z, ndm)); def ST_SEM = \(z : TMState, r : Nat, d : Int, s : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let sval = @(TMREG_RETRIEVE, rg, s) in let aval = @(IADD, d, @(B322INT, sval)) in let ix = @(TMREG_RETRIEVE, rg, IS_REG), vs = @(TMREG_RETRIEVE, rg, VS_REG) in @(GIF_THEN_ELSE, TMState, @(NOT, @(EQUAL, @(B322NAT, ix), NIL_VMKLOC)), let res = @(VarWriteCheck, @(B322NAT, ix), @(INT2NAT, aval), z) in @(GIF_THEN_ELSE, TMState, res, @(DO_ST_SEM, z, r, aval), @(DMEM_ERR_TMSTATE, z)), @(GIF_THEN_ELSE, TMState,

134

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

@(NOT, @(EQUAL, @(B322NAT, vs), NIL_VMKLOC)), let res = @(VarWriteCheck, @(B322NAT, vs), @(INT2NAT, aval), z) in @(GIF_THEN_ELSE, TMState, res, @(DO_ST_SEM, z, r, aval), @(DMEM_ERR_TMSTATE, z)), @(DO_ST_SEM, z, r, aval)));

6.1.20

Semantics of JLT

def JLT_SEM = \(z : TMState, r : Nat, d : Int, s : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let sval = @(TMREG_RETRIEVE, rg, s) in let aval = @(IADD, d, @(B322INT, sval)) in @(GIF_THEN_ELSE, TMState, @(OR, @(ILS, aval, IOO), @(ILS, @(NAT2INT, DADDR_SIZE), aval)), @(DMEM_ERR_TMSTATE, z), let rval = @(TMREG_RETRIEVE, rg, r) in @(GIF_THEN_ELSE, TMState, @(ILS, @(B322INT, rval), IOO), let nrg = @(TMREG_ASSIGN, rg, PC_REG, @(INT2B32, aval)) in @(SET_TMST_TMREG, z, nrg), z));

6.1.21

Semantics of JLE

def JLE_SEM = \(z : TMState, r : Nat, d : Int, s : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let sval = @(TMREG_RETRIEVE, rg, s) in let aval = @(IADD, d, @(B322INT, sval)) in @(GIF_THEN_ELSE, TMState, @(OR, @(ILS, aval, IOO), @(ILS, @(NAT2INT, DADDR_SIZE), aval)), @(DMEM_ERR_TMSTATE, z),

135

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

let rval = @(TMREG_RETRIEVE, rg, r) in @(GIF_THEN_ELSE, TMState, @(OR, @(ILS, @(B322INT, rval), IOO), @(IEQ, @(B322INT, rval), IOO)), let nrg = @(TMREG_ASSIGN, rg, PC_REG, @(INT2B32, aval)) in @(SET_TMST_TMREG, z, nrg), z));

6.1.22

Semantics of JGE

def JGE_SEM = \(z : TMState, r : Nat, d : Int, s : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let sval = @(TMREG_RETRIEVE, rg, s) in let aval = @(IADD, d, @(B322INT, sval)) in @(GIF_THEN_ELSE, TMState, @(OR, @(ILS, aval, IOO), @(ILS, @(NAT2INT, DADDR_SIZE), aval)), @(DMEM_ERR_TMSTATE, z), let rval = @(TMREG_RETRIEVE, rg, r) in @(GIF_THEN_ELSE, TMState, @(OR, @(ILS, IOO, @(B322INT, rval)), @(IEQ, @(B322INT, rval), IOO)), let nrg = @(TMREG_ASSIGN, rg, PC_REG, @(INT2B32, aval)) in @(SET_TMST_TMREG, z, nrg), z));

6.1.23

Semantics of JGT

def JGT_SEM = \(z : TMState, r : Nat, d : Int, s : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let sval = @(TMREG_RETRIEVE, rg, s) in let aval = @(IADD, d, @(B322INT, sval)) in @(GIF_THEN_ELSE,

136

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

TMState, @(OR, @(ILS, aval, IOO), @(ILS, @(NAT2INT, DADDR_SIZE), aval)), @(DMEM_ERR_TMSTATE, z), let rval = @(TMREG_RETRIEVE, rg, r) in @(GIF_THEN_ELSE, TMState, @(ILS, IOO, @(B322INT, rval)), let nrg = @(TMREG_ASSIGN, rg, PC_REG, @(INT2B32, aval)) in @(SET_TMST_TMREG, z, nrg), z));

6.1.24

Semantics of JEQ

def JEQ_SEM = \(z : TMState, r : Nat, d : Int, s : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let sval = @(TMREG_RETRIEVE, rg, s) in let aval = @(IADD, d, @(B322INT, sval)) in @(GIF_THEN_ELSE, TMState, @(OR, @(ILS, aval, IOO), @(ILS, @(NAT2INT, DADDR_SIZE), aval)), @(DMEM_ERR_TMSTATE, z), let rval = @(TMREG_RETRIEVE, rg, r) in @(GIF_THEN_ELSE, TMState, @(IEQ, @(B322INT, rval), IOO), let nrg = @(TMREG_ASSIGN, rg, PC_REG, @(INT2B32, aval)) in @(SET_TMST_TMREG, z, nrg), z));

6.1.25

Semantics of JNE

def JNE_SEM = \(z : TMState, r : Nat, d : Int, s : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let sval = @(TMREG_RETRIEVE, rg, s) in let aval = @(IADD, d, @(B322INT, sval)) in @(GIF_THEN_ELSE, TMState,

137

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

138

@(OR, @(ILS, aval, IOO), @(ILS, @(NAT2INT, DADDR_SIZE), aval)), @(DMEM_ERR_TMSTATE, z), let rval = @(TMREG_RETRIEVE, rg, r) in @(GIF_THEN_ELSE, TMState, @(NOT, @(IEQ, @(B322INT, rval), IOO)), let nrg = @(TMREG_ASSIGN, rg, PC_REG, @(INT2B32, aval)) in @(SET_TMST_TMREG, z, nrg), z));

6.2 6.2.1

Semantics for VMK Manager, VMCBs and TTSCBs Semantics of MAN GET

dec MAN_GET_SEM : [TMState -> Nat -> Nat -> Nat -> TMState]; def MAN_GET_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z), vm = @(GET_TMST_VMCBLT, z), ts = @(GET_TMST_TTSCBL, z) in @(GIF_THEN_ELSE, TMState, @(IS_USE_MODE, @(TMREG_RETRIEVE, rg, MD_REG)), @(ERR_TMSTATE, z), let man_reg = @(GET_VMKMAN_MANREG, mn) in let sval = @(VMKMAN_REG_RETRIEVE, man_reg, s) in let nrg = @(TMREG_ASSIGN, rg, r, sval) in @(SET_TMST_TMREG, z, nrg));

6.2.2

Semantics of MAN SET

dec MAN_SET_SEM : [TMState -> Nat -> Nat -> Nat -> TMState]; def MAN_SET_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z),

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z), vm = @(GET_TMST_VMCBLT, z), ts = @(GET_TMST_TTSCBL, z) in @(GIF_THEN_ELSE, TMState, @(IS_USE_MODE, @(TMREG_RETRIEVE, rg, MD_REG)), @(ERR_TMSTATE, z), let man_reg = @(GET_VMKMAN_MANREG, mn) in let rval = @(TMREG_RETRIEVE, rg, r) in let nman_reg = @(VMKMAN_REG_ASSIGN, man_reg, s, rval) in let nmn = @(SET_VMKMAN_MANREG, mn, nman_reg) in @(SET_TMST_VMKMAN, z, nmn));

6.2.3

Semantics of VM GET

dec VM_GET_SEM : [TMState -> Nat -> Nat -> Nat -> TMState]; def VM_GET_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z), vm = @(GET_TMST_VMCBLT, z), ts = @(GET_TMST_TTSCBL, z) in @(GIF_THEN_ELSE, TMState, @(IS_USE_MODE, @(TMREG_RETRIEVE, rg, MD_REG)), @(ERR_TMSTATE, z), let sval = @(B322NAT, @(TMREG_RETRIEVE, rg, s)), tval = @(B322NAT, @(TMREG_RETRIEVE, rg, t)) in let rval = @(VMCB_REG_GET, z, sval, tval) in let nrg = @(TMREG_ASSIGN, rg, r, rval) in @(SET_TMST_TMREG, z, nrg));

139

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

6.2.4

Semantics of VM SET

dec VM_SET_SEM : [TMState -> Nat -> Nat -> Nat -> TMState]; def VM_SET_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z), vm = @(GET_TMST_VMCBLT, z), ts = @(GET_TMST_TTSCBL, z) in @(GIF_THEN_ELSE, TMState, @(IS_USE_MODE, @(TMREG_RETRIEVE, rg, MD_REG)), @(ERR_TMSTATE, z), let sval = @(B322NAT, @(TMREG_RETRIEVE, rg, s)), tval = @(B322NAT, @(TMREG_RETRIEVE, rg, t)) in let rval = @(TMREG_RETRIEVE, rg, r) in @(VMCB_REG_SET, z, sval, tval, rval));

6.2.5

Semantics of TTS GET

dec TTS_GET_SEM : [TMState -> Nat -> Nat -> Nat -> TMState]; def TTS_GET_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z), vm = @(GET_TMST_VMCBLT, z), ts = @(GET_TMST_TTSCBL, z) in @(GIF_THEN_ELSE, TMState, @(IS_USE_MODE, @(TMREG_RETRIEVE, rg, MD_REG)), @(ERR_TMSTATE, z), let sval = @(B322NAT, @(TMREG_RETRIEVE, rg, s)), tval = @(B322NAT, @(TMREG_RETRIEVE, rg, t)) in let rval = @(TTSCB_REG_GET, z, sval, tval) in let nrg = @(TMREG_ASSIGN, rg, r, rval) in

140

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

@(SET_TMST_TMREG, z, nrg));

6.2.6

Semantics of TTS SET

dec TTS_SET_SEM : [TMState -> Nat -> Nat -> Nat -> TMState]; def TTS_SET_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z), vm = @(GET_TMST_VMCBLT, z), ts = @(GET_TMST_TTSCBL, z) in @(GIF_THEN_ELSE, TMState, @(IS_USE_MODE, @(TMREG_RETRIEVE, rg, MD_REG)), @(ERR_TMSTATE, z), let sval = @(B322NAT, @(TMREG_RETRIEVE, rg, s)), tval = @(B322NAT, @(TMREG_RETRIEVE, rg, t)) in let rval = @(TMREG_RETRIEVE, rg, r) in @(TTSCB_REG_SET, z, sval, tval, rval));

6.3 6.3.1

Semantics for Scheduling Semantics of SCHEDULE

dec GetVMVTickInt : [VMKLocation -> TMState -> Nat]; def GetVMVTickInt = \(vm_loc : VMKLocation, z : TMState) let vm = @(VMCB_GET, z, vm_loc) in let vint_block = @(GetVMCBVIntCBlck, vm) in let vtickcb = @(GetVMVIntTickCB, vint_block) in @(GetVMVTIntCBCoun, vtickcb); dec SetVMVTickInt : [VMKLocation -> Nat -> TMState -> TMState]; def SetVMVTickInt = \(vm_loc : VMKLocation, tick : Nat, z : TMState) let vm = @(VMCB_GET, z, vm_loc) in let vint_block = @(GetVMCBVIntCBlck, vm) in

141

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

let vtickcb = @(GetVMVIntTickCB, vint_block) in let nvtickcb = @(SetVMVTIntCBCoun, vtickcb, tick) in let nvint_block = @(SetVMVIntTickCB, vint_block, nvtickcb) in let nvm = @(SetVMCBVIntCBlck, vm, nvint_block) in @(VMCB_SET, z, vm_loc, nvm); dec SAVE_CONTEXT : [TMState -> TMState]; def SAVE_CONTEXT = \(z : TMState) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z) in let old_vm_loc = @(GET_VMKMAN_RUNVM, mn) in let old_vm = @(VMCB_GET, z, old_vm_loc), new_vm = @(SetVMCBIntContxt, old_vm, rg) in @(VMCB_SET, z, old_vm_loc, new_vm); dec SWITCH_CONTEXT : [TMState -> TMState]; def SWITCH_CONTEXT = \(z : TMState) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z) in let run_vm_loc = @(GET_VMKMAN_RUNVM, mn) in let run_vm = @(VMCB_GET, z, run_vm_loc) in let memoidx = @(GetVMCBMemoIndex, run_vm), context = @(GetVMCBIntContxt, run_vm) in let nrg0 = @(TMREG_ASSIGN, context, MD_REG, USE_MODE), nrg1 = @(TMREG_ASSIGN, nrg0, SG_REG, @(NAT2B32, memoidx)) in @(SET_TMST_TMREG, z, nrg1); def SCHEDULE_VM = \(z : TMState) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z) in let old_vm_loc = @(GET_VMKMAN_RUNVM, mn), tts_vm_loc = @(GET_VMKMAN_TTSVM, mn), prq_vm_loc = @(GET_VMKMAN_PQUEVM, mn), ticks_numb = @(GET_VMKMAN_TICKCN, mn) in let tts_vm = @(VMCB_GET, z, tts_vm_loc),

142

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

prq_vm = @(VMCB_GET, z, prq_vm_loc) in let new_vm_loc = @(GIF_THEN_ELSE, VMKLocation, @(EQ_VMKLOC, tts_vm_loc, NIL_VMKLOC), prq_vm_loc, tts_vm_loc) in @(GIF_THEN_ELSE, TMState, @(NOT, @(EQ_VMKLOC, new_vm_loc, old_vm_loc)), let old_vm = @(VMCB_GET, z, old_vm_loc), new_vm = @(VMCB_GET, z, new_vm_loc) in let nmn = @(SET_VMKMAN_RUNVM, mn, new_vm_loc) in let nold_vm = @(SetVMCBLeaveTick, old_vm, OO) in let z0 = @(GIF_THEN_ELSE, TMState, @(IS_VMFIRSTRUN, @(GetVMCBStatus, new_vm)), @(SetVMVTickInt, new_vm_loc, ticks_numb, z), z), z1 = @(SET_TMST_VMKMAN, z0, nmn), z2 = @(VMCB_SET, z1, old_vm_loc, nold_vm) in z2, z); def SCH_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z) in @(GIF_THEN_ELSE, TMState, @(IS_USE_MODE, @(TMREG_RETRIEVE, rg, MD_REG)), @(ERR_TMSTATE, z), let z1 = @(SAVE_CONTEXT, z), z2 = @(SCHEDULE_VM, z1), z3 = @(SWITCH_CONTEXT, z2) in z3);

6.3.2

Semantics of CLEAR VM READY

dec CLEAR_PRIORITYQ : [PriorityVMQueue -> Nat -> VMKLocation -> PriorityVMQueue]; dec DEL_LIST : [VMKLocation -> @(List, VMKLocation) -> @(List, VMKLocation)]; def CLEAR_PRIORITYQ = \(qarray : PriorityVMQueue,

143

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

index : Nat, vm_loc : VMKLocation) let vmq = @(RETRIEVE, @(List, VMKLocation), VMK_PRIORITY_NUMBER, qarray, index) in @(GIF_THEN_ELSE, @(Array, @(List, VMKLocation), VMK_PRIORITY_NUMBER), @(IS_IN_LIST, VMKLocation, vm_loc, vmq), let nvmq = @(DEL_LIST, vm_loc, vmq) in @(ASSIGN, @(List, VMKLocation), VMK_PRIORITY_NUMBER, qarray, index, nvmq), qarray); dec DoGetHighPriorVM : [@(Array, @(List, VMKLocation), VMK_PRIORITY_NUMBER) -> Nat -> VMKLocation]; def DoGetHighPriorVM = \(qarray : @(Array, @(List, VMKLocation), VMK_PRIORITY_NUMBER), index : Nat) let vmq = @(RETRIEVE, @(List, VMKLocation), VMK_PRIORITY_NUMBER, qarray, index) in @(GIF_THEN_ELSE, VMKLocation, @(IS_ZERO, index), @(GIF_THEN_ELSE, VMKLocation, @(IS_EMPTY, VMKLocation, vmq), ERR_NAT, @(HEAD, VMKLocation, vmq)), @(GIF_THEN_ELSE, VMKLocation, @(IS_EMPTY, VMKLocation, vmq), @(DoGetHighPriorVM, qarray, @(PP, index)), @(HEAD, VMKLocation, vmq))); dec GetHighPriorVM : [@(Array, @(List, VMKLocation), VMK_PRIORITY_NUMBER) -> VMKLocation]; def GetHighPriorVM = \(qarray : @(Array, @(List, VMKLocation), VMK_PRIORITY_NUMBER)) @(DoGetHighPriorVM, qarray, VMK_PRIORITY_NUMBER); dec ClearVMReady : [VMKLocation -> TMState -> TMState]; def ClearVMReady = \(vm_loc : VMKLocation, nz : TMState) let vmk_manager = @(GET_TMST_VMKMAN, nz) in let vm = @(VMCB_GET, nz, vm_loc) in let vm_status = @(GetVMCBStatus, vm), vm_schedule_type = @(GetVMCBSchedType, vm), vm_priority = @(GetVMCBPriority, vm) in let nvm_status = @(BitAndVMStatus, vm_status, @(SetVMNotREADY, VMREADY)) in let vm1 = @(SetVMCBStatus, vm, nvm_status) in let nz1 = @(VMCB_SET, nz, vm_loc, vm1) in @(GIF_THEN_ELSE, TMState, @(IsVMSchedulePr, vm_schedule_type),

144

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

let priority_queue0 = @(GET_VMKMAN_PRIOTQ, vmk_manager), priority_queue1 = @(CLEAR_PRIORITYQ, priority_queue0, vm_priority, vm_loc) in let high_prior_qvm = @(GetHighPriorVM, priority_queue0) in let nvmk_manager0 = @(SET_VMKMAN_PQUEVM, vmk_manager, high_prior_qvm), nvmk_manager1 = @(SET_VMKMAN_PRIOTQ, nvmk_manager0, priority_queue1) in @(SET_TMST_VMKMAN, nz1, nvmk_manager1), let ttsvm = @(GET_VMKMAN_TTSVM, vmk_manager), curtts = @(GET_VMKMAN_CURTTS, vmk_manager), idlevm = @(GET_VMKMAN_IDLEVM, vmk_manager) in @(GIF_THEN_ELSE, TMState, @(AND, @(EQ_VMKLOC, vm_loc, ttsvm), @(NOT, @(EQ_VMKLOC, curtts, NIL_VMKLOC))), let curttscb = @(TTSCB_GET, nz1, curtts), ncurttscb = @(SetTTSStatus, curttscb, TTSWaitStatus) in let nvmk_manager = @(SET_VMKMAN_TTSVM, vmk_manager, idlevm) in @(TTSCB_SET, nz1, curtts, ncurttscb), nz1)); def CVR_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in @(GIF_THEN_ELSE, TMState, @(IS_USE_MODE, @(TMREG_RETRIEVE, rg, MD_REG)), @(ERR_TMSTATE, z), let rval = @(TMREG_RETRIEVE, rg, r) in @(ClearVMReady, @(B322NAT, rval), z));

6.3.3

Semantics of SET VM READY

dec SetVMReady : [VMKLocation -> TMState -> TMState]; dec INSERT_LAST : !(U : Prop) [@(List, U) -> U -> @(List, U)]; dec ADD_PRIORITYQ : [PriorityVMQueue -> Nat -> VMKLocation -> PriorityVMQueue]; def ADD_PRIORITYQ =

145

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

\(q : PriorityVMQueue, n : Nat, l : VMKLocation) let vmq = @(RETRIEVE, @(List, VMKLocation), VMK_PRIORITY_NUMBER, q, n) in let nvmq = @(INSERT_LAST, VMKLocation, vmq, l) in @(ASSIGN, @(List, VMKLocation), VMK_PRIORITY_NUMBER, q, n, nvmq); def SetVMReady = \(vm_loc : VMKLocation, nz : TMState) let vmk_manager = @(GET_TMST_VMKMAN, nz) in let vm = @(VMCB_GET, nz, vm_loc) in let vm_status = @(GetVMCBStatus, vm), vm_schedule_type = @(GetVMCBSchedType, vm), vm_priority = @(GetVMCBPriority, vm) in let nvm_status = @(InclOrVMStatus, vm_status, VMREADY) in let vm1 = @(SetVMCBStatus, vm, nvm_status) in @(GIF_THEN_ELSE, TMState, @(IsVMSchedulePr, vm_schedule_type), let priority_queue0 = @(GET_VMKMAN_PRIOTQ, vmk_manager), priority_queue1 = @(ADD_PRIORITYQ, priority_queue0, vm_priority, vm_loc) in let high_prior_qvm = @(GetHighPriorVM, priority_queue1) in let vm2 = @(SetVMCBTickSlice, vm1, @(GetVMCBTickSlSiz, vm1)) in let nz1 = @(VMCB_SET, nz, vm_loc, vm2) in let nvmk_manager0 = @(SET_VMKMAN_PQUEVM, vmk_manager, high_prior_qvm), nvmk_manager1 = @(SET_VMKMAN_PRIOTQ, nvmk_manager0, priority_queue1) in @(SET_TMST_VMKMAN, nz1, nvmk_manager1), let ttsvm = @(GET_VMKMAN_TTSVM, vmk_manager), curtts = @(GET_VMKMAN_CURTTS, vmk_manager), idlevm = @(GET_VMKMAN_IDLEVM, vmk_manager) in @(GIF_THEN_ELSE, TMState, @(EQ_VMKLOC, curtts, NIL_VMKLOC), nz, let curttscb = @(TTSCB_GET, nz, curtts) in let tts_status = @(GetTTSStatus, curttscb), tts_cur_win = @(GetTTSCurrentWin, curttscb), tts_nodes = @(GetTTSNodes, curttscb) in let ttsv = @(RETRIEVE, TTSNode, MAX_TTSCB_SIZE, tts_nodes, tts_cur_win) in let ttsvloc = @(GetTTSNodId, ttsv) in @(GIF_THEN_ELSE,

146

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

147

TMState, @(AND, @(IsTTSWaitStatus, tts_status), @(EQ_VMKLOC, ttsvloc, vm_loc)), let ncurttscb = @(SetTTSStatus, curttscb, TTSWaitStatus), nvmk_manager = @(SET_VMKMAN_TTSVM, vmk_manager, vm_loc) in let z1 = @(VMCB_SET, nz, vm_loc, vm1), z2 = @(SET_TMST_VMKMAN, z1, nvmk_manager), z3 = @(TTSCB_SET, z2, curtts, ncurttscb) in z3, nz))); def SVR_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in @(GIF_THEN_ELSE, TMState, @(IS_USE_MODE, @(TMREG_RETRIEVE, rg, MD_REG)), @(ERR_TMSTATE, z), let rval = @(TMREG_RETRIEVE, rg, r) in @(SetVMReady, @(B322NAT, rval), z));

6.3.4

Semantics of CLEAR VM WAIT

def ClearVMWaiting = \(vm_loc : VMKLocation, nz : TMState) let vm = @(VMCB_GET, nz, vm_loc) in let vm_status = @(GetVMCBStatus, vm), nvm_status = @(BitAndVMStatus, vm_status, @(SetVMNotWAIT, VMWAIT)) in let vm1 = @(SetVMCBStatus, vm, nvm_status), vm2 = @(SetVMCBWakeType, vm1, VMWUNull) in let z1 = @(VMCB_SET, nz, vm_loc, vm2) in @(GIF_THEN_ELSE, TMState, @(NOT, @(IS_VMSUSPEND, nvm_status)), @(SetVMReady, vm_loc, z1), z1); def CVW_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in @(GIF_THEN_ELSE,

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

TMState, @(IS_USE_MODE, @(TMREG_RETRIEVE, rg, MD_REG)), @(ERR_TMSTATE, z), let rval = @(TMREG_RETRIEVE, rg, r) in @(ClearVMWaiting, @(B322NAT, rval), z));

6.3.5

Semantics of EXACT VM WAIT

dec MODIFY_WT_LIST : [TMState -> VMKLocation -> @(List, VMKLocation) -> @(Product, TMState, @(List, VMKLocation))]; def MODIFY_WT_LIST = \(z : TMState, vm_loc : VMKLocation, l : @(List, VMKLocation)) @(GIF_THEN_ELSE, @(Product, TMState, @(List, VMKLocation)), @(IS_EMPTY, VMKLocation, l), @(PRODUCT, TMState, @(List, VMKLocation), z, l), let hl = @(HEAD, VMKLocation, l), tl = @(TAIL, VMKLocation, l) in @(GIF_THEN_ELSE, @(Product, TMState, @(List, VMKLocation)), @(EQ_VMKLOC, hl, vm_loc), @(GIF_THEN_ELSE, @(Product, TMState, @(List, VMKLocation)), @(IS_EMPTY, VMKLocation, tl), @(PRODUCT, TMState, @(List, VMKLocation), z, tl), let next_wt_vm_loc = @(HEAD, VMKLocation, tl) in let vm = @(VMCB_GET, z, vm_loc), next_wt_vm = @(VMCB_GET, z, next_wt_vm_loc) in let waited_tick = @(GetVMCBWaitTick, vm), next_waited_tick = @(GetVMCBWaitTick, next_wt_vm) in let next_wt_vm1 = @(SetVMCBWaitTick, next_wt_vm, @(ADD, waited_tick, next_waited_tick)) in let z1 = @(VMCB_SET, z, next_wt_vm_loc, next_wt_vm1) in @(PRODUCT, TMState, @(List, VMKLocation), z1, tl)), let z2l = @(MODIFY_WT_LIST, z, vm_loc, tl) in let z1 = @(PJ1, TMState, @(List, VMKLocation), z2l), tl1 = @(PJ2, TMState, @(List, VMKLocation), z2l) in let tl2 = @(CONS, VMKLocation, hl, tl1) in @(PRODUCT, TMState, @(List, VMKLocation), z1, tl2))); dec ExactWaitedVM : [VMKLocation -> TMState -> TMState]; def ExactWaitedVM = \(vm_loc : VMKLocation, nz : TMState) let vmk_manager = @(GET_TMST_VMKMAN, nz) in

148

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

let vm = @(VMCB_GET, nz, vm_loc) in let tick_waited_vms = @(GET_VMKMAN_TICKWT, vmk_manager) in @(GIF_THEN_ELSE, TMState, @(IS_IN_LIST, VMKLocation, vm_loc, tick_waited_vms), let z2l = @(MODIFY_WT_LIST, nz, vm_loc, tick_waited_vms) in let z1 = @(PJ1, TMState, @(List, VMKLocation), z2l), tick_waited_vms1 = @(PJ2, TMState, @(List, VMKLocation), z2l) in let nvmk_manager = @(SET_VMKMAN_TICKWT, vmk_manager, tick_waited_vms1) in let z2 = @(SET_TMST_VMKMAN, z1, nvmk_manager) in let nvm = @(SetVMCBWaitTick, vm, OO) in @(VMCB_SET, z2, vm_loc, nvm), let nvm = @(SetVMCBWaitTick, vm, OO) in @(VMCB_SET, nz, vm_loc, nvm)); def EVW_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in @(GIF_THEN_ELSE, TMState, @(IS_USE_MODE, @(TMREG_RETRIEVE, rg, MD_REG)), @(ERR_TMSTATE, z), let rval = @(TMREG_RETRIEVE, rg, r) in @(ExactWaitedVM, @(B322NAT, rval), z));

6.3.6

Semantics of TICK NOTIFY

dec NEQ : [Nat -> Nat -> Bool]; dec NGT : [Nat -> Nat -> Bool]; dec GET_LOC_LIST : [Nat -> @(List, VMKLocation) -> VMKLocation]; dec DoTTSWinServInt : [Nat -> VMCB -> VMCB]; def DoTTSWinServInt = \(vector : Nat, vm : VMCB) let vint_block = @(GetVMCBVIntCBlck, vm) in let vint_init = @(GetVMVIntInit, vint_block), vint_serv = @(GetVMVIntServCB, vint_block) in let servintcb = @(GET_INT_LIST, vector, vint_serv) in @(GIF_THEN_ELSE, VMCB, vint_init, let nservintcb = @(SetVMVIntCBFire, servintcb, TT) in

149

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

let nvint_serv = @(SET_INT_LIST, vector, vint_serv, nservintcb) in let nvint_block = @(SetVMVIntServCB, vint_block, nvint_serv) in let nvm = @(SetVMCBVIntCBlck, vm, nvint_block) in nvm, vm); dec DoVTickIntCount : [VMCB -> VMCB]; def DoVTickIntCount = \(vm : VMCB) let leave_tick = @(GetVMCBLeaveTick, vm) in @(GIF_THEN_ELSE, VMCB, @(IS_ZERO, leave_tick), let vint_block = @(GetVMCBVIntCBlck, vm) in let tickintcb = @(GetVMVIntTickCB, vint_block) in let ticks = @(GetVMVTIntCBCoun, tickintcb) in let ntickintcb = @(SetVMVTIntCBCoun, tickintcb, @(SS, ticks)) in let nvint_block = @(SetVMVIntTickCB, vint_block, ntickintcb) in @(SetVMCBVIntCBlck, vm, nvint_block), vm); dec RRSchedule : [VMKLocation -> TMState -> TMState]; def RRSchedule = \(vm_loc : VMKLocation, nz : TMState) let vmk_manager = @(GET_TMST_VMKMAN, nz) in let vm = @(VMCB_GET, nz, vm_loc) in let vm_tick_slice = @(GetVMCBTickSlice, vm), vm_tick_slice_size = @(GetVMCBTickSlSiz, vm), vm_priority = @(GetVMCBPriority, vm) in let vm_priority_queue = @(GET_VMKMAN_PRIOTQ, vmk_manager) in let vm_loc_list = @(RETRIEVE, @(List, VMKLocation), VMK_PRIORITY_NUMBER, vm_priority_queue, vm_priority) in @(GIF_THEN_ELSE, TMState, @(IS_ZERO, vm_tick_slice), let vm1 = @(SetVMCBTickSlice, vm, vm_tick_slice_size) in @(GIF_THEN_ELSE, TMState, @(IS_EMPTY, VMKLocation, vm_loc_list), nz, let hvm_loc = @(HEAD, VMKLocation, vm_loc_list), tvm_loc_list = @(TAIL, VMKLocation, vm_loc_list) in let vm_loc_list1 = @(INSERT_LAST, VMKLocation, tvm_loc_list, hvm_loc) in let vm_priority_queue1 = @(ASSIGN,

150

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

@(List, VMKLocation), VMK_PRIORITY_NUMBER, vm_priority_queue, vm_priority, vm_loc_list1) in let nvmk_manager = @(SET_VMKMAN_PQUEVM, vmk_manager, @(HEAD, VMKLocation, vm_loc_list1)) in @(SET_TMST_VMKMAN, nz, nvmk_manager)), nz); dec DoTickWaitedVM : [TMState -> TMState]; dec CheckTickWaitedVM : [@(List, VMKLocation) -> TMState -> TMState]; def CheckTickWaitedVM = \(l : @(List, VMKLocation), nz : TMState) let vmk_manager = @(GET_TMST_VMKMAN, nz) in @(GIF_THEN_ELSE, TMState, @(IS_EMPTY, VMKLocation, l), nz, let vm_loc = @(HEAD, VMKLocation, l), tail_l = @(TAIL, VMKLocation, l) in let vm = @(VMCB_GET, nz, vm_loc) in let waited_tick = @(GetVMCBWaitTick, vm) in @(GIF_THEN_ELSE, TMState, @(IS_ZERO, waited_tick), let nvmk_manager = @(SET_VMKMAN_TICKWT, vmk_manager, tail_l) in let z1 = @(SET_TMST_VMKMAN, nz, nvmk_manager), z2 = @(ClearVMWaiting, vm_loc, z1) in @(CheckTickWaitedVM, tail_l, z2), nz)); def DoTickWaitedVM = \(nz : TMState) let vmk_manager = @(GET_TMST_VMKMAN, nz) in let nodes = @(GET_VMKMAN_TICKWT, vmk_manager) in @(GIF_THEN_ELSE, TMState, @(IS_EMPTY, VMKLocation, nodes), nz, let vm_loc = @(HEAD, VMKLocation, nodes), tail_l = @(TAIL, VMKLocation, nodes) in let vm = @(VMCB_GET, nz, vm_loc) in let waited_tick = @(GetVMCBWaitTick, vm) in let nwaited_tick = @(PP, waited_tick) in let vm1 = @(SetVMCBWaitTick, vm, nwaited_tick) in let z1 = @(VMCB_SET, nz, vm_loc, vm1) in @(CheckTickWaitedVM, nodes, z1));

151

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

dec TTS_WIN_SERV_INT : Nat; dec ClearVMWaitUp : [VMCB -> VMCB]; dec TickNotify : [TickNotifyType -> TMState -> @(Product, Bool, TMState)]; def SystTickNotify = \(type : TickNotifyType, nz : TMState) let vmk_manager = @(GET_TMST_VMKMAN, nz) in let vm_loc = @(GET_VMKMAN_RUNVM, vmk_manager), vmk_tick = @(GET_VMKMAN_TICKCN, vmk_manager) in let vm = @(VMCB_GET, nz, vm_loc) in let nvmk_tick = @(SS, vmk_tick) in let vm_tick = @(GetVMCBTickUsage, vm), nvm_tick = @(SS, vm_tick) in let vm_leave_tick = @(GetVMCBLeaveTick, vm), vm_schedule_type = @(GetVMCBSchedType, vm) in let nvm = @(SetVMCBTickUsage, vm, nvm_tick), mvm = @(GIF_THEN_ELSE, VMCB, @(IS_ZERO, vm_leave_tick), @(DoVTickIntCount, nvm), nvm) in let z0 = @(VMCB_SET, nz, vm_loc, mvm) in let nvmk_manager = @(SET_VMKMAN_TICKCN, vmk_manager, nvmk_tick) in let z1 = @(SET_TMST_VMKMAN, z0, nvmk_manager), z2 = @(GIF_THEN_ELSE, TMState, @(IsVMSchedulePr, vm_schedule_type), @(RRSchedule, vm_loc, z1), z1), z3 = @(VMCB_SET, z2, vm_loc, nvm) in @(DoTickWaitedVM, z3); def CheckWindowTick = \(tts_loc : VMKLocation, nz : TMState) let vmk_manager = @(GET_TMST_VMKMAN, nz) in let tts = @(TTSCB_GET, nz, tts_loc) in let status = @(GetTTSStatus, tts), node_max = @(GETTTSNodeMax, tts), main_frame_ticks = @(GetTTSMFrameTick, tts), window_ticks = @(GetTTSWindowTick, tts), frame_ticks = @(GetTTSFrameTick, tts), frames = @(GetTTSFrames, tts), current_window = @(GetTTSCurrentWin, tts), nodes = @(GetTTSNodes, tts) in let node_index = @(GIF_THEN_ELSE, Nat, @(IsTTSIdle, status), current_window, @(SS, current_window)) in let node = @(RETRIEVE, TTSNode, MAX_TTSCB_SIZE, nodes, node_index) in

152

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

let node_id = @(GetTTSNodId, node), node_start_time = @(GetTTSNodStart, node), node_during_time = @(GetTTSNodDuring, node) in @(GIF_THEN_ELSE, TMState, @(IS_ZERO, node_during_time), let tts1 = @(SetTTSStatus, tts, TTSWaitFrame) in let z1 = @(TTSCB_SET, nz, tts_loc, tts1) in let nvmk_manager = @(SET_VMKMAN_TTSVM, vmk_manager, @(GET_VMKMAN_IDLEVM, vmk_manager)) in @(SET_TMST_VMKMAN, z1, nvmk_manager), let tts1 = @(SetTTSCurrentWin, tts, node_index) in @(GIF_THEN_ELSE, TMState, @(NGT, node_start_time, frame_ticks), let tts2 = @(SetTTSStatus, tts1, TTSIdle), tts3 = @(SetTTSWindowTick, tts2, @(MINUS, node_start_time, frame_ticks)) in let z1 = @(TTSCB_SET, nz, tts_loc, tts3) in let nvmk_manager = @(SET_VMKMAN_TTSVM, vmk_manager, @(GET_VMKMAN_IDLEVM, vmk_manager)) in @(SET_TMST_VMKMAN, z1, nvmk_manager), let tts2 = @(SetTTSWindowTick, tts1, node_during_time) in let vm = @(VMCB_GET, nz, node_id) in let vm1 = @(ClearVMWaitUp, vm) in let vm_schedule_type = @(GetVMCBSchedType, vm1), vm_status = @(GetVMCBStatus, vm1) in @(GIF_THEN_ELSE, TMState, @(NOT, @(IsVMScheduleTT, vm_schedule_type)), let tts3 = @(SetTTSStatus, tts2, TTSAbort) in let z1 = @(TTSCB_SET, nz, tts_loc, tts3), z2 = @(VMCB_SET, z1, node_id, vm1) in let nvmk_manager = @(SET_VMKMAN_TTSVM, vmk_manager, @(GET_VMKMAN_IDLEVM, vmk_manager)) in @(SET_TMST_VMKMAN, z2, nvmk_manager), @(GIF_THEN_ELSE, TMState, @(NOT, @(IS_VMREADY, vm_status)), let tts3 = @(SetTTSStatus, tts2, TTSWaitStatus) in let z1 = @(TTSCB_SET, nz, tts_loc, tts3), z2 = @(VMCB_SET, z1, node_id, vm1) in let nvmk_manager = @(SET_VMKMAN_TTSVM, vmk_manager, @(GET_VMKMAN_IDLEVM, vmk_manager)) in @(SET_TMST_VMKMAN, z2, nvmk_manager), let tts3 = @(SetTTSStatus, tts2, TTSRunning) in let z1 = @(TTSCB_SET, nz, tts_loc, tts3) in

153

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

let nvmk_manager = @(SET_VMKMAN_TTSVM, vmk_manager, node_id) in let vm2 = @(DoTTSWinServInt, TTS_WIN_SERV_INT, vm1) in let z2 = @(VMCB_SET, z1, node_id, vm2) in @(SET_TMST_VMKMAN, z2, nvmk_manager))))); dec DoTTSEnd : [VMKLocation -> TMState -> @(Product, Bool, TMState)]; def CheckFrameTick = \(tts_loc : VMKLocation, nz : TMState) let vmk_manager = @(GET_TMST_VMKMAN, nz) in let tts = @(TTSCB_GET, nz, tts_loc) in let status = @(GetTTSStatus, tts), node_max = @(GETTTSNodeMax, tts), main_frame_ticks = @(GetTTSMFrameTick, tts), window_ticks = @(GetTTSWindowTick, tts), frame_ticks = @(GetTTSFrameTick, tts), frames = @(GetTTSFrames, tts), current_window = @(GetTTSCurrentWin, tts), nodes = @(GetTTSNodes, tts) in let tts1 = @(SetTTSFrameTick, tts, OO), tts2 = @(SetTTSFrames, tts1, @(SS, frames)), tts3 = @(SetTTSCurrentWin, tts2, OO) in let node = @(RETRIEVE, TTSNode, MAX_TTSCB_SIZE, nodes, OO) in let node_id = @(GetTTSNodId, node), node_start_time = @(GetTTSNodStart, node), node_during_time = @(GetTTSNodDuring, node) in @(GIF_THEN_ELSE, TMState, @(NGT, node_start_time, frame_ticks), let tts4 = @(SetTTSStatus, tts3, TTSIdle), tts5 = @(SetTTSWindowTick, tts4, @(MINUS, node_start_time, frame_ticks)) in let z1 = @(TTSCB_SET, nz, tts_loc, tts5) in let nvmk_manager = @(SET_VMKMAN_TTSVM, vmk_manager, @(GET_VMKMAN_IDLEVM, vmk_manager)) in @(SET_TMST_VMKMAN, z1, nvmk_manager), let tts4 = @(SetTTSWindowTick, tts3, node_during_time) in let vm = @(VMCB_GET, nz, node_id) in let vm1 = @(ClearVMWaitUp, vm) in let vm_schedule_type = @(GetVMCBSchedType, vm1), vm_status = @(GetVMCBStatus, vm1) in @(GIF_THEN_ELSE, TMState, @(NOT, @(IsVMScheduleTT, vm_schedule_type)), let tts5 = @(SetTTSStatus, tts4, TTSAbort) in let z1 = @(TTSCB_SET, nz, tts_loc, tts5) in let nvmk_manager = @(SET_VMKMAN_TTSVM, vmk_manager,

154

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

155

@(GET_VMKMAN_IDLEVM, vmk_manager)) in let z2 = @(VMCB_SET, z1, node_id, vm1) in @(SET_TMST_VMKMAN, z2, nvmk_manager), @(GIF_THEN_ELSE, TMState, @(NOT, @(IS_VMREADY, vm_status)), let tts5 = @(SetTTSStatus, tts4, TTSWaitStatus) in let z1 = @(TTSCB_SET, nz, tts_loc, tts5) in let nvmk_manager = @(SET_VMKMAN_TTSVM, vmk_manager, @(GET_VMKMAN_IDLEVM, vmk_manager)) in let z2 = @(VMCB_SET, z1, node_id, vm1) in @(SET_TMST_VMKMAN, z2, nvmk_manager), let tts5 = @(SetTTSStatus, tts4, TTSRunning) in let z1 = @(TTSCB_SET, nz, tts_loc, tts5) in let nvmk_manager = @(SET_VMKMAN_TTSVM, vmk_manager, node_id) in let vm2 = @(DoTTSWinServInt, TTS_WIN_SERV_INT, vm1) in let z2 = @(VMCB_SET, z1, node_id, vm2) in @(SET_TMST_VMKMAN, z2, nvmk_manager)))); dec SetTTSTick : [Nat -> TickNotifyType -> TMState -> TMState]; def DoTTSEnd = \(tts_loc : VMKLocation, z : TMState) let tts = @(TTSCB_GET, z, tts_loc) in let status = @(GetTTSStatus, tts), main_frame_ticks = @(GetTTSMFrameTick, tts), frame_ticks = @(GetTTSFrameTick, tts), window_ticks = @(GetTTSWindowTick, tts) in @(GIF_THEN_ELSE, @(Product, Bool, TMState), @(NOT, @(NEQ, main_frame_ticks, frame_ticks)), let z1 = @(GIF_THEN_ELSE, TMState, @(IsTTSWaitFrame, status), @(SetTTSTick, @(MINUS, main_frame_ticks, frame_ticks), VMK_FRAMETICK, z), @(SetTTSTick, window_ticks, VMK_WINDOWTICK, z)) in @(PRODUCT, Bool, TMState, FF, z1), @(PRODUCT, Bool, TMState, TT, z)); def TickNotify = \(type : TickNotifyType, nz : TMState) let vmk_manager = @(GET_TMST_VMKMAN, nz) in let z2 = @(GIF_THEN_ELSE, TMState, @(IS_VMK_SYSTICK, type), @(SystTickNotify, type, nz),

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

156

nz) in let tts_loc = @(GET_VMKMAN_CURTTS, vmk_manager) in let z3 = @(GIF_THEN_ELSE, TMState, @(AND, @(NOT, @(EQ_VMKLOC, tts_loc, NIL_VMKLOC)), @(OR, @(IS_VMK_WINDOWTICK, type), @(IS_VMK_FRAMETICK, type))), let z4 = @(GIF_THEN_ELSE, TMState, @(IS_VMK_WINDOWTICK, type), @(CheckWindowTick, tts_loc, z2), z2) in @(GIF_THEN_ELSE, TMState, @(IS_VMK_FRAMETICK, type), @(CheckFrameTick, tts_loc, z4), z4), z2) in @(DoTTSEnd, tts_loc, z3); def TMN_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in @(GIF_THEN_ELSE, TMState, @(IS_USE_MODE, @(TMREG_RETRIEVE, rg, MD_REG)), @(ERR_TMSTATE, z), let rval = @(TMREG_RETRIEVE, rg, r) in let b2z = @(TickNotify, rval, z) in let nb = @(PJ1, Bool, TMState, b2z), nz = @(PJ2, Bool, TMState, b2z) in let sval = @(BOOL2B32, nb) in let nrg = @(TMREG_ASSIGN, rg, s, sval) in @(SET_TMST_TMREG, nz, nrg));

6.4 6.4.1

Semantics for Interrupt and Virtual Interrupt Management Semantics of EPIC

dec DoEnablePIC : [TMState -> VMKLocation -> VMVIntCBList -> VMVIntCBList];

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

def DoEnablePIC = \(nz : TMState, enable_pic_loc : VMKLocation, int_list : VMVIntCBList) let vintcb = @(GET_INT_LIST, enable_pic_loc, int_list) in let intmask = @(GetVMVIntCBMask, vintcb) in @(GIF_THEN_ELSE, VMVIntCBList, @(NOT, intmask), let vintcb1 = @(SetVMVIntCBMask, vintcb, FF) in @(SET_INT_LIST, enable_pic_loc, int_list, vintcb1), int_list); def EnablePIC = \(enabpicloc : VMKLocation, nz : TMState) let vmk_manager = @(GET_TMST_VMKMAN, nz) in let current_vm_loc = @(GET_VMKMAN_RUNVM, vmk_manager) in let vmcb = @(VMCB_GET, nz, current_vm_loc) in let vintcblock = @(GetVMCBVIntCBlck, vmcb) in let vextrintl = @(GetVMVIntExtrCB, vintcblock), vexcpintl = @(GetVMVIntExcpCB, vintcblock), vservintl = @(GetVMVIntServCB, vintcblock) in @(GIF_THEN_ELSE, TMState, @(OR, @(IS_IN_INT_LIST, enabpicloc, vextrintl), @(OR, @(IS_IN_INT_LIST, enabpicloc, vexcpintl), @(IS_IN_INT_LIST, enabpicloc, vservintl))), @(GIF_THEN_ELSE, TMState, @(IS_IN_INT_LIST, enabpicloc, vextrintl), let nvextrintl = @(DoEnablePIC, nz, enabpicloc, vextrintl) in let nvintcblock = @(SetVMVIntExtrCB, vintcblock, nvextrintl) in let nvmcb = @(SetVMCBVIntCBlck, vmcb, nvintcblock) in @(VMCB_SET, nz, current_vm_loc, nvmcb), @(GIF_THEN_ELSE, TMState, @(IS_IN_INT_LIST, enabpicloc, vexcpintl), let nvexcpintl = @(DoEnablePIC, nz, enabpicloc, vexcpintl) in let nvintcblock = @(SetVMVIntExcpCB, vintcblock, nvexcpintl) in let nvmcb = @(SetVMCBVIntCBlck, vmcb, nvintcblock) in @(VMCB_SET, nz, current_vm_loc, nvmcb), let nvservintl = @(DoEnablePIC, nz, enabpicloc, vservintl) in let nvintcblock = @(SetVMVIntServCB, vintcblock, nvservintl) in let nvmcb = @(SetVMCBVIntCBlck, vmcb, nvintcblock) in @(VMCB_SET, nz, current_vm_loc, nvmcb))), nz); def EPIC_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z),

157

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z), vm = @(GET_TMST_VMCBLT, z), ts = @(GET_TMST_TTSCBL, z) in @(GIF_THEN_ELSE, TMState, @(IS_USE_MODE, @(TMREG_RETRIEVE, rg, MD_REG)), @(ERR_TMSTATE, z), let rval = @(TMREG_RETRIEVE, rg, r) in @(EnablePIC, @(B322NAT, rval), z));

6.4.2

Semantics of DPIC

dec DoDisablePIC : [TMState -> VMKLocation -> VMVIntCBList -> VMVIntCBList]; def DoDisablePIC = \(nz : TMState, disable_pic_loc : VMKLocation, int_list : VMVIntCBList) let vintcb = @(GET_INT_LIST, disable_pic_loc, int_list) in let intmask = @(GetVMVIntCBMask, vintcb) in @(GIF_THEN_ELSE, VMVIntCBList, @(NOT, intmask), let vintcb1 = @(SetVMVIntCBMask, vintcb, TT) in @(SET_INT_LIST, disable_pic_loc, int_list, vintcb1), int_list); def DisablePIC = \(disabpicloc : VMKLocation, nz : TMState) let vmk_manager = @(GET_TMST_VMKMAN, nz) in let current_vm_loc = @(GET_VMKMAN_RUNVM, vmk_manager) in let vmcb = @(VMCB_GET, nz, current_vm_loc) in let vintcblock = @(GetVMCBVIntCBlck, vmcb) in let vextrintl = @(GetVMVIntExtrCB, vintcblock), vexcpintl = @(GetVMVIntExcpCB, vintcblock), vservintl = @(GetVMVIntServCB, vintcblock) in @(GIF_THEN_ELSE, TMState, @(OR, @(IS_IN_INT_LIST, disabpicloc, vextrintl), @(OR, @(IS_IN_INT_LIST, disabpicloc, vexcpintl), @(IS_IN_INT_LIST, disabpicloc, vservintl))), @(GIF_THEN_ELSE, TMState, @(IS_IN_INT_LIST, disabpicloc, vextrintl),

158

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

let nvextrintl = @(DoDisablePIC, nz, disabpicloc, vextrintl) let nvintcblock = @(SetVMVIntExtrCB, vintcblock, nvextrintl) let nvmcb = @(SetVMCBVIntCBlck, vmcb, nvintcblock) in @(VMCB_SET, nz, current_vm_loc, nvmcb), @(GIF_THEN_ELSE, TMState, @(IS_IN_INT_LIST, disabpicloc, vexcpintl), let nvexcpintl = @(DoDisablePIC, nz, disabpicloc, vexcpintl) let nvintcblock = @(SetVMVIntExcpCB, vintcblock, nvexcpintl) let nvmcb = @(SetVMCBVIntCBlck, vmcb, nvintcblock) in @(VMCB_SET, nz, current_vm_loc, nvmcb), let nvservintl = @(DoDisablePIC, nz, disabpicloc, vservintl) let nvintcblock = @(SetVMVIntServCB, vintcblock, nvservintl) let nvmcb = @(SetVMCBVIntCBlck, vmcb, nvintcblock) in @(VMCB_SET, nz, current_vm_loc, nvmcb))), nz); def DPIC_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z), vm = @(GET_TMST_VMCBLT, z), ts = @(GET_TMST_TTSCBL, z) in @(GIF_THEN_ELSE, TMState, @(IS_USE_MODE, @(TMREG_RETRIEVE, rg, MD_REG)), @(ERR_TMSTATE, z), let rval = @(TMREG_RETRIEVE, rg, r) in @(DisablePIC, @(B322NAT, rval), z));

6.4.3

Semantics of SSINT

dec ExactWaitedVM : [VMKLocation -> TMState -> TMState]; dec ClearVMWaiting : [VMKLocation -> TMState -> TMState]; def SendServInt = \(sendvmloc : VMKLocation, sdservloc : VMKLocation, nz : TMState) let vmk_manager = @(GET_TMST_VMKMAN, nz) in let vmcb = @(VMCB_GET, nz, sendvmloc) in let vm_vintblock = @(GetVMCBVIntCBlck, vmcb), vm_status = @(GetVMCBStatus, vmcb), vm_wakeup_type = @(GetVMCBWakeType, vmcb) in let vintinit = @(GetVMVIntInit, vm_vintblock), vservintl = @(GetVMVIntServCB, vm_vintblock) in @(GIF_THEN_ELSE, TMState,

in in

in in

in in

159

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

@(IS_VMSLEEP, vm_status), @(ERR_TMSTATE, nz), @(GIF_THEN_ELSE, TMState, @(NOT, vintinit), @(ERR_TMSTATE, nz), @(GIF_THEN_ELSE, TMState, @(NOT, @(IS_IN_INT_LIST, sdservloc, vservintl)), @(ERR_TMSTATE, nz), let vservintcb = @(GET_INT_LIST, sdservloc, vservintl) in let servintmask = @(GetVMVIntCBMask, vservintcb) in @(GIF_THEN_ELSE, TMState, @(NOT, servintmask), let vservintcb1 = @(SetVMVIntCBFire, vservintcb, TT) in let vservintl1 = @(SET_INT_LIST, sdservloc, vservintl, vservintcb1), vm_vintblock1 = @(SetVMVIntServCB, vm_vintblock, vservintl1), vmcb1 = @(SetVMCBVIntCBlck, vmcb, vm_vintblock1) in let z2 = @(VMCB_SET, nz, sendvmloc, vmcb1) in @(GIF_THEN_ELSE, TMState, @(IS_VMWUBasic, vm_wakeup_type), let z3 = let tick_waited_vms = @(GET_VMKMAN_TICKWT, vmk_manager) in @(GIF_THEN_ELSE, TMState, @(IS_IN_LIST, VMKLocation, sendvmloc, tick_waited_vms), @(ExactWaitedVM, sendvmloc, z2), z2), z4 = @(ClearVMWaiting, sendvmloc, z3) in z4, z2), @(ERR_TMSTATE, nz))))); def SSINT_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z), vm = @(GET_TMST_VMCBLT, z), ts = @(GET_TMST_TTSCBL, z) in @(GIF_THEN_ELSE, TMState, @(IS_USE_MODE, @(TMREG_RETRIEVE, rg, MD_REG)), @(ERR_TMSTATE, z), let rval = @(TMREG_RETRIEVE, rg, r),

160

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

sval = @(TMREG_RETRIEVE, rg, s) in @(SendServInt, @(B322NAT, rval), @(B322NAT, sval), z));

6.4.4

Semantics of VAE

def VAckException = \(nz : TMState) let vmk_manager = @(GET_TMST_VMKMAN, nz) in let current_vm_loc = @(GET_VMKMAN_RUNVM, vmk_manager) in let vmcb = @(VMCB_GET, nz, current_vm_loc) in let vintcblock = @(GetVMCBVIntCBlck, vmcb) in let nvintcblock = @(SetVMVIntExcpNum, vintcblock, OO) in let nvmcb = @(SetVMCBVIntCBlck, vmcb, nvintcblock) in @(VMCB_SET, nz, current_vm_loc, nvmcb); def VAE_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), st = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in @(GIF_THEN_ELSE, TMState, @(IS_USE_MODE, @(TMREG_RETRIEVE, rg, MD_REG)), @(ERR_TMSTATE, z), @(VAckException, z));

6.4.5

Semantics of TVI

def VIntTickTrigger = \(z : TMState, vintcb : VMVTickIntCB) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), st = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let int = @(GetVMVTIntCBFire, vintcb) in @(GIF_THEN_ELSE, TMState, int, let tmreg = @(GetVMVTIntCBHand, vintcb) in let z1 = @(SET_TMST_TMREG, z, tmreg), z2 = @(SET_TMST_TMSREG, z1, @(PUSH, TMReg, rg, st)) in z2, z);

161

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

def VIntTrigger = \(z : TMState, vintcb : VMVIntCB) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), st = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let int = @(GetVMVIntCBFire, vintcb) in @(GIF_THEN_ELSE, TMState, int, let tmreg = @(GetVMVIntCBHand, vintcb) in let z1 = @(SET_TMST_TMREG, z, tmreg), z2 = @(SET_TMST_TMSREG, z1, @(PUSH, TMReg, rg, st)) in z2, z); dec VIntTriggerList : [TMState -> VMVIntCBList -> TMState]; def VIntTriggerList = \(z : TMState, intl : VMVIntCBList) @(GIF_THEN_ELSE, TMState, @(IS_EMPTY, VMVIntCB, intl), z, let hintl = @(HEAD, VMVIntCB, intl), tintl = @(TAIL, VMVIntCB, intl) in let nz = @(VIntTrigger, z, hintl) in @(VIntTriggerList, nz, tintl)); dec RTVTickIntTrigger : [VMVTickIntCB -> VMVTickIntCB]; def RTVTickIntTrigger = \(vintcb : VMVTickIntCB) let int = @(GetVMVTIntCBFire, vintcb) in @(GIF_THEN_ELSE, VMVTickIntCB, int, @(SetVMVTIntCBFire, vintcb, FF), vintcb); def RTVIntTrigger = \(vintcb : VMVIntCB) let int = @(GetVMVIntCBFire, vintcb) in @(GIF_THEN_ELSE, VMVIntCB, int, @(SetVMVIntCBFire, vintcb, FF), vintcb); dec RTVIntTriggerList : [VMVIntCBList -> VMVIntCBList];

162

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

def RTVIntTriggerList = \(vintcb_list : VMVIntCBList) @(GIF_THEN_ELSE, VMVIntCBList, @(IS_EMPTY, VMVIntCB, vintcb_list), vintcb_list, let hvintcb_list = @(HEAD, VMVIntCB, vintcb_list), tvintcb_list = @(TAIL, VMVIntCB, vintcb_list) in let nhvintcb_list = @(RTVIntTrigger, hvintcb_list), ntvintcb_list = @(RTVIntTriggerList, tvintcb_list) in @(CONS, VMVIntCB, hvintcb_list, tvintcb_list)); def TriggerVInt = \(nz : TMState) let vmk_manager = @(GET_TMST_VMKMAN, nz), current_vm_loc = @(GET_VMKMAN_RUNVM, vmk_manager) in let vmcb = @(VMCB_GET, nz, current_vm_loc) in let vintcblock = @(GetVMCBVIntCBlck, vmcb) in let vtickint = @(GetVMVIntTickCB, vintcblock), vservintl = @(GetVMVIntServCB, vintcblock), vextrintl = @(GetVMVIntExtrCB, vintcblock), vexcpintl = @(GetVMVIntExcpCB, vintcblock) in let z1 = @(VIntTickTrigger, nz, vtickint), z2 = @(VIntTriggerList, z1, vservintl), z3 = @(VIntTriggerList, z2, vextrintl), z4 = @(VIntTriggerList, z3, vexcpintl) in let nvtickint = @(RTVTickIntTrigger, vtickint), nvservintl = @(RTVIntTriggerList, vservintl), nvextrintl = @(RTVIntTriggerList, vextrintl), nvexcpintl = @(RTVIntTriggerList, vexcpintl) in let vintcblock1 = @(SetVMVIntTickCB, vintcblock, nvtickint), vintcblock2 = @(SetVMVIntServCB, vintcblock1, nvservintl), vintcblock3 = @(SetVMVIntExtrCB, vintcblock2, nvextrintl), vintcblock4 = @(SetVMVIntExcpCB, vintcblock3, nvexcpintl) in let nvmcb = @(SetVMCBVIntCBlck, vmcb, vintcblock4) in @(VMCB_SET, z4, current_vm_loc, nvmcb); def TVI_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), st = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in @(GIF_THEN_ELSE, TMState, @(IS_USE_MODE, @(TMREG_RETRIEVE, rg, MD_REG)), @(ERR_TMSTATE, z), @(TriggerVInt, z));

163

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

6.4.6

Semantics of INTP

def IntDispatch = \(dispatchintnum : Nat, nz : TMState) let vmk_manager = @(GET_TMST_VMKMAN, nz) in let intl = @(GET_VMKMAN_INTDIS, vmk_manager) in let vm_loc = @(GET_LOC_LIST, dispatchintnum, intl) in let vmcb = @(VMCB_GET, nz, vm_loc) in let vm_intcbs = @(GetVMCBVIntCBlck, vmcb), vm_status = @(GetVMCBStatus, vmcb), vm_wakeup_type = @(GetVMCBWakeType, vmcb) in let vintinit = @(GetVMVIntInit, vm_intcbs), vextrintl = @(GetVMVIntExtrCB, vm_intcbs), vextrintcb = @(GET_INT_LIST, dispatchintnum, vextrintl) in @(GIF_THEN_ELSE, TMState, @(IS_VMSLEEP, vm_status), @(ERR_TMSTATE, nz), @(GIF_THEN_ELSE, TMState, @(NOT, vintinit), @(ERR_TMSTATE, nz), let vextrintcb1 = @(SetVMVIntCBFire, vextrintcb, TT), vextrintl1 = @(SET_INT_LIST, dispatchintnum, vextrintl, vextrintcb1), vm_intcbs1 = @(SetVMVIntExtrCB, vm_intcbs, vextrintl1), vmcb1 = @(SetVMCBVIntCBlck, vmcb, vm_intcbs1), z0 = @(VMCB_SET, nz, vm_loc, vmcb1) in @(GIF_THEN_ELSE, TMState, @(IS_VMWUBasic, vm_wakeup_type), let z1 = let tick_waited_vms = @(GET_VMKMAN_TICKWT, vmk_manager) in @(GIF_THEN_ELSE, TMState, @(IS_IN_LIST, VMKLocation, vm_loc, tick_waited_vms), @(ExactWaitedVM, vm_loc, z0), z0) in @(ClearVMWaiting, vm_loc, z1), nz))); def INTP_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z), vm = @(GET_TMST_VMCBLT, z), ts = @(GET_TMST_TTSCBL, z) in @(GIF_THEN_ELSE, TMState,

164

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

@(IS_USE_MODE, @(TMREG_RETRIEVE, rg, MD_REG)), @(ERR_TMSTATE, z), let rval = @(TMREG_RETRIEVE, rg, r) in @(IntDispatch, @(B322NAT, rval), z));

6.4.7

Semantics of IVTI

def InitVTickInt = \(tickintmsk : Bool, tickintsrv : TMReg, nz : TMState) let vmk_manager = @(GET_TMST_VMKMAN, nz) in let current_vm_loc = @(GET_VMKMAN_RUNVM, vmk_manager) in let vmcb = @(VMCB_GET, nz, current_vm_loc) in let vintcblock = @(GetVMCBVIntCBlck, vmcb) in let vtickintcb = @(GetVMVIntTickCB, vintcblock), vintinit = @(GetVMVIntInit, vintcblock) in @(GIF_THEN_ELSE, TMState, @(NOT, vintinit), let vtickintcb1 = @(SetVMVTIntCBMask, vtickintcb, tickintmsk), vtickintcb2 = @(SetVMVTIntCBHand, vtickintcb1, tickintsrv) in let vintcblock0 = @(SetVMVIntTickCB, vintcblock, vtickintcb2) in let vintcblock1 = @(SetVMVIntInit, vintcblock0, TT), vintcblock2 = @(SetVMVIntExcpNum, vintcblock1, OO) in let vmcb2 = @(SetVMCBVIntCBlck, vmcb, vintcblock2) in @(VMCB_SET, nz, current_vm_loc, vmcb2), nz); def IVTI_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z), vm = @(GET_TMST_VMCBLT, z), ts = @(GET_TMST_TTSCBL, z) in @(GIF_THEN_ELSE, TMState, @(IS_USE_MODE, @(TMREG_RETRIEVE, rg, MD_REG)), @(ERR_TMSTATE, z), let rval = @(TMREG_RETRIEVE, rg, r), sval = @(TMREG_RETRIEVE, rg, s) in let tmreg = @(TMREG_ASSIGN, TMREG_NEW, IH_REG, sval) in @(InitVTickInt, @(B322BOOL, rval), tmreg, z));

165

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

6.5 6.5.1

Semantics for Location List Semantics of INSERT WVM

def INSERT_WVM_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z) in let rval = @(TMREG_RETRIEVE, rg, r), sval = @(TMREG_RETRIEVE, rg, s) in let vm_loc = @(B322NAT, rval), tick = @(B322NAT, sval) in @(InsertWaitedVM, z, vm_loc, tick);

6.5.2

Semantics of VLOC EMPTY

def VLOC_EMPY_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z) in let rval = @(TMREG_RETRIEVE, rg, r) in let list_index = @(B322NAT, rval) in let b = @(VMLOC_EMPY, z, list_index) in let nrg = @(TMREG_ASSIGN, rg, s, @(BOOL2B32, b)) in @(SET_TMST_TMREG, z, nrg);

6.5.3

Semantics of VLOC HEAD

def VLOC_HEAD_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z) in let rval = @(TMREG_RETRIEVE, rg, r) in let list_index = @(B322NAT, rval) in

166

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

let loc = @(VMLOC_HEAD, z, list_index) in let nrg = @(TMREG_ASSIGN, rg, s, @(NAT2B32, loc)) in @(SET_TMST_TMREG, z, nrg);

6.5.4

Semantics of VLOC TAIL

def VLOC_TAIL_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z) in let rval = @(TMREG_RETRIEVE, rg, r) in let list_index = @(B322NAT, rval) in @(VMLOC_TAIL, z, list_index);

6.5.5

Semantics of VLOC CONS

def VLOC_CONS_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z) in let rval = @(TMREG_RETRIEVE, rg, r), sval = @(TMREG_RETRIEVE, rg, s) in let list_index = @(B322NAT, rval), loc = @(B322NAT, sval) in @(VMLOC_CONS, z, list_index, loc);

6.5.6

Semantics of VLOC IN

def VLOC_IN_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z) in let rval = @(TMREG_RETRIEVE, rg, r),

167

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

sval = @(TMREG_RETRIEVE, rg, s) in let list_index = @(B322NAT, rval), loc = @(B322NAT, sval) in let b = @(VMLOC_IN, z, list_index, loc) in let nrg = @(TMREG_ASSIGN, rg, t, @(BOOL2B32, b)) in @(SET_TMST_TMREG, z, nrg);

6.5.7

Semantics of VLOC GET

def VLOC_GET_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z) in let rval = @(TMREG_RETRIEVE, rg, r), sval = @(TMREG_RETRIEVE, rg, s) in let list_index = @(B322NAT, rval), loc = @(B322NAT, sval) in let v = @(VMLOC_GET, z, list_index, loc) in let nrg = @(TMREG_ASSIGN, rg, t, @(NAT2B32, v)) in @(SET_TMST_TMREG, z, nrg);

6.5.8

Semantics of VLOC SET

def VLOC_SET_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z) in let rval = @(TMREG_RETRIEVE, rg, r), sval = @(TMREG_RETRIEVE, rg, s), tval = @(TMREG_RETRIEVE, rg, t) in let list_index = @(B322NAT, rval), loc = @(B322NAT, sval), v = @(B322NAT, tval) in @(VMLOC_SET, z, list_index, loc, v);

168

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

6.5.9

Semantics of VLOC DEL

def VLOC_DEL_SEM = \(z : TMState, r : Nat, s : Nat, t : Nat) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z), mn = @(GET_TMST_VMKMAN, z) in let rval = @(TMREG_RETRIEVE, rg, r), sval = @(TMREG_RETRIEVE, rg, s) in let list_index = @(B322NAT, rval), loc = @(B322NAT, sval) in @(VMLOC_DEL, z, list_index, loc);

6.6 6.6.1

Semantics of TM-2 Semantics of RO-Instructions

def TMROSEM = \(z : TMState, i : ROInstr) @(i, TMState, \(o : ROOpcode, r : Nat, s : Nat, t : Nat) @(o, TMState, @(IRET_SEM, z, r, s, t), @(VIRET_SEM, z, r, s, t), @(HALT_SEM, z, r, s, t), @(ADD_SEM, z, r, s, t), @(SUB_SEM, z, r, s, t), @(MUL_SEM, z, r, s, t), @(DIV_SEM, z, r, s, t), @(BITAND_SEM, z, r, s, t), @(BITOR_SEM, z, r, s, t), @(BITMASK_SEM, z, r, s, t), @(BITANDMATCH_SEM, z, r, s, t), @(BITORMATCH_SEM, z, r, s, t), @(BITSHIFTL_SEM, z, r, s, t), @(BITSHIFTR_SEM, z, r, s, t), @(SCH_SEM, z, r, s, t), @(SVR_SEM, z, r, s, t), @(CVR_SEM, z, r, s, t), @(EVW_SEM, z, r, s, t), @(CVW_SEM, z, r, s, t),

169

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

@(TMN_SEM, z, r, s, t), @(MAN_GET_SEM, z, r, s, t), @(MAN_SET_SEM, z, r, s, t), @(VM_GET_SEM, z, r, s, t), @(VM_SET_SEM, z, r, s, t), @(TTS_GET_SEM, z, r, s, t), @(TTS_SET_SEM, z, r, s, t), @(EPIC_SEM, z, r, s, t), @(DPIC_SEM, z, r, s, t), @(SSINT_SEM, z, r, s, t), @(VAE_SEM, z, r, s, t), @(TVI_SEM, z, r, s, t), @(INTP_SEM, z, r, s, t), @(IVTI_SEM, z, r, s, t), @(INSERT_WVM_SEM, z, r, s, t), @(VLOC_EMPY_SEM, z, r, s, t), @(VLOC_HEAD_SEM, z, r, s, t), @(VLOC_TAIL_SEM, z, r, s, t), @(VLOC_CONS_SEM, z, r, s, t), @(VLOC_IN_SEM, z, r, s, t), @(VLOC_GET_SEM, z, r, s, t), @(VLOC_SET_SEM, z, r, s, t), @(VLOC_DEL_SEM, z, r, s, t)));

6.6.2

Semantics of RM-Instructions

def TMRMSEM = \(z : TMState, i : RMInstr) @(i, TMState, \(o : RMOpcode, r : Nat, d : Int, s : Nat) @(o, TMState, @(LD_SEM, z, r, d, s), @(LDA_SEM, z, r, d, s), @(LDC_SEM, z, r, d, s), @(ST_SEM, z, r, d, s), @(JLT_SEM, z, r, d, s), @(JLE_SEM, z, r, d, s), @(JGE_SEM, z, r, d, s), @(JGT_SEM, z, r, d, s), @(JEQ_SEM, z, r, d, s), @(JNE_SEM, z, r, d, s)));

170

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

6.6.3

Semantics of TM Instructions

def TMSEM = \(z : TMState, i : Instr) @(i, TMState, \(x : ROInstr) @(TMROSEM, z, x), \(y : RMInstr) @(TMRMSEM, z, y));

6.6.4

Fetch-Execution Cycle

FETCH EXEC CYCLE performs a conventional fetch-execute cycle. def FETCH_EXEC_CYCLE = \(z : TMState) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let pc = @(TMREG_RETRIEVE, rg, PC_REG) in let instr = @(IMEM_RETRIEVE, im, @(B322NAT, pc)) in let nrg = @(TMREG_ASSIGN, rg, PC_REG, @(NAT2B32, @(SS, @(B322NAT, pc)))) in let nz = @(SET_TMST_TMREG, z, nrg) in @(TMSEM, nz, instr);

6.6.5

Functions for Interruption Handling

dec IS_INT_ENABLED : [Bit32Word -> Bool]; def IS_INT_ENABLED = \(w : Bit32Word) let n = @(B322NAT, w) in @(EQUAL, n, II); dec DO_IS_INT_FIRED : [Bit32Word -> Nat -> Bool]; def DO_IS_INT_FIRED = \(w : Bit32Word, i : Nat) @(GIF_THEN_ELSE,

171

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

Bool, @(EQUAL, i, N32), FF, let b = @(GTBit32Word, w, i) in @(GIF_THEN_ELSE, Bool, b, TT, @(DO_IS_INT_FIRED, w, @(SS, i)))); def IS_INT_FIRED = \(w : Bit32Word) @(DO_IS_INT_FIRED, w, OO); dec DO_GET_1ST_FIRED : [Bit32Word -> Nat -> Nat]; def DO_GET_1ST_FIRED = \(w : Bit32Word, i : Nat) @(GIF_THEN_ELSE, Nat, @(EQUAL, i, N32), ERR_NAT, let b = @(GTBit32Word, w, i) in @(GIF_THEN_ELSE, Nat, b, i, @(DO_GET_1ST_FIRED, w, @(SS, i)))); def GET_1ST_FIRED_INT = \(w : Bit32Word) @(DO_GET_1ST_FIRED, w, OO); dec GetIntHandler : [Bit32Word -> Nat -> TMState -> TMReg]; def GetIntHandler = \(w : Bit32Word, n : Nat, z : TMState) let address = @(ADD, @(B322NAT, w), n) in let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in @(TMREG_ASSIGN, rg, PC_REG, @(NAT2B32, address));

172

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

6.6.6

Functions for Virtual Interruption Handling

dec VTINT_FIRED : [VMVTickIntCB -> Bool]; def VTINT_FIRED = \(t : VMVTickIntCB) let mask = @(GetVMVTIntCBMask, t), fire = @(GetVMVTIntCBFire, t) in @(AND, fire, @(NOT, mask)); dec VINT_LIST_FIRED : [VMVIntCBList -> Bool]; def VINT_LIST_FIRED = \(l : VMVIntCBList) @(GIF_THEN_ELSE, Bool, @(IS_EMPTY, VMVIntCB, l), FF, let hl = @(HEAD, VMVIntCB, l), tl = @(TAIL, VMVIntCB, l) in let mask = @(GetVMVIntCBMask, hl), fire = @(GetVMVIntCBFire, hl) in @(GIF_THEN_ELSE, Bool, @(AND, fire, @(NOT, mask)), TT, @(VINT_LIST_FIRED, tl))); def VINT_FIRED = \(z : TMState) let vmcb = @(VMCB_GET, z, SG_REG) in let vintcblock = @(GetVMCBVIntCBlck, vmcb) in let vtickcb = @(GetVMVIntTickCB, vintcblock), vexcpcbl = @(GetVMVIntExcpCB, vintcblock), vextrcbl = @(GetVMVIntExtrCB, vintcblock), vservcbl = @(GetVMVIntServCB, vintcblock) in @(OR, @(VTINT_FIRED, vtickcb), @(OR, @(VINT_LIST_FIRED, vexcpcbl), @(OR, @(VINT_LIST_FIRED, vextrcbl), @(VINT_LIST_FIRED, vservcbl)))); def DO_VTINTSR = \(vt : VIntType, vintcb : VMVTickIntCB, z : TMState) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), st = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in

173

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

let ie = @(TMREG_RETRIEVE, rg, IE_REG), ic = @(TMREG_RETRIEVE, rg, IC_REG), im = @(TMREG_RETRIEVE, rg, IM_REG), ih = @(TMREG_RETRIEVE, rg, IH_REG), ix = @(TMREG_RETRIEVE, rg, IS_REG), sm = @(TMREG_RETRIEVE, rg, SG_REG), md = @(TMREG_RETRIEVE, rg, MD_REG) in let hand = @(GetVMVTIntCBHand, vintcb) in let nvt = @(NAT2B32, vt), nmd = SUP_MODE, nsm = @(NAT2B32, OO), nih = @(TMREG_RETRIEVE, hand, IH_REG) in let nrg0 = @(TMREG_ASSIGN, rg, SG_REG, nsm), nrg1 = @(TMREG_ASSIGN, nrg0, VT_REG, nvt), nrg2 = @(TMREG_ASSIGN, nrg1, MD_REG, nmd), nrg3 = @(TMREG_ASSIGN, nrg2, PC_REG, nih), nrg4 = @(TMREG_ASSIGN, nrg3, VS_REG, nih) in let z1 = @(SET_TMST_TMREG, z, nrg4), z2 = @(FETCH_EXEC_CYCLE, z1), z3 = @(EXTERNAL_ENV, z2) in @(TARGET_MACHINE, z3); def DO_VINTSR = \(vt : VIntType, vintcb : VMVIntCB, z : TMState) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), st = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let ie = @(TMREG_RETRIEVE, rg, IE_REG), ic = @(TMREG_RETRIEVE, rg, IC_REG), im = @(TMREG_RETRIEVE, rg, IM_REG), ih = @(TMREG_RETRIEVE, rg, IH_REG), ix = @(TMREG_RETRIEVE, rg, IS_REG), sm = @(TMREG_RETRIEVE, rg, SG_REG), md = @(TMREG_RETRIEVE, rg, MD_REG) in let hand = @(GetVMVIntCBHand, vintcb) in let nvt = @(NAT2B32, vt), nmd = SUP_MODE, nsm = @(NAT2B32, OO), nih = @(TMREG_RETRIEVE, hand, IH_REG) in let nrg0 = @(TMREG_ASSIGN, rg, SG_REG, nsm), nrg1 = @(TMREG_ASSIGN, nrg0, VT_REG, nvt), nrg2 = @(TMREG_ASSIGN, nrg1, MD_REG, nmd), nrg3 = @(TMREG_ASSIGN, nrg2, PC_REG, nih), nrg4 = @(TMREG_ASSIGN, nrg3, VS_REG, nih) in let z1 = @(SET_TMST_TMREG, z, nrg4), z2 = @(FETCH_EXEC_CYCLE, z1), z3 = @(EXTERNAL_ENV, z2) in @(TARGET_MACHINE, z3); dec GET_VINTSR_LIST : [VMVIntCBList -> VMVIntCB];

174

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

def GET_VINTSR_LIST = \(vintcbl : VMVIntCBList) @(GIF_THEN_ELSE, VMVIntCB, @(IS_EMPTY, VMVIntCB, vintcbl), ERR_VMVINTCB, let hl = @(HEAD, VMVIntCB, vintcbl), tl = @(TAIL, VMVIntCB, vintcbl) in let mask = @(GetVMVIntCBMask, hl), fire = @(GetVMVIntCBFire, hl), hand = @(GetVMVIntCBHand, hl) in @(GIF_THEN_ELSE, VMVIntCB, @(AND, fire, @(NOT, mask)), hl, @(GET_VINTSR_LIST, tl))); dec SET_VINTSR_LIST : [VMVIntCBList -> VMVIntCBList]; def SET_VINTSR_LIST = \(vintcbl : VMVIntCBList) @(GIF_THEN_ELSE, VMVIntCBList, @(IS_EMPTY, VMVIntCB, vintcbl), vintcbl, let hl = @(HEAD, VMVIntCB, vintcbl), tl = @(TAIL, VMVIntCB, vintcbl) in let mask = @(GetVMVIntCBMask, hl), fire = @(GetVMVIntCBFire, hl), hand = @(GetVMVIntCBHand, hl) in @(GIF_THEN_ELSE, VMVIntCBList, @(AND, fire, @(NOT, mask)), let nhl = @(SetVMVIntCBFire, hl, FF) in @(CONS, VMVIntCB, nhl, tl), @(CONS, VMVIntCB, hl, @(SET_VINTSR_LIST, tl)))); dec START_VTINTSR : [VIntType -> VMVTickIntCB -> TMState -> TMState]; def START_VTINTSR = \(vt : VIntType, vtintcb : VMVTickIntCB, z : TMState) let nvtintcb = @(SetVMVTIntCBFire, vtintcb, FF) in let vmcb = @(VMCB_GET, z, SG_REG) in let vintcblock = @(GetVMCBVIntCBlck, vmcb) in let nvintcblock = @(SetVMVIntTickCB, vintcblock, nvtintcb) in let nvmcb = @(SetVMCBVIntCBlck, vmcb, nvintcblock) in let nz = @(VMCB_SET, z, SG_REG, nvmcb) in @(DO_VTINTSR, vt, vtintcb, z); dec START_VINTSR_LIST : [VIntType -> VMVIntCBList -> TMState -> TMState];

175

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

def START_VINTSR_LIST = \(vt : VIntType, vintcbl : VMVIntCBList, z : TMState) let vmvintcb = @(GET_VINTSR_LIST, vintcbl), vmvintcbl = @(SET_VINTSR_LIST, vintcbl) in let vmcb = @(VMCB_GET, z, SG_REG) in let vintcblock = @(GetVMCBVIntCBlck, vmcb) in let nvintcblock = @(GIF_THEN_ELSE, VMVIntCBlock, @(EQUAL, vt, VExcpIntType), @(SetVMVIntExcpCB, vintcblock, vmvintcbl), @(GIF_THEN_ELSE, VMVIntCBlock, @(EQUAL, vt, VExtrIntType), @(SetVMVIntExtrCB, vintcblock, vmvintcbl), @(SetVMVIntServCB, vintcblock, vmvintcbl))) in let nvmcb = @(SetVMCBVIntCBlck, vmcb, nvintcblock) in let nz = @(VMCB_SET, z, SG_REG, nvmcb) in @(DO_VINTSR, vt, vmvintcb, z); dec START_VINTSR : [TMState -> TMState]; def START_VINTSR = \(z : TMState) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), st = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let ie = @(TMREG_RETRIEVE, rg, IE_REG), ic = @(TMREG_RETRIEVE, rg, IC_REG), im = @(TMREG_RETRIEVE, rg, IM_REG), ih = @(TMREG_RETRIEVE, rg, IH_REG), ix = @(TMREG_RETRIEVE, rg, IS_REG), sm = @(TMREG_RETRIEVE, rg, SG_REG), md = @(TMREG_RETRIEVE, rg, MD_REG) in let vmcb = @(VMCB_GET, z, SG_REG) in let vintcblock = @(GetVMCBVIntCBlck, vmcb) in let vtickcb = @(GetVMVIntTickCB, vintcblock), vexcpcbl = @(GetVMVIntExcpCB, vintcblock), vextrcbl = @(GetVMVIntExtrCB, vintcblock), vservcbl = @(GetVMVIntServCB, vintcblock) in @(GIF_THEN_ELSE, TMState, @(VTINT_FIRED, vtickcb), @(START_VTINTSR, VTickIntType, vtickcb, z), @(GIF_THEN_ELSE, TMState, @(VINT_LIST_FIRED, vexcpcbl), @(START_VINTSR_LIST, VExcpIntType, vexcpcbl, z), @(GIF_THEN_ELSE, TMState, @(VINT_LIST_FIRED, vextrcbl),

176

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

177

@(START_VINTSR_LIST, VExtrIntType, vextrcbl, z), @(GIF_THEN_ELSE, TMState, @(VINT_LIST_FIRED, vservcbl), @(START_VINTSR_LIST, VExtrIntType, vservcbl, z), z))));

6.6.7

Simulation Semantics

• Handling of interruption • Handling of virtual interruption. It will be performed in interruption processing cycle. • Execution of instructions dec EXTERNAL_ENV : [TMState -> TMState]; dec TARGET_MACHINE : [TMState -> TMState]; def TARGET_MACHINE = \(z : TMState) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), st = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let ie = @(TMREG_RETRIEVE, rg, IE_REG), ic = @(TMREG_RETRIEVE, rg, IC_REG), im = @(TMREG_RETRIEVE, rg, IM_REG), ih = @(TMREG_RETRIEVE, rg, IH_REG), ix = @(TMREG_RETRIEVE, rg, IS_REG), sm = @(TMREG_RETRIEVE, rg, SG_REG), md = @(TMREG_RETRIEVE, rg, MD_REG), vt = @(TMREG_RETRIEVE, rg, VT_REG) in @(GIF_THEN_ELSE, TMState, @(IS_INT_ENABLED, ie), @(GIF_THEN_ELSE, TMState, @(IS_INT_FIRED, ic), let nz = @(GIF_THEN_ELSE, TMState, @(IS_USE_MODE, md), @(SAVE_CONTEXT, z), z) in

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

let n = @(GET_1ST_FIRED_INT, ic) in @(GIF_THEN_ELSE, TMState, @(GTBit32Word, im, n), let nic = @(STBit32Word, ic, n, FF), nie = @(GIF_THEN_ELSE, Bit32Word, @(IS_INT_FIRED, nic), ie, INT_ENABLE) in let nrg0 = rg, nrg1 = @(TMREG_ASSIGN, nrg0, IE_REG, nrg2 = @(TMREG_ASSIGN, nrg1, IC_REG, let z0 = @(SET_TMST_TMREG, nz, nrg2) in @(TARGET_MACHINE, z0), let nsm = @(NAT2B32, OO), nmd = SUP_MODE, nic = @(STBit32Word, ic, n, FF), npc = ih, nix = ih, nst = @(PUSH, TMReg, rg, st), nrg = @(GetIntHandler, ih, n, nz) in let nrg0 = @(TMREG_ASSIGN, nrg, SG_REG, nrg1 = @(TMREG_ASSIGN, nrg0, IS_REG, nrg2 = @(TMREG_ASSIGN, nrg1, MD_REG, nrg3 = @(TMREG_ASSIGN, nrg2, PC_REG, nrg4 = @(TMREG_ASSIGN, nrg3, IC_REG, let z1 = @(SET_TMST_TMREG, nz, nrg3), z2 = @(SET_TMST_TMSREG, z1, nst), z3 = @(FETCH_EXEC_CYCLE, z2), z4 = @(EXTERNAL_ENV, z3) in @(TARGET_MACHINE, z4)), @(GIF_THEN_ELSE, TMState, @(AND, @(VINT_FIRED, z), @(AND, @(NOT, @(IS_INT_SERVICED, ix)), @(NOT, @(IS_VINT_SERVICED, vt)))), let z0 = @(START_VINTSR, z), z1 = @(FETCH_EXEC_CYCLE, z0), z2 = @(EXTERNAL_ENV, z1) in @(TARGET_MACHINE, z2), let z1 = @(FETCH_EXEC_CYCLE, z), z2 = @(EXTERNAL_ENV, z1) in @(TARGET_MACHINE, z2))), let z1 = @(FETCH_EXEC_CYCLE, z),

nie), nic) in

nsm), nix), nmd), npc), nic) in

178

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

179

z2 = @(EXTERNAL_ENV, z1) in @(TARGET_MACHINE, z2));

At start-up, the Target Machine sets all registers and data memory to 0, then loads the highest legal address (namely DADDR SIZE-1) into dMem[0]. (This allows memory to be easily added to the TM, since programs can find out during execution how much memory is available.) The TM then start to execute instructions beginning at iMem[0]. The machine stops when a HALT instruction is executed by the kernel in supervisor mode.

6.6.8

Initialization

6.6.8.1

Initialization of Registers

dec DO_INIT_TMREG : [TMReg -> Nat -> TMReg]; def DO_INIT_TMREG = \(r : TMReg, i : Nat) @(GIF_THEN_ELSE, TMReg, @(NLE, i, TMREG_SIZE), let nr = @(TMREG_ASSIGN, r, i, @(NAT2B32, NIL_VMKLOC)) in @(DO_INIT_TMREG, nr, @(SS, i)), r); def INIT_TMREG = \(r : TMReg) let nrg0 = @(DO_INIT_TMREG, r, OO) in let nrg1 = @(TMREG_ASSIGN, nrg0, SG_REG, @(NAT2B32, VMK_MANAGER_IDX)), nrg2 = @(TMREG_ASSIGN, nrg1, VT_REG, @(NAT2B32, VNilIntType)), nrg3 = @(TMREG_ASSIGN, nrg2, MD_REG, SUP_MODE) in nrg3;

6.6.8.2

Initialization of Data Memory

dec INIT_DMEM : [DMemory -> Nat -> DMemory]; def INIT_DMEM = \(d : DMemory, i : Nat) @(GIF_THEN_ELSE, DMemory, @(LESS, i, DADDR_SIZE), let nd = @(DMEM_ASSIGN, d, i, @(INT2B32, IOO)) in @(INIT_DMEM, nd, @(SS, i)),

CHAPTER 6. SEMANTICS OF EXTENDED TARGET MACHINE

d);

6.6.8.3

Initialization of TM

dec DO_INIT_TM : [TMState -> Nat -> TMState]; def DO_INIT_TM = \(z : TMState, i : Nat) @(GIF_THEN_ELSE, TMState, @(LESS, i, SEGMENT_SIZE), let segset = @(GET_TMST_TMSEG, z), regs = @(GET_TMST_TMREG, z) in let segment = @(SEG_RETRIEVE, segset, i) in let dmem = @(GET_TMSG_DMEM, segment) in let haddr = @(MINUS, DADDR_SIZE, II) in let ndmem1 = @(INIT_DMEM, dmem, OO), ndmem2 = @(DMEM_ASSIGN, ndmem1, OO, @(NAT2B32, haddr)) in let nregs = @(INIT_TMREG, regs) in let nsegment = @(SET_TMSG_DMEM, segment, ndmem2) in let nz = @(SET_TMST_TMREG, z, nregs) in let nsegset = @(SEG_ASSIGN, segset, i, nsegment) in @(DO_INIT_TM, nz, @(SS, i)), z); def INIT_TARGET_MACHINE = \(z : TMState) @(DO_INIT_TM, z, OO); dec INSTALL_VMK : [TMState -> TMState]; def EXEC_TM = \(z : TMState) let nz0 = @(INIT_TARGET_MACHINE, z), nz1 = @(INSTALL_VMK, nz0), nz2 = @(SCHEDULE_VM, nz1) in @(TARGET_MACHINE, nz2);

180

Part III

The Verification

181

Chapter 7

The Separation Kernel Property 7.1

Specification of Separation Kernel

The architecture of the Separation Kernel is simple. It is a single-processor model of a distributed system in which all user processes are separated in time and space from each other. In a distributed system, the execution of each process takes place in a manner independent of any other. Processes can wait for data inputs, particularly inputs from communications channels. For the remainder of the time, the component processes execute at rates independent of all others. There is, in a distributed system, temporal separation between the execution of one process and all other processes. Separation in space means that the processes constituting a distributed system each have their own disjoint address spaces. If two address spaces are disjoint, it is not possible for one process directly to write to the address space of any other process. The Separation Kernel is based on these two fundamental observations. • Separation in time results from the fact that no two processes can be active at exactly the same time. Furthermore, if processes communicate using asynchronous channels, no synchronization points are required, so processes can proceed at their own rate. • Separation in space results from the fact that processes are allocated their own disjoint address spaces.

7.1.1

Temporal Separation

Temporal separation can be enforced by the systems scheduler and by a messagepassing system. On a uni-processor system, the scheduler ensures that only one 182

CHAPTER 7. THE SEPARATION KERNEL PROPERTY

183

process executes at any time and executions are interleaved in time. The length of time during which any process will be executing (be active) depends upon the scheduling algorithm and, as will be seen, the algorithm proposed by Rushby is particularly simple. In addition, the use of asynchronous messages means that processes do not synchronize during the exchange of messages, although they are permitted to wait for responses or results to be returned. Even in the case of waiting for a response, the waiting state depends upon the algorithms used to implement processes, not upon the underlying system.

7.1.2

Spatial Separation

Spatial separation can be enforced by segmentation. Most processors supporting segmented address spaces also have mechanisms for detecting and reacting to attempts by one process to access the segments of another. On the Intel IA32 and IA64 machines, for example, attempts to cross segment boundaries causes a hardware exception; a handler can be provided to handle the exception by, for example, killing the offending process. Each process is, therefore, allocated one or more segments. Should a process, either by error or through malice, attempt to address a location in another process segments, the hardware should cause an exception to be raised. This permits the kernel to detect such illegal accesses and to perform some action.

7.2

Formal Definition of Spatial Separation

The space partitioning can be simply defined as Space partitioning = “M emory P rotection′′ • Utilizes built-in hardware MMU to enforce execute/read/write permission • Partition’s memory protected from access by another partition • Memory violations are detected and mitigated • System calls within a partition use that partition’s memory allocation • No recursion ensures maximum kernel stack size • Resource and I/O protection

7.2.1

Well-Defined VMCB

dec VMCB_In_VMKState : [VMCB -> TMState -> Prop]; def VMCB_In_VMKState =

CHAPTER 7. THE SEPARATION KERNEL PROPERTY

\(vmcb : VMCB, z : TMState) let vmcbidx = @(GetVMCBMemoIndex, vmcb) in let spc = @(GET_TMST_TMSEG, z) in let seg = @(SEG_RETRIEVE, spc, vmcbidx) in @(Not, @(Equal, TMSegment, seg, ERR_TMSEG));

7.2.2

Well-Defined Address

dec Addr_In_VMCB : [Nat -> VMKLocation -> TMState -> VMCB -> Prop]; def Addr_In_VMCB = \(i : Nat, l : VMKLocation, z : TMState, vmcb : VMCB) let vmcb_idx = @(GetVMCBMemoIndex, vmcb) in @(And, @(Equal, Nat, i, vmcb_idx), let reg = @(GET_TMST_TMREG, z) in let nreg = @(TMREG_ASSIGN, reg, SG_REG, @(NAT2B32, i)) in let nz = @(SET_TMST_TMREG, z, nreg) in let v = @(GET, nz, l) in @(Not, @(Equal, Bit32Word, v, ErrBit32Word)));

7.2.3

Uniqness of VMKMagnager Index

def UniqVMKManIdxCond = \(z : TMState) !(vmcb : VMCB) [@(VMCB_In_VMKState, vmcb, z) -> let vmindex = @(GetVMCBMemoIndex, vmcb) in @(Not, @(Equal, Nat, vmindex, VMK_MANAGER_IDX))];

7.2.4

Uniqness of VMCB Indexes

def UniqVMCBIdxCond1 = \(z : TMState) !(vmcb1 : VMCB, vmcb2 : VMCB) [@(VMCB_In_VMKState, vmcb1, z) -> @(VMCB_In_VMKState, vmcb2, z) -> @(Not, @(Equal, VMCB, vmcb1, vmcb2)) -> let vmindex1 = @(GetVMCBMemoIndex, vmcb1), vmindex2 = @(GetVMCBMemoIndex, vmcb2) in @(Not, @(Equal, Nat, vmindex1, vmindex2))];

184

CHAPTER 7. THE SEPARATION KERNEL PROPERTY

185

def UniqVMCBIdxCond2 = \(z : TMState) !(vmcb1 : VMCB, vmcb2 : VMCB) [@(VMCB_In_VMKState, vmcb1, z) -> @(VMCB_In_VMKState, vmcb2, z) -> let vmindex1 = @(GetVMCBMemoIndex, vmcb1), vmindex2 = @(GetVMCBMemoIndex, vmcb2) in @(Not, @(Equal, Nat, vmindex1, vmindex2)) -> @(Not, @(Equal, VMCB, vmcb1, vmcb2))];

7.2.5

Space Separation Property

Definition 7.1 (Separation Kernel Condition) For a given VMK state z, for any vmcb1 of type VMCB, if vmcb1 is well-defined in z, for any address (i, l), if (i, l) is well-defined in z and vmcb1, for any vmcb2 of type VMCB, if vmcb2 is well-defined in z and (i, l) is well-defined in z and vmcb2, then vmcb1 and vmcb2 are equal. def SepKernelCond = \(z : TMState) !(vmcb1 : VMCB) [@(VMCB_In_VMKState, vmcb1, z) -> !(i : Nat, l : VMKLocation) [@(Addr_In_VMCB, i, l, z, vmcb1) -> !(vmcb2 : VMCB) [@(VMCB_In_VMKState, vmcb2, z) -> @(Addr_In_VMCB, i, l, z, vmcb2) -> @(Equal, VMCB, vmcb1, vmcb2)]]];

7.3

Formal Definition of Temporal Separation

The time partition can be simply defined as T ime partitioning = deterministic scheduling and execution • Must provide execution overrun detection • No variability in scheduler • Bounded computation time for all system calls – Prevent usage of system calls which cannot guarantee – No dynamic data structures

CHAPTER 7. THE SEPARATION KERNEL PROPERTY

186

– Memory allocation only at system startup – Prevent usage of semaphores (blocking and synchronization issues)

7.3.1

Uniqueness of Running VM

def UniqeRunningVM = \(z : TMState) !(vmcb1 : VMCB) [@(VMCB_In_VMKState, vmcb1, z) -> let status1 = @(GetVMCBStatus, vmcb1) in [@(Equal, VMStatus, status1, VMRUNNING) -> !(vmcb2 : VMCB) [@(VMCB_In_VMKState, vmcb2, z) -> let status2 = @(GetVMCBStatus, vmcb2) in [@(Equal, VMStatus, status2, VMRUNNING) -> @(Equal, VMCB, vmcb1, vmcb2)]]]]

7.4

Spatial Separation Kernel Theorem

7.4.1

The Spatial Separation Kernel Theorem

Theorem 7.1 (Separation Kernel Theorem) For any VMK state z and vmcb1 of type VMCB, if vmcb1 is well-defined in z, for any address l, if l is welldefined in z and vmcb1, for any vmcb2 of type VMCB, if vmcb2 is well-defined in z and l is well-defined in z and vmcb2, then vmcb1 and vmcb2 are equal. dec SepKernelThm : !(z : TMState) @(SepKernelCond, z);

7.4.2

The Proof of Spatial Separation Kernel Theorem

dec ExclMidRule : !(P : Prop) @(Or, P, @(Not, P)); Lemma 7.1 (Separation Kernel Lemma) For any VMK state z and vmcb1 of type VMCB, if vmcb1 is well-defined in z, for any address l, if l is well-defined in z and vmcb1, for any vmcb2 of type VMCB, if vmcb2 is well-defined in z and l is well-defined in z and vmcb2, then the segment index of vmcb1 and vmcb2, namely, vmindex1 and vmindex2 are equal.

CHAPTER 7. THE SEPARATION KERNEL PROPERTY

dec SepKernelLem : !(z : TMState) !(vmcb1 : VMCB) [@(VMCB_In_VMKState, vmcb1, z) -> !(i : Nat, l : VMKLocation) [@(Addr_In_VMCB, i, l, z, vmcb1) -> !(vmcb2 : VMCB) [@(VMCB_In_VMKState, vmcb2, z) -> @(Addr_In_VMCB, i, l, z, vmcb2) -> let vmindex1 = @(GetVMCBMemoIndex, vmcb1), vmindex2 = @(GetVMCBMemoIndex, vmcb2) in @(Equal, Nat, vmindex1, vmindex2)]]];

dec SepKernelLem : !(z : TMState) !(vmcb1 : VMCB) [@(VMCB_In_VMKState, vmcb1, z) -> !(i : Nat, l : VMKLocation) [@(Addr_In_VMCB, i, l, z, vmcb1) -> !(vmcb2 : VMCB) [@(VMCB_In_VMKState, vmcb2, z) -> @(Addr_In_VMCB, i, l, z, vmcb2) -> let vmindex1 = @(GetVMCBMemoIndex, vmcb1), vmindex2 = @(GetVMCBMemoIndex, vmcb2) in @(Equal, Nat, vmindex1, vmindex2)]]]; def SepKernelLem = \(z : TMState) \(vmcb1 : VMCB) \(p : @(VMCB_In_VMKState, vmcb1, z)) \(i : Nat, l : VMKLocation) \(q : @(Addr_In_VMCB, i, l, z, vmcb1)) \(vmcb2 : VMCB) \(q1 : @(VMCB_In_VMKState, vmcb2, z), q2 : @(Addr_In_VMCB, i, l, z, vmcb2)) let vmindex1 = @(GetVMCBMemoIndex, vmcb1), vmindex2 = @(GetVMCBMemoIndex, vmcb2) in let vmcb_idx1 = @(GetVMCBMemoIndex, vmcb1), vmcb_idx2 = @(GetVMCBMemoIndex, vmcb2) in let P11 = @(Equal, Nat, i, vmcb_idx1), P12 = let reg = @(GET_TMST_TMREG, z) in let nreg = @(TMREG_ASSIGN, reg, SG_REG, @(NAT2B32, i)) in let nz = @(SET_TMST_TMREG, z, nreg) in let v = @(GET, nz, l) in @(Not, @(Equal, Bit32Word, v, ErrBit32Word)), P21 = @(Equal, Nat, i, vmcb_idx2), P22 = let reg = @(GET_TMST_TMREG, z) in let nreg = @(TMREG_ASSIGN, reg, SG_REG, @(NAT2B32, i)) in

187

CHAPTER 7. THE SEPARATION KERNEL PROPERTY

let nz = @(SET_TMST_TMREG, z, nreg) in let v = @(GET, nz, l) in @(Not, @(Equal, Bit32Word, v, ErrBit32Word)) in let p11 = @(PJ1, P11, P12, q), p21 = @(PJ1, P21, P22, q2) in let w = @(Symm_Eq, Nat, i, vmcb_idx1, p11) in @(Tran_Eq, Nat, vmcb_idx1, i, vmcb_idx2, w, p21); def SepKernelThm = \(z : TMState) \(vmcb1 : VMCB) \(p : @(VMCB_In_VMKState, vmcb1, z)) \(i : Nat, l : VMKLocation) \(q : @(Addr_In_VMCB, i, l, z, vmcb1)) \(vmcb2 : VMCB) \(q1 : @(VMCB_In_VMKState, vmcb2, z), q2 : @(Addr_In_VMCB, i, l, z, vmcb2)) let P = @(Equal, VMCB, vmcb1, vmcb2) in let w = @(ExclMidRule, P) in @(WHEN, P, @(Not, P), P, w, \(u : P) u, \(u : @(Not, P)) let v1 = @(UniqVMCBIdxThm1, z, vmcb1, vmcb2, p, q1, u), v2 = @(SepKernelLem, z, vmcb1, p, i, l, q, vmcb2, q1, q2) in @(v1, v2, P));

188

Chapter 8

The Memory Separation Property 8.1 8.1.1

Specification of Memory Partitioning Instructions Well-Defined in Instruction Memory

dec Instr_In_IMemory : [Instr -> IMemory -> Type(0)]; def Instr_In_IMemory = \(i : Instr, imem : IMemory) ?(idx : Nat) @(And, @(NLe, idx, IADDR_SIZE), let ni = @(IMEM_RETRIEVE, imem, idx) in @(Equal, Instr, i, ni));

8.1.2

Memory Partitioning

def MemoryPartCond1 = \(z : TMState) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let mode = @(TMREG_RETRIEVE, rg, MD_REG) in [!(i : Instr) [@(Instr_In_IMemory, i, im) ->

189

CHAPTER 8. THE MEMORY SEPARATION PROPERTY

?(d : Int, s : Nat) @(Or, @(Equal, Instr, i, @(MK_TMRM, @(MK_RMINST, LD, SG_REG, d, s))), @(Or, @(Equal, Instr, i, @(MK_TMRM, @(MK_RMINST, LDA, SG_REG, d, s))), @(Equal, Instr, i, @(MK_TMRM, @(MK_RMINST, LDC, SG_REG, d, s)))))] -> @(Equal, Bit32Word, mode, SUP_MODE)]; def MemoryPartCond2 = \(z : TMState) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let mode = @(TMREG_RETRIEVE, rg, MD_REG) in [@(Neg, @(Equal, Bit32Word, mode, SUP_MODE)) -> !(i : Instr) [@(Instr_In_IMemory, i, im) -> @(Neg0, ?(d : Int, s : Nat) @(Or, @(Equal, Instr, i, @(MK_TMRM, @(MK_RMINST, LD, SG_REG, d, s))), @(Or, @(Equal, Instr, i, @(MK_TMRM, @(MK_RMINST, LDA, SG_REG, d, s))), @(Equal, Instr, i, @(MK_TMRM, @(MK_RMINST, LDC, SG_REG, d, s))))))]]; def MemoryPartCond = \(z : TMState) @(And1, @(MemoryPartCond1, z), @(MemoryPartCond2, z));

8.1.3

Specification of Safe Memory

def MemorySafeCond = \(z : TMState) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let mod = @(TMREG_RETRIEVE, rg, MD_REG), idx = @(B322NAT, @(TMREG_RETRIEVE, rg, SG_REG)), pc = @(B322NAT, @(TMREG_RETRIEVE, rg, PC_REG)) in let instr = @(IMEM_RETRIEVE, im, pc) in [@(Neg, @(Equal, Bit32Word, mod, SUP_MODE)) -> let nz = @(TMSEM, z, instr) in [@(Neg, @(Equal, TMState, nz, @(ERR_TMSTATE, z))) -> let nim = @(GET_TMST_IMEM, nz), ndm = @(GET_TMST_DMEM, nz), nrg = @(GET_TMST_TMREG, nz),

190

CHAPTER 8. THE MEMORY SEPARATION PROPERTY

191

nsg = @(GET_TMST_TMSREG, nz), nio = @(GET_TMST_TMVECT, nz) in let nidx = @(B322NAT, @(TMREG_RETRIEVE, nrg, SG_REG)) in @(Equal, Nat, idx, nidx)]];

8.2

Memory Safe Theorem

8.2.1

The Safe Kernel Theorem

dec SafeKernelThm : !(z : TMState) [@(MemoryPartCond, z) -> @(MemorySafeCond, z)];

8.2.2

The Proof of Safe Kernel Theorem

dec SGRegInstrLem : !(z : TMState) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let mod = @(TMREG_RETRIEVE, rg, MD_REG), idx = @(B322NAT, @(TMREG_RETRIEVE, rg, SG_REG)), pc = @(B322NAT, @(TMREG_RETRIEVE, rg, PC_REG)) in let ins = @(IMEM_RETRIEVE, im, pc) in [@(Neg, @(Equal, Bit32Word, mod, SUP_MODE)) -> let nz = @(TMSEM, z, ins) in [@(Neg, @(Equal, TMState, nz, @(ERR_TMSTATE, z))) -> let nim = @(GET_TMST_IMEM, nz), ndm = @(GET_TMST_DMEM, nz), nrg = @(GET_TMST_TMREG, nz), nsg = @(GET_TMST_TMSREG, nz), nio = @(GET_TMST_TMVECT, nz) in let nidx = @(B322NAT, @(TMREG_RETRIEVE, nrg, SG_REG)) in [@(Neg, @(Equal, Nat, idx, nidx)) -> ?(d : Int, s : Nat) @(Or, @(Equal, Instr, ins, @(MK_TMRM, @(MK_RMINST, LD, SG_REG, d, s))), @(Or, @(Equal, Instr, ins, @(MK_TMRM, @(MK_RMINST, LDA, SG_REG, d, s))), @(Equal, Instr, ins, @(MK_TMRM, @(MK_RMINST, LDC, SG_REG, d, s)))))]]]; dec PCRegInstrLem : !(z : TMState) let im = @(GET_TMST_IMEM,

z),

CHAPTER 8. THE MEMORY SEPARATION PROPERTY

dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let pc = @(B322NAT, @(TMREG_RETRIEVE, rg, PC_REG)) in let instr = @(IMEM_RETRIEVE, im, pc) in @(Instr_In_IMemory, instr, im); def SafeKernelThm = \(z : TMState) \(p : @(MemoryPartCond, z)) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let mod = @(TMREG_RETRIEVE, rg, MD_REG), idx = @(B322NAT, @(TMREG_RETRIEVE, rg, SG_REG)), pc = @(B322NAT, @(TMREG_RETRIEVE, rg, PC_REG)) in let instr = @(IMEM_RETRIEVE, im, pc) in \(q1 : @(Neg, @(Equal, Bit32Word, mod, SUP_MODE))) let nz = @(TMSEM, z, instr) in \(q2 : @(Neg, @(Equal, TMState, nz, @(ERR_TMSTATE, z)))) let nim = @(GET_TMST_IMEM, nz), ndm = @(GET_TMST_DMEM, nz), nrg = @(GET_TMST_TMREG, nz), nsg = @(GET_TMST_TMSREG, nz), nio = @(GET_TMST_TMVECT, nz) in let nidx = @(B322NAT, @(TMREG_RETRIEVE, nrg, SG_REG)) in let P1 = @(MemoryPartCond1, z), P2 = @(MemoryPartCond2, z) in let p1 = @(PJ11, P1, P2, p), p2 = @(PJ12, P1, P2, p) in let P = @(Equal, Nat, idx, nidx) in let w = @(ExclMidRule, P) in @(WHEN, P, @(Not, P), P, w, \(u : P) u, \(u : @(Not, P)) let v1 = @(SGRegInstrLem, z, q1, q2, u), v2 = @(PCRegInstrLem, z) in @(p2, q1, instr, v2, v1, P));

192

Chapter 9

The Safe ISR Property 9.1

The Specification Safe ISR Property

dec Is_In_Var_List : [VMKLocation -> @(List, VMKLocation) -> Prop]; dec AddrInInstrCode : [TMState -> VMKLocation -> VMKLocation -> Prop]; dec DoAddrInInstr : [IMemory -> TMReg -> VMKLocation -> VMKLocation -> Prop]; def DoAddrInInstr = \(im : IMemory, rg : TMReg, h : VMKLocation, l : VMKLocation) let instr = @(IMEM_RETRIEVE, im, h) in @(GIF_THEN_ELSE0, Prop, @(IS_NIL_INSTR, instr), Null, @(GIF_THEN_ELSE0, Prop, @(IS_TMRO, instr), @(DoAddrInInstr, im, rg, @(SS, h), l), @(GIF_THEN_ELSE0, Prop, @(IS_TMRM, instr), let rminstr = @(GET_TMRM, instr) in let op = @(GET_RMINST_OP, rminstr), r = @(GET_RMINST_R, rminstr), d = @(GET_RMINST_D, rminstr), s = @(GET_RMINST_S, rminstr) in let sval = @(TMREG_RETRIEVE, rg, s), aval = @(INT2NAT, @(IADD, d, @(B322INT, sval))) in @(GIF_THEN_ELSE0, Prop, @(OR, @(OR, @(IS_LD, op), @(IS_LDA, op)), @(IS_ST, op)),

193

CHAPTER 9. THE SAFE ISR PROPERTY

@(GIF_THEN_ELSE0, Prop, @(EQUAL, aval, l), True, @(DoAddrInInstr, im, rg, @(SS, h), l)), @(DoAddrInInstr, im, rg, @(SS, h), l)), @(DoAddrInInstr, im, rg, @(SS, h), l)))); def AddrInInstrCode = \(z : TMState, h : VMKLocation, l : VMKLocation) let spc = @(GET_TMST_TMSEG, z) in let seg = @(SEG_RETRIEVE, spc, VMK_MANAGER_IDX) in let im = @(GET_TMSG_IMEM, seg), rg = @(GET_TMST_TMREG, z) in @(DoAddrInInstr, im, rg, h, l); dec InFlowList : [@(List, VMKLocation) -> VMKLocation -> VMKLocation -> TMState -> Prop]; def InFlowList = \(l : @(List, VMKLocation), h : VMKLocation, a : VMKLocation, z : TMState) @(GIF_THEN_ELSE0, Prop, @(IS_EMPTY, VMKLocation, l), Null, let hl = @(HEAD, VMKLocation, l), tl = @(TAIL, VMKLocation, l) in let dm = @(GET_TMST_DMEM, z) in let subject = @(B322NAT, @(DMEM_RETRIEVE, dm, hl)), resource = @(B322NAT, @(DMEM_RETRIEVE, dm, @(SS, hl))), mode = @(B322NAT, @(DMEM_RETRIEVE, dm, @(SS, @(SS, hl)))) in @(GIF_THEN_ELSE0, Prop, @(AND, @(EQUAL, h, subject), @(EQUAL, a, resource)), True, @(InFlowList, tl, h, a, z))); def SafeISRCond1 = \(z : TMState) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let ie = @(TMREG_RETRIEVE, rg, IE_REG), ic = @(TMREG_RETRIEVE, rg, IC_REG), im = @(TMREG_RETRIEVE, rg, IM_REG), ih = @(TMREG_RETRIEVE, rg, IH_REG), ix = @(TMREG_RETRIEVE, rg, IS_REG), sm = @(TMREG_RETRIEVE, rg, SG_REG) in !(instr : Instr) [@(Equal, Bool, @(IS_TMRM, instr), TT) ->

194

CHAPTER 9. THE SAFE ISR PROPERTY

let rminstr = @(GET_TMRM, instr) in let op = @(GET_RMINST_OP, rminstr), r = @(GET_RMINST_R, rminstr), d = @(GET_RMINST_D, rminstr), s = @(GET_RMINST_S, rminstr) in [@(Or, @(Equal, RMOpcode, op, LD), @(Or, @(Equal, RMOpcode, op, LDA), @(Equal, RMOpcode, op, ST))) -> let sval = @(TMREG_RETRIEVE, rg, s), aval = @(INT2NAT, @(IADD, d, @(B322INT, sval))) in ?(idx : Nat) @(And, @(Neg, @(Equal, Nat, idx, VMK_MANAGER_IDX)), let vmcb = @(VMCB_GET, z, idx), vmk_manager = @(GET_TMST_VMKMAN, z) in let exp_var_list = @(GetVMCBExportVar, vmcb), flow_list = @(GET_VMKMAN_FLOWLT, vmk_manager) in let P1 = @(Is_In_Var_List, aval, exp_var_list), P2 = !(p : ?(n : Nat) let isr_addr = @(ADD, @(B322NAT, ih), n) in @(AddrInInstrCode, z, isr_addr, aval)) let n = @(FST, p) in let isr_addr = @(ADD, @(B322NAT, ih), n) in @(InFlowList, flow_list, isr_addr, aval, z) in [P1 -> P2])]]; def SafeISRCond2 = \(z : TMState) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let ie = @(TMREG_RETRIEVE, rg, IE_REG), ic = @(TMREG_RETRIEVE, rg, IC_REG), im = @(TMREG_RETRIEVE, rg, IM_REG), ih = @(TMREG_RETRIEVE, rg, IH_REG), ix = @(TMREG_RETRIEVE, rg, IS_REG), sm = @(TMREG_RETRIEVE, rg, SG_REG) in !(instr : Instr) [@(Equal, Bool, @(IS_TMRM, instr), TT) -> let rminstr = @(GET_TMRM, instr) in let op = @(GET_RMINST_OP, rminstr), r = @(GET_RMINST_R, rminstr), d = @(GET_RMINST_D, rminstr), s = @(GET_RMINST_S, rminstr) in [@(Or, @(Equal, RMOpcode, op, LD), @(Or, @(Equal, RMOpcode, op, LDA),

195

CHAPTER 9. THE SAFE ISR PROPERTY

@(Equal, RMOpcode, op, ST))) -> let sval = @(TMREG_RETRIEVE, rg, s), aval = @(INT2NAT, @(IADD, d, @(B322INT, sval))) in ?(idx : Nat) @(And, @(Neg, @(Equal, Nat, idx, VMK_MANAGER_IDX)), let vmcb = @(VMCB_GET, z, idx), vmk_manager = @(GET_TMST_VMKMAN, z) in let exp_var_list = @(GetVMCBExportVar, vmcb), flow_list = @(GET_VMKMAN_FLOWLT, vmk_manager) in let P1 = @(Is_In_Var_List, aval, exp_var_list), P2 = !(p : ?(n : Nat) let isr_addr = @(ADD, @(B322NAT, ih), n) in @(AddrInInstrCode, z, isr_addr, aval)) let n = @(FST, p) in let isr_addr = @(ADD, @(B322NAT, ih), n) in @(InFlowList, flow_list, isr_addr, aval, z) in [P2 -> P1])]]; def SafeISRCond = \(z : TMState) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let ie = @(TMREG_RETRIEVE, rg, IE_REG), ic = @(TMREG_RETRIEVE, rg, IC_REG), im = @(TMREG_RETRIEVE, rg, IM_REG), ih = @(TMREG_RETRIEVE, rg, IH_REG), ix = @(TMREG_RETRIEVE, rg, IS_REG), sm = @(TMREG_RETRIEVE, rg, SG_REG) in !(instr : Instr) [@(Equal, Bool, @(IS_TMRM, instr), TT) -> let rminstr = @(GET_TMRM, instr) in let op = @(GET_RMINST_OP, rminstr), r = @(GET_RMINST_R, rminstr), d = @(GET_RMINST_D, rminstr), s = @(GET_RMINST_S, rminstr) in [@(Or, @(Equal, RMOpcode, op, LD), @(Or, @(Equal, RMOpcode, op, LDA), @(Equal, RMOpcode, op, ST))) -> let sval = @(TMREG_RETRIEVE, rg, s), aval = @(INT2NAT, @(IADD, d, @(B322INT, sval))) in ?(idx : Nat) @(And, @(Neg, @(Equal, Nat, idx, VMK_MANAGER_IDX)), let vmcb = @(VMCB_GET, z, idx), vmk_manager = @(GET_TMST_VMKMAN, z) in let exp_var_list = @(GetVMCBExportVar, vmcb),

196

CHAPTER 9. THE SAFE ISR PROPERTY

flow_list = @(GET_VMKMAN_FLOWLT, vmk_manager) in let P1 = @(Is_In_Var_List, aval, exp_var_list), P2 = !(p : ?(n : Nat) let isr_addr = @(ADD, @(B322NAT, ih), n) in @(AddrInInstrCode, z, isr_addr, aval)) let n = @(FST, p) in let isr_addr = @(ADD, @(B322NAT, ih), n) in @(InFlowList, flow_list, isr_addr, aval, z) in @(And, P1, P2))]];

9.2 9.2.1

Safe ISR Theorem The Safe ISR Theorem

dec SafeISRThm : !(z : TMState) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let pc = @(TMREG_RETRIEVE, rg, PC_REG), ie = @(TMREG_RETRIEVE, rg, IE_REG), ic = @(TMREG_RETRIEVE, rg, IC_REG), md = @(TMREG_RETRIEVE, rg, IM_REG), ih = @(TMREG_RETRIEVE, rg, IH_REG), ix = @(TMREG_RETRIEVE, rg, IS_REG), sm = @(TMREG_RETRIEVE, rg, SG_REG) in [@(SafeISRCond, z) -> let instr = @(IMEM_RETRIEVE, im, @(B322NAT, pc)) in [@(Equal, Bool, @(IS_TMRM, instr), TT) -> let rminstr = @(GET_TMRM, instr) in let op = @(GET_RMINST_OP, rminstr), r = @(GET_RMINST_R, rminstr), d = @(GET_RMINST_D, rminstr), s = @(GET_RMINST_S, rminstr) in [@(Or, @(Equal, RMOpcode, op, LD), @(Or, @(Equal, RMOpcode, op, LDA), @(Equal, RMOpcode, op, ST))) -> let sval = @(TMREG_RETRIEVE, rg, s), aval = @(INT2NAT, @(IADD, d, @(B322INT, sval))) in ?(idx : Nat) @(And, @(Neg, @(Equal, Nat, idx, VMK_MANAGER_IDX)), let vmcb = @(VMCB_GET, z, idx), vmk_manager = @(GET_TMST_VMKMAN, z) in let exp_var_list = @(GetVMCBExportVar, vmcb),

197

CHAPTER 9. THE SAFE ISR PROPERTY

flow_list = @(GET_VMKMAN_FLOWLT, vmk_manager) in let P1 = @(Is_In_Var_List, aval, exp_var_list), P2 = !(p : ?(n : Nat) let isr_addr = @(ADD, @(B322NAT, ih), n) in @(AddrInInstrCode, z, isr_addr, aval)) let n = @(FST, p) in let isr_addr = @(ADD, @(B322NAT, ih), n) in @(InFlowList, flow_list, isr_addr, aval, z) in @(And, P1, P2))]]];

9.2.2

The Proof of Safe ISR Theorem

def SafeISRThm = \(z : TMState) let im = @(GET_TMST_IMEM, z), dm = @(GET_TMST_DMEM, z), rg = @(GET_TMST_TMREG, z), sg = @(GET_TMST_TMSREG, z), io = @(GET_TMST_TMVECT, z) in let pc = @(TMREG_RETRIEVE, rg, PC_REG), ie = @(TMREG_RETRIEVE, rg, IE_REG), ic = @(TMREG_RETRIEVE, rg, IC_REG), md = @(TMREG_RETRIEVE, rg, IM_REG), ih = @(TMREG_RETRIEVE, rg, IH_REG), ix = @(TMREG_RETRIEVE, rg, IS_REG), sm = @(TMREG_RETRIEVE, rg, SG_REG) in \(p : @(SafeISRCond, z)) let instr = @(IMEM_RETRIEVE, im, @(B322NAT, pc)) in \(q1 : @(Equal, Bool, @(IS_TMRM, instr), TT)) let rminstr = @(GET_TMRM, instr) in let op = @(GET_RMINST_OP, rminstr), r = @(GET_RMINST_R, rminstr), d = @(GET_RMINST_D, rminstr), s = @(GET_RMINST_S, rminstr) in \(q2 : @(Or, @(Equal, RMOpcode, op, LD), @(Or, @(Equal, RMOpcode, op, LDA), @(Equal, RMOpcode, op, ST)))) let sval = @(TMREG_RETRIEVE, rg, s), aval = @(INT2NAT, @(IADD, d, @(B322INT, sval))) in @(p, instr, q1, q2);

198

Chapter 10

Formal Deterministic Analysis of SVMK 10.1

What is Deterministic RTOSes?

10.1.1

The Definition of Deterministics

RTOS stands for real-time operating system, versus the general-computing operating system (OS). The key difference between general-computing operating systems and realtime operating systems is the need for “deterministic” timing behavior in the real-time operating systems. Formally, “deterministic” timing means that operating system services consume only known and expected amounts of time. In theory, these service times could be expressed as mathematical formulas. These formulas must be strictly algebraic and not include any random timing components. Random elements in service times could cause random delays in application software and could then make the application randomly miss real-time deadlines C a scenario clearly unacceptable for a real-time embedded system. Many non-real-time operating systems also provide similar kernel services.

10.1.2

The Deterministic Requirement for RTOSes

General-computing non-real-time operating systems are often quite non-deterministic. Their services can inject random delays into application software and thus cause slow responsiveness of an application at unexpected times. If you ask the developer of a non-real-time operating system for the algebraic formula describing the timing behavior of one of its services (such as sending a message from task to task), you will invariably not get an algebraic formula. Instead the developer of the non-real-time operating system (such as Windows, Unix

199

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

200

or Linux) will just give you a puzzled look. Deterministic timing behavior was simply not a design goal for these general-computing operating systems. On the other hand, real-time operating systems often go a step beyond basic determinism. For most kernel services, these operating systems offer constant load-independent timing: In other words, the algebraic formula is as simple as: T(message send) = constant, irrespective of the length of the message to be sent, or other factors such as the numbers of tasks and queues and messages being managed by the RTOS. Many RTOS proponents argue that a real-time operating system must not use virtual memory concepts, because paging mechanics prevent a deterministic response. While this is a frequently supported argument, it should be noted that the term “real-time operating system” and determinism in this context covers a very wide meaning, and vendors of many different operating systems apply these terms with varied meaning. When selecting an operating system for a specific task, the real-time attribute alone is an insufficient criterion, therefore. Deterministic behavior and deterministic latencies have value only if the response lies within the boundaries of the physics of the process that is to be controlled. Real-time operating systems are often uses in embedded solutions, that is, computing platforms that are within another device. Examples for embedded systems include combustion engine controllers or washing machine controllers and many others. Desktop PC and other general-purpose computers are not embedded systems. While real-time operating systems are typically designed for and used with embedded systems, the two aspects are essentially distinct, and have different requirements. A real-time operating system for embedded system addresses both sets of requirements.

10.1.3

Deterministics and Termination Condition

The deterministics of computing function also means that it is terminated. We then will be able to obtain a by-product when achieving the proof of deterministic property for a computation function. However the condition of deterministic is rather stronger than what has been required for termination condition. The termination condition does not mean that the computation is bounded by a constant. Therefore if we can prove that each instruction of VMK is deterministic then it means that all the instruction are terminated.

10.2

Functions for Time-Complexity Calculation

We assume that for each function there is a function for measuring the computational complexity for a given type of function. For instance we have TIME CAL

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

201

for [TMState -> TMState], any state transition functions. Other measurement functions include [TMState -> Bool], [TMState -> Nat] and so on. We will not give the definitions of these functions explicitly, the functions will be defined implicitly instead. dec dec dec dec dec dec dec

TIME_CAL BOOL_TIME_CAL NAT_TIME_CAL TMREG_TIME_CAL TMREG2_TIME_CAL TMVMKMAN_TIME_CAL STMVMKMAN_TIME_CAL

: : : : : : :

[[TMState [[TMState [[TMState [[TMState [[TMState [[TMState [[TMState

-> -> -> -> -> -> ->

TMState] Bool] VMKLocation] TMReg] TMReg -> TMState] VMKManager] VMKManager -> TMState]

-> -> -> -> -> -> ->

Nat]; Nat]; Nat]; Nat]; Nat]; Nat]; Nat];

dec B2B_TIME_CAL : [[Bool -> Bool] -> Nat]; dec N2N_TIME_CAL : [[VMKLocation -> VMKLocation] -> Nat]; dec NAT2_TIME_CAL : [[VMKLocation -> VMKLocation -> VMKLocation] -> Nat]; dec NATEQ_TIME_CAL : [[VMKLocation -> VMKLocation -> Bool] -> Nat]; dec BTMREG_TIME_CAL : [[TMReg -> Bool] -> Nat]; dec TMREG2BW_TIME_CAL : [[TMReg -> Bit32Word] -> Nat]; dec TMREG2TMREG_TCAL : [[TMReg -> TMReg] -> Nat]; dec BW2BOOL_TIME_CAL : [[Bit32Word -> Bool] -> Nat]; dec GET_VMCB_TIME_CAL : [[VMKLocation -> TMState -> VMCB] -> Nat]; dec SET_VMCB_TIME_CAL : [[VMKLocation -> VMCB -> TMState -> TMState] -> Nat]; dec VMKMAN_LOC_TIME_CAL : [[VMKManager -> VMKLocation] -> Nat]; dec SVMKMAN_LOC_TIME_CAL : [[VMKManager -> VMKLocation -> VMKManager] -> Nat]; dec dec dec dec dec

VMCB_TIME_CAL VMCB2BITWORD_TCAL GVMCBMMIDX_TCAL GVMCBINTCX_TCAL SVMCBINTCX_TCAL

: : : : :

[[VMCB [[VMCB [[VMCB [[VMCB [[VMCB

-> -> -> -> ->

VMCB] Bit32Word] Nat] TMReg] TMReg -> VMCB]

-> -> -> -> ->

Nat]; Nat]; Nat]; Nat]; Nat];

10.3

Definitions of Deterministics

10.3.1

Definitions of Deterministics for Functions on TMState

The definition of deterministics of a state transition function f is simply given as follows: @(TIME CAL, f) ≤ C def FunTimeDet = \(f : [TMState -> TMState])

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

202

\(C : Nat) @(NLe, @(TIME_CAL, f), C); def BoolFunTimeDet = \(f : [TMState -> Bool]) \(C : Nat) @(NLe, @(BOOL_TIME_CAL, f), C); def NatFunTimeDet = \(f : [TMState -> VMKLocation]) \(C : Nat) @(NLe, @(NAT_TIME_CAL, f), C); def TMRegFunTimeDet = \(f : [TMState -> TMReg]) \(C : Nat) @(NLe, @(TMREG_TIME_CAL, f), C); def TMReg2FunTimeDet = \(f : [TMState -> TMReg -> TMState]) \(C : Nat) @(NLe, @(TMREG2_TIME_CAL, f), C); def TMVMKManTDet = \(f : [TMState -> VMKManager]) \(C : Nat) @(NLe, @(TMVMKMAN_TIME_CAL, f), C); def STMVMKManTDet = \(f : [TMState -> VMKManager -> TMState]) \(C : Nat) @(NLe, @(STMVMKMAN_TIME_CAL, f), C);

10.3.2

Definitions of Deterministics for Functions on Bool and Nat

def B2BFunTimeDet = \(f : [Bool -> Bool]) \(C : Nat) @(NLe, @(B2B_TIME_CAL, f), C); def N2NFunTimeDet = \(f : [VMKLocation -> VMKLocation]) \(C : Nat) @(NLe, @(N2N_TIME_CAL, f), C); def Nat2FunTimeDet = \(f : [VMKLocation -> VMKLocation -> VMKLocation])

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

203

\(C : Nat) @(NLe, @(NAT2_TIME_CAL, f), C); def NatEqFunTimeDet = \(f : [VMKLocation -> VMKLocation -> Bool]) \(C : Nat) @(NLe, @(NATEQ_TIME_CAL, f), C); def BW2BoolTimeDet = \(f : [Bit32Word -> Bool]) \(C : Nat) @(NLe, @(BW2BOOL_TIME_CAL, f), C);

10.3.3

Definitions of Deterministics for Functions on TMReg

def BTMRegFunTimeDet = \(f : [TMReg -> Bool]) \(C : Nat) @(NLe, @(BTMREG_TIME_CAL, f), C); def TMReg2BWTDet = \(f : [TMReg -> Bit32Word]) \(C : Nat) @(NLe, @(TMREG2BW_TIME_CAL, f), C); def TMReg2TMRegTDet = \(f : [TMReg -> TMReg]) \(C : Nat) @(NLe, @(TMREG2TMREG_TCAL, f), C);

10.3.4

Definitions of Deterministics for Functions on VMCB

def GtVMCBStTimeDet = \(f : [VMCB -> VMStatus]) \(C : Nat) @(NLe, @(VMCB2BITWORD_TCAL, f), C); def SetVMCBFTDet = \(f : [VMCB -> VMCB]) \(C : Nat) @(NLe, @(VMCB_TIME_CAL, f), C); def VMCBGetTDet =

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

\(f : [VMKLocation -> TMState -> VMCB]) \(C : Nat) @(NLe, @(GET_VMCB_TIME_CAL, f), C); def VMCBSetTDet = \(f : [VMKLocation -> VMCB -> TMState -> TMState]) \(C : Nat) @(NLe, @(SET_VMCB_TIME_CAL, f), C); def VMKManLocTDet = \(f : [VMKManager -> VMKLocation]) \(C : Nat) @(NLe, @(VMKMAN_LOC_TIME_CAL, f), C); def SVMKManLocTDet = \(f : [VMKManager -> VMKLocation -> VMKManager]) \(C : Nat) @(NLe, @(SVMKMAN_LOC_TIME_CAL, f), C); def GetVMCBMmIdxDet = \(f : [VMCB -> Nat]) \(C : Nat) @(NLe, @(GVMCBMMIDX_TCAL, f), C); def GetVMCBIntCxDet = \(f : [VMCB -> TMReg]) \(C : Nat) @(NLe, @(GVMCBINTCX_TCAL, f), C); def SetVMCBIntCxDet = \(f : [VMCB -> TMReg -> VMCB]) \(C : Nat) @(NLe, @(SVMCBINTCX_TCAL, f), C);

10.3.5

Deterministics of Instructions

def TimeDet = \(i : Instr) \(C : Nat) let f = \(z : TMState) @(TMSEM, z, i) in @(FunTimeDet, f, C);

204

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

10.4

Deterministic Conditions

10.4.1

Deterministic Condition for Instructions

205

The time-deterministic condition for any instructions i of TM-2 ∃C @(TimeDet, i, C) def TimeDetCond = \(i : Instr) ?(C : Nat) @(TimeDet, i, C);

10.4.2

Deterministic Condition for State Transition Functions

We then will have the time-deterministic condition for any state transition function f ∃C @(FunTimeDet, f, C) def FunTimeDetCond = \(f : [TMState -> TMState]) ?(C : Nat) @(FunTimeDet, f, C); def BFunTimeDetCond = \(f : [TMState -> Bool]) ?(C : Nat) @(BoolFunTimeDet, f, C); def NFunTimeDetCond = \(f : [TMState -> VMKLocation]) ?(C : Nat) @(NatFunTimeDet, f, C); def TMRegFunTDetCond = \(f : [TMState -> TMReg]) ?(C : Nat) @(TMRegFunTimeDet, f, C); def TMReg2FunTDetCond = \(f : [TMState -> TMReg -> TMState]) ?(C : Nat) @(TMReg2FunTimeDet, f, C); def TMVMKManTDetCond = \(f : [TMState -> VMKManager]) ?(C : Nat)

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

@(TMVMKManTDet, f, C); def STMVMKManTDetCond = \(f : [TMState -> VMKManager -> TMState]) ?(C : Nat) @(STMVMKManTDet, f, C); def VMCBSetTDetCond = \(f : [VMKLocation -> VMCB -> TMState -> TMState]) ?(C : Nat) @(VMCBSetTDet, f, C);

10.4.3

Deterministic Condition for Bool, Nat and TMReg

def B2BTimeDetCond = \(f : [Bool -> Bool]) ?(C : Nat) @(B2BFunTimeDet, f, C); def N2NFunTimeDetCond = \(f : [VMKLocation -> VMKLocation]) ?(C : Nat) @(N2NFunTimeDet, f, C); def N2FunTimeDetCond = \(f : [VMKLocation -> VMKLocation -> VMKLocation]) ?(C : Nat) @(Nat2FunTimeDet, f, C); def NEqFunTDetCond = \(f : [VMKLocation -> VMKLocation -> Bool]) ?(C : Nat) @(NatEqFunTimeDet, f, C); def BTMRegFunTDetCond = \(f : [TMReg -> Bool]) ?(C : Nat) @(BTMRegFunTimeDet, f, C); def TMReg2BWCond = \(f : [TMReg -> Bit32Word]) ?(C : Nat) @(TMReg2BWTDet, f, C); def TMReg2TMRegCond = \(f : [TMReg -> TMReg]) ?(C : Nat) @(TMReg2TMRegTDet, f, C); def BW2BoolCond =

206

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

\(f : [Bit32Word -> Bool]) ?(C : Nat) @(BW2BoolTimeDet, f, C);

10.4.4

Deterministic Conditions for VMKManager

def VMKMLocTDetCond = \(f : [VMKManager -> VMKLocation]) ?(C : Nat) @(VMKManLocTDet, f, C); def SVMKMLocTDetCond = \(f : [VMKManager -> VMKLocation -> VMKManager]) ?(C : Nat) @(SVMKManLocTDet, f, C);

10.4.5

Deterministic Conditions for VMCB

def GtVMCBStTDetCond = \(f : [VMCB -> VMStatus]) ?(C : Nat) @(GtVMCBStTimeDet, f, C); def SetVMCBFTDetCond = \(f : [VMCB -> VMCB]) ?(C : Nat) @(SetVMCBFTDet, f, C); def VMCBGetTDetCond = \(f : [VMKLocation -> TMState -> VMCB]) ?(C : Nat) @(VMCBGetTDet, f, C); def GetVMCBMmIdxCond = \(f : [VMCB -> Nat]) ?(C : Nat) @(GetVMCBMmIdxDet, f, C); def GetVMCBIntCxCond = \(f : [VMCB -> TMReg]) ?(C : Nat) @(GetVMCBIntCxDet, f, C); def SetVMCBIntCxCond = \(f : [VMCB -> TMReg -> VMCB]) ?(C : Nat)

207

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

208

@(SetVMCBIntCxDet, f, C);

10.5

The Time-Deterministic Theorems

We want to prove the following main theorems. Theorem 10.1 (Time-Deterministic Theorem) For every instruction i there exists a constant C such that @(TimeDet, i, C). dec TimeDetThm : !(i : Instr) ?(C : Nat) @(TimeDet, i, C);

We may have the following rather stronger theorem. Theorem 10.2 (Time-Deterministic Theorem 2) There exists a constant C such that for every instruction i @(TimeDet, i, C). dec TimeDetThm2 : ?(C : Nat) !(i : Instr) @(TimeDet, i, C);

In the first theorem the constant C is dependent on a given instruction i and in the second one there exists a constant C without depending on any instructions.

10.6

The Proofs of Time-Deterministic Theorems

To achieve the proofs of TimeDetThm and TimeDetThm2 we need to prove the time-deterministic theorems for RO-instructions and RM-instructions.

10.6.1

Time-Deterministic Theorems for RO-Instructions

Theorem 10.3 (RO-Instruction Time-Deterministic Theorem) For every RO-instruction i there exists a constant C such that @(TimeDet, @(MK TMRO, i), C).

dec ROTimeDetThm : !(i : ROInstr)

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

209

?(C : Nat) @(TimeDet, @(MK_TMRO, i), C);

Theorem 10.4 (RO-Instruction Time-Deterministic Theorem 2) There is a constant C such that for every RO-instruction i @(TimeDet, @(MK TMRO, i), C).

dec ROTimeDetThm2 : ?(C : Nat) !(i : ROInstr) @(TimeDet, @(MK_TMRO, i), C);

10.6.2

Time-Deterministic Theorems for RM-Instructions

Theorem 10.5 (RM-Instruction Time-Deterministic Theorem) For every RM-instruction i there exists a constant C such that @(TimeDet, @(MK TMRM, i), C).

dec RMTimeDetThm : !(i : RMInstr) ?(C : Nat) @(TimeDet, @(MK_TMRM, i), C);

Theorem 10.6 (RM-Instruction Time-Deterministic Theorem 2) There is a constant C such that for every RM-instruction i @(TimeDet, @(MK TMRM, i), C).

dec RMTimeDetThm2 : ?(C : Nat) !(i : RMInstr) @(TimeDet, @(MK_TMRM, i), C);

10.6.3

Axioms of Time-Deterministic Analysis

Since the whole proof is conducted in a purely analytical way, we will assume that for a group of basic functions there exists a set of corresponding timedeterministic axioms. For instance, we assume that the time-deterministic property hold for identity function defined on TMState. dec IdentFunTDetAxm : let f = \(z : TMState) z in @(NLe, @(TIME_CAL, f), OO);

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

Other axioms are listed without explaination as follows: dec NatEqAxm : let f = \(old_vm_loc : VMKLocation, new_vm_loc : VMKLocation) @(EQ_VMKLOC, new_vm_loc, old_vm_loc) in @(NEqFunTDetCond, f); dec BoolNotAxm : let f = \(b : Bool) @(NOT, b) in @(B2BTimeDetCond, f); dec TMRegRetrieveAxm : !(idx : Nat) let f = \(rg : TMReg) @(TMREG_RETRIEVE, rg, idx) in @(TMReg2BWCond, f); dec TMRegAssignAxm : !(idx : Nat, w : Bit32Word) let f = \(rg : TMReg) @(TMREG_ASSIGN, rg, idx, w) in @(TMReg2TMRegCond, f); dec IsUseModeAxm : let f = \(bw : Bit32Word) @(IS_USE_MODE, bw) in @(BW2BoolCond, f); dec IsFirstRunAxm : let f = \(status : VMStatus) @(IS_VMFIRSTRUN, status) in @(BW2BoolCond, f); dec GetTMRegTDetAxm : @(TMRegFunTDetCond, \(z : TMState) @(GET_TMST_TMREG, z)); dec SetTMRegTDetAxm : @(TMReg2FunTDetCond, \(z : TMState, rg : TMReg) @(SET_TMST_TMREG, z, rg)); dec GetVMKManTDetAxm : @(TMVMKManTDetCond, \(z : TMState) @(GET_TMST_VMKMAN, z)); dec SetVMKManTDetAxm : @(STMVMKManTDetCond, \(z : TMState, mn : VMKManager) @(SET_TMST_VMKMAN, z, mn)); dec SetVMCBLvTickAxm : !(n : Nat) let f = \(vm : VMCB) @(SetVMCBLeaveTick, vm, n) in @(SetVMCBFTDetCond, f); dec GetVMK2RVTDetAxm :

210

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

let f = \(vmk : VMKManager) @(GET_VMKMAN_RUNVM, vmk) in @(VMKMLocTDetCond, f); dec GetVMK2TTSTDetAxm : let f = \(vmk : VMKManager) @(GET_VMKMAN_TTSVM, vmk) in @(VMKMLocTDetCond, f); dec GetVMK2PRQTDetAxm : let f = \(vmk : VMKManager) @(GET_VMKMAN_PQUEVM, vmk) in @(VMKMLocTDetCond, f); dec GetVMK2TICTDetAxm : let f = \(vmk : VMKManager) @(GET_VMKMAN_TICKCN, vmk) in @(VMKMLocTDetCond, f); dec SetVMK2RVTDetAxm : let f = \(vmk : VMKManager, vm_loc : VMKLocation) @(SET_VMKMAN_RUNVM, vmk, vm_loc) in @(SVMKMLocTDetCond, f); dec VMCBSetAxm : let f = \(vm_loc : VMKLocation, vm : VMCB, z : TMState) @(VMCB_SET, z, vm_loc, vm) in @(VMCBSetTDetCond, f); dec VMCBGetAxm : let f = \(loc : VMKLocation, z : TMState) @(VMCB_GET, z, loc) in @(VMCBGetTDetCond, f); dec GetVMCBStatusAxm : let f = \(vm : VMCB) @(GetVMCBStatus, vm) in @(GtVMCBStTDetCond, f); dec GetVMCBMmIdxAxm : let f = \(old_vm : VMCB) @(GetVMCBMemoIndex, old_vm) in @(GetVMCBMmIdxCond, f); dec GetVMCBIntCxAxm : let f = \(old_vm : VMCB) @(GetVMCBIntContxt, old_vm) in @(GetVMCBIntCxCond, f); dec SetVMCBIntCxAxm : let f = \(old_vm : VMCB, rg : TMReg) @(SetVMCBIntContxt, old_vm, rg) in

211

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

212

@(SetVMCBIntCxCond, f);

10.6.4

Auxiliary Theorems

10.6.4.1

Utility Theorems for Conditional Functions

The very frequently used functions in the semantic setting is conditional functions. The following time-deterministic theorem is established for the conditional functions defined on TMState. dec CondFunThm : !(b : [TMState -> Bool], f1 : [TMState -> TMState], f2 : [TMState -> TMState]) [@(BFunTimeDetCond, b) -> @(FunTimeDetCond, f1) -> @(FunTimeDetCond, f2) -> let f = \(z : TMState) @(GIF_THEN_ELSE, TMState, @(b, z), @(f1, z), @(f2, z)) in @(FunTimeDetCond, f)];

10.6.4.2

Utility Theorems for Composition Functions

Another very frequently used functions in the semantic setting is composition functions. The following time-deterministic theorem is established for the composition functions. dec CompFunThm : !(f1 : [TMState -> TMState], f2 : [TMState -> TMState]) [@(FunTimeDetCond, f1) -> @(FunTimeDetCond, f2) -> let f = \(z : TMState) @(f2, @(f1, z)) in @(FunTimeDetCond, f)]; dec Comp3FunThm : !(f1 : [TMState -> TMState], f2 : [TMState -> TMState], f3 : [TMState -> TMState]) [@(FunTimeDetCond, f1) -> @(FunTimeDetCond, f2) -> @(FunTimeDetCond, f3) -> let f = \(z : TMState)

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

213

@(f3, @(f2, @(f1, z))) in @(FunTimeDetCond, f)];

Beside of composition functions for state-transition functions, we also need composition functions defined for other types of domains such as TMReg, Bool and Nat. dec TMRegFCompThm : !(f1 : [TMState -> TMReg], f2 : [TMReg -> Bool]) [@(TMRegFunTDetCond, f1) -> @(BTMRegFunTDetCond, f2) -> let f = \(z : TMState) @(f2, @(f1, z)) in @(BFunTimeDetCond, f)]; dec BWTMRegFCompThm : !(f1 : [TMReg -> Bit32Word], f2 : [Bit32Word -> Bool]) [@(TMReg2BWCond, f1) -> @(BW2BoolCond, f2) -> let f = \(rg : TMReg) @(f2, @(f1, rg)) in @(BTMRegFunTDetCond, f)]; dec CompFunN21Thm : !(f1 : [TMState -> VMKLocation], f2 : [VMKLocation -> TMState -> TMState -> TMState]) [@(NFunTimeDetCond, f1) -> !(loc : VMKLocation, z0 : TMState) @(FunTimeDetCond, @(f2, loc, z0)) -> let f = \(z0 : TMState, z : TMState) @(f2, @(f1, z0), z0, z) in !(z0 : TMState) @(FunTimeDetCond, @(f, z0))]; dec CompFunN20Thm : !(f1 : [TMState -> VMKLocation], f2 : [VMKLocation -> TMState -> TMState]) [@(NFunTimeDetCond, f1) -> !(loc : VMKLocation) @(FunTimeDetCond, @(f2, loc)) -> let f = \(z : TMState) @(f2, @(f1, z), z) in @(FunTimeDetCond, f)]; dec CompFunN21Thm : !(f1 : [TMState -> VMKLocation], f2 : [VMKLocation -> TMState -> TMState -> TMState]) [@(NFunTimeDetCond, f1) -> !(loc : VMKLocation, z0 : TMState) @(FunTimeDetCond, @(f2, loc, z0)) -> let f = \(z0 : TMState, z : TMState)

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

@(f2, @(f1, z0), z0, z) in !(z0 : TMState) @(FunTimeDetCond, @(f, z0))]; dec CompFunN22Thm : !(f1 : [VMCB -> VMStatus], f2 : [VMStatus -> Bool]) [@(GtVMCBStTDetCond, f1) -> @(BW2BoolCond, f2) -> let f = \(vm : VMCB, z : TMState) @(f2, @(f1, vm)) in !(vm : VMCB) @(BFunTimeDetCond, @(f, vm))]; dec CompFunN2BThm : !(f1 : [VMKLocation -> VMKLocation -> Bool], f2 : [Bool -> Bool]) [@(NEqFunTDetCond, f1) -> @(B2BTimeDetCond, f2) -> let f = \(loc1 : VMKLocation, loc2 : VMKLocation) @(f2, @(f1, loc1, loc2)) in @(NEqFunTDetCond, f)]; dec Comp31FunThm : !(f1 : [TMState -> TMState], f2 : [TMState -> TMState -> TMState], f3 : [TMState -> TMState -> TMState]) [@(FunTimeDetCond, f1) -> !(z : TMState) @(FunTimeDetCond, @(f2, z)) -> !(z : TMState) @(FunTimeDetCond, @(f3, z)) -> let f = \(z : TMState) @(f3, z, @(f2, z, @(f1, z))) in @(FunTimeDetCond, f)]; dec MNComp31FunThm : !(f1 : [TMState -> VMKManager], f2 : [VMKManager -> VMKLocation -> VMKManager], f3 : [TMState -> VMKManager -> TMState]) [@(TMVMKManTDetCond, f1) -> @(SVMKMLocTDetCond, f2) -> @(STMVMKManTDetCond, f3) -> !(loc : VMKLocation, z0 : TMState) let f = \(z : TMState) @(f3, z, @(f2, @(f1, z0), loc)) in @(FunTimeDetCond, f)]; dec CompFunN41Thm : !(f1 : [TMState -> VMKManager], f2 : [VMKManager -> VMKLocation], f3 : [VMKManager -> VMKLocation], f4 : [VMKLocation -> VMKLocation -> VMKLocation]) [@(TMVMKManTDetCond, f1) ->

214

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

@(VMKMLocTDetCond, f2) -> @(VMKMLocTDetCond, f3) -> @(N2FunTimeDetCond, f4) -> let f = \(z : TMState) @(f4, @(f2, @(f1, z)), @(f3, @(f1, z))) in @(NFunTimeDetCond, f)]; dec CompFunN42Thm : !(f1 : [TMState -> VMKManager], f2 : [VMKManager -> Nat], f3 : [VMKLocation -> TMState -> VMCB], f4 : [VMKLocation -> VMCB -> Nat -> TMState -> TMState]) [@(TMVMKManTDetCond, f1) -> @(VMKMLocTDetCond, f2) -> @(VMCBGetTDetCond, f3) -> !(loc : VMKLocation, vm : VMCB, ticks : Nat) @(FunTimeDetCond, @(f4, loc, vm, ticks)) -> !(loc : VMKLocation) let f = \(z : TMState) @(f4, loc, @(f3, loc, z), @(f2, @(f1, z)), z) in @(FunTimeDetCond, f)]; dec Comp5FunThm : !(f1 : [TMState -> VMKManager], f2 : [VMKManager -> VMKLocation], f3 : [VMKLocation -> TMState -> VMCB], f4 : [VMCB -> VMCB], f5 : [VMKLocation -> VMCB -> TMState -> TMState]) [@(TMVMKManTDetCond, f1) -> @(VMKMLocTDetCond, f2) -> @(VMCBGetTDetCond, f3) -> @(SetVMCBFTDetCond, f4) -> @(VMCBSetTDetCond, f5) -> let f = \(z0 : TMState, z : TMState) let vm_loc = @(f2, @(f1, z0)), vm = @(f3, vm_loc, z0), nvm = @(f4, vm) in @(f5, vm_loc, nvm, z) in !(z0 : TMState) @(FunTimeDetCond, @(f, z0))]; dec BComp6FunThm : !(f1 : [TMState -> VMKManager], f2 : [VMKManager -> VMKLocation], f3 : [VMKManager -> VMKLocation], f4 : [VMKManager -> VMKLocation], f5 : [VMKLocation -> VMKLocation -> VMKLocation], f6 : [VMKLocation -> VMKLocation -> Bool]) [@(TMVMKManTDetCond, f1) -> @(VMKMLocTDetCond, f2) -> @(VMKMLocTDetCond, f3) -> @(VMKMLocTDetCond, f4) ->

215

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

@(N2FunTimeDetCond, f5) -> @(NEqFunTDetCond, f6) -> let f = \(z : TMState) let old_vm_loc = @(f2, @(f1, z)), tts_vm_loc = @(f3, @(f1, z)), prq_vm_loc = @(f4, @(f1, z)) in let new_vm_loc = @(f5, tts_vm_loc, prq_vm_loc) in @(f6, old_vm_loc, new_vm_loc) in @(BFunTimeDetCond, f)]; dec ZComp6FunThm : !(f1 : [TMState -> VMKManager], f2 : [VMKManager -> VMKLocation], f3 : [VMKLocation -> TMState -> VMCB], f4 : [TMState -> TMReg], f5 : [VMCB -> TMReg -> VMCB], f6 : [VMKLocation -> VMCB -> TMState -> TMState]) [@(TMVMKManTDetCond, f1) -> @(VMKMLocTDetCond, f2) -> @(VMCBGetTDetCond, f3) -> @(TMRegFunTDetCond, f4) -> @(SetVMCBIntCxCond, f5) -> @(VMCBSetTDetCond, f6) -> let f = \(z : TMState) let old_vm_loc = @(f2, @(f1, z)) in let old_vm = @(f3, old_vm_loc, z), rg = @(f4, z), new_vm = @(f5, old_vm, rg) in @(f6, old_vm_loc, new_vm, z) in @(FunTimeDetCond, f)]; dec ZComp8FunThm : !(f1 : [TMState -> VMKManager], f2 : [VMKManager -> VMKLocation], f3 : [VMKLocation -> TMState -> VMCB], f4 : [VMCB -> Nat], f5 : [VMCB -> TMReg], f6 : [TMReg -> TMReg], f7 : [Nat -> TMReg -> TMReg], f8 : [TMState -> TMReg -> TMState]) [@(TMVMKManTDetCond, f1) -> @(VMKMLocTDetCond, f2) -> @(VMCBGetTDetCond, f3) -> @(GetVMCBMmIdxCond, f4) -> @(GetVMCBIntCxCond, f5) -> @(TMReg2TMRegCond, f6) -> !(memoidx : Nat) @(TMReg2TMRegCond, @(f7, memoidx)) -> @(TMReg2FunTDetCond, f8) -> let f = \(z : TMState) let run_vm_loc = @(f2, @(f1, z)) in let run_vm = @(f3, run_vm_loc, z), memoidx = @(f4, run_vm),

216

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

context = @(f5, run_vm) in let nrg1 = @(f6, context), nrg2 = @(f7, memoidx, nrg1) in @(f8, z, nrg2) in @(FunTimeDetCond, f)];

10.6.4.3

Proofs of Utility Theorems

The CondFunThm is proved as follows: dec CondFunAxm : !(b : [TMState -> Bool], f1 : [TMState -> TMState], f2 : [TMState -> TMState]) !(bC : Nat, C1 : Nat, C2 : Nat) [@(BoolFunTimeDet, b, bC) -> @(FunTimeDet, f1, C1) -> @(FunTimeDet, f2, C2) -> let C = @(MAX, @(ADD, bC, C1), @(ADD, bC, C2)), f = \(z : TMState) @(GIF_THEN_ELSE, TMState, @(b, z), @(f1, z), @(f2, z)) in @(FunTimeDet, f, C)]; def CondFunThm = \(b : [TMState -> Bool], f1 : [TMState -> TMState], f2 : [TMState -> TMState]) \(bp : @(BFunTimeDetCond, b), p1 : @(FunTimeDetCond, f1), p2 : @(FunTimeDetCond, f2)) let bC = @(FST, bp), bq = @(SND, bp), C1 = @(FST, p1), q1 = @(SND, p1), C2 = @(FST, p2), q2 = @(SND, p2) in let C = @(MAX, @(ADD, bC, C1), @(ADD, bC, C2)), q = @(CondFunAxm, b, f1, f2, bC, C1, C2, bq, q1, q2) in ;

The CompFunThm is proved as follows: dec CompFunAxm : !(f1 : [TMState -> TMState], f2 : [TMState -> TMState]) let f = \(z : TMState) @(f2, @(f1, z)) in @(Equal, Nat,

217

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

@(TIME_CAL, f), @(ADD, @(TIME_CAL, f1), @(TIME_CAL, f2))); dec CompFunLem : !(f1 : [TMState -> TMState], f2 : [TMState -> TMState]) !(C1 : Nat, C2 : Nat) [@(FunTimeDet, f1, C1) -> @(FunTimeDet, f2, C2) -> let C = @(ADD, C1, C2), f = \(z : TMState) @(f2, @(f1, z)) in @(FunTimeDet, f, C)]; dec NLeAddLem : !(c1 : Nat, c2 : Nat, C1 : Nat, C2 : Nat) [@(NLe, c1, C1) -> @(NLe, c2, C2) -> @(NLe, @(ADD, c1, c2), @(ADD, C1, C2))]; dec NLeEqTranLem : !(c1 : Nat, c2 : Nat, C1 : Nat, C2 : Nat, C : Nat) [@(Equal, Nat, C, @(ADD, c1, c2)) -> @(NLe, @(ADD, c1, c2), @(ADD, C1, C2)) -> @(NLe, C, @(ADD, C1, C2))]; def CompFunLem = \(f1 : [TMState -> TMState], f2 : [TMState -> TMState]) \(C1 : Nat, C2 : Nat) \(p1 : @(FunTimeDet, f1, C1), p2 : @(FunTimeDet, f2, C2)) let c1 = @(TIME_CAL, f1), c2 = @(TIME_CAL, f2) in let q1 = @(CompFunAxm, f1, f2), q2 = @(NLeAddLem, c1, c2, C1, C2, p1, p2) in let f = \(z : TMState) @(f2, @(f1, z)) in @(NLeEqTranLem, c1, c2, C1, C2, @(TIME_CAL, f), q1, q2); def CompFunThm = \(f1 : [TMState -> TMState], f2 : [TMState -> TMState]) \(p1 : @(FunTimeDetCond, f1), p2 : @(FunTimeDetCond, f2)) let C1 = @(FST, p1), q1 = @(SND, p1), C2 = @(FST, p2), q2 = @(SND, p2) in let C = @(ADD, C1, C2), p = @(CompFunLem, f1, f2, C1, C2, q1, q2) in ;

Comp3FunThm is proved using CompFunThm.

218

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

219

def Comp3FunThm = \(f1 : [TMState -> TMState], f2 : [TMState -> TMState], f3 : [TMState -> TMState]) \(p1 : @(FunTimeDetCond, f1), p2 : @(FunTimeDetCond, f2), p3 : @(FunTimeDetCond, f3)) let f = \(z : TMState) @(f2, @(f1, z)), p = @(CompFunThm, f1, f2, p1, p2) in @(CompFunThm, f, f3, p, p3);

10.6.5

Proofs of TimeDetThm

The proof of TimeDetThm can easily be proved using the theorems ROTimeDetThm and RMTimeDetThm with the induction rule InstrInduct on Instr def TimeDetThm = let P = \(i : Instr) ?(C : Nat) @(TimeDet, i, C) in @(InstrInduct, P, ROTimeDetThm, RMTimeDetThm)

10.6.6

Proofs of TimeDetThm2

The following lemmas will be listed without proofs. dec NatMAXLem : !(C1 : Nat, C2 : Nat) @(NLe, C1, @(MAX, C1, C2)); dec NatMAXSymmLem : !(C : Nat, C1 : Nat, C2 : Nat) [@(NLe, C, @(MAX, C1, C2)) -> @(NLe, C, @(MAX, C2, C1))]; dec Nat_Tran_Le : !(x : Nat, y : Nat, z : Nat) [@(NLe, x, y) -> @(NLe, y, z) -> @(NLe, x, z)];

To prove TimeDetThm2 we will need a lemma TimeDetLem2.

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

220

dec TimeDetLem2 : !(C1 : Nat, C2 : Nat) [!(i : ROInstr) let f = \(z : TMState) @(TMSEM, z, @(MK_TMRO, i)) in @(NLe, @(TIME_CAL, f), C1) -> !(i : RMInstr) let f = \(z : TMState) @(TMSEM, z, @(MK_TMRM, i)) in @(NLe, @(TIME_CAL, f), C2) -> let C = @(MAX, C1, C2) in !(i : Instr) let f = \(z : TMState) @(TMSEM, z, i) in @(NLe, @(TIME_CAL, f), C)];

To prove TimeDetLem2, we will need two lemmas TimeDetLem21 and TimeDetLem22. dec TimeDetLem21 : !(C1 : Nat, C2 : Nat) [!(i : ROInstr) let f = \(z : TMState) @(TMSEM, z, @(MK_TMRO, i)) in @(NLe, @(TIME_CAL, f), C1) -> !(i : ROInstr) let f = \(z : TMState) @(TMSEM, z, @(MK_TMRO, i)) in let C = @(MAX, C1, C2) in @(NLe, @(TIME_CAL, f), C)]; def TimeDetLem21 = \(C1 : Nat, C2 : Nat) \(p : !(i : ROInstr) let f = \(z : TMState) @(TMSEM, z, @(MK_TMRO, i)) in @(NLe, @(TIME_CAL, f), C1)) \(i : ROInstr) let f = \(z : TMState) @(TMSEM, z, @(MK_TMRO, i)) in let C = @(MAX, C1, C2) in let q = @(NatMAXLem, C1, C2) in @(Nat_Tran_Le, @(TIME_CAL, f), C1, C, @(p, i), q); dec TimeDetLem22 : !(C1 : Nat, C2 : Nat) [!(i : RMInstr) let f = \(z : TMState) @(TMSEM, z, @(MK_TMRM, i)) in @(NLe, @(TIME_CAL, f), C2) -> !(i : RMInstr) let f = \(z : TMState) @(TMSEM, z, @(MK_TMRM, i)) in let C = @(MAX, C1, C2) in @(NLe, @(TIME_CAL, f), C)];

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

221

def TimeDetLem22 = \(C1 : Nat, C2 : Nat) \(p : !(i : RMInstr) let f = \(z : TMState) @(TMSEM, z, @(MK_TMRM, i)) in @(NLe, @(TIME_CAL, f), C2)) \(i : RMInstr) let f = \(z : TMState) @(TMSEM, z, @(MK_TMRM, i)) in let C = @(MAX, C2, C1) in let q1 = @(NatMAXLem, C2, C1), q2 = @(Nat_Tran_Le, @(TIME_CAL, f), C2, C, @(p, i), q1) in @(NatMAXSymmLem, @(TIME_CAL, f), C2, C1, q2);

TimeDetLem2 is proved using lemmas TimeDetLem21 and TimeDetLem22. def TimeDetLem2 = \(C1 : Nat, C2 : Nat) \(p1 : !(i : ROInstr) let f = \(z : TMState) @(TMSEM, z, @(MK_TMRO, i)) in @(NLe, @(TIME_CAL, f), C1), p2 : !(i : RMInstr) let f = \(z : TMState) @(TMSEM, z, @(MK_TMRM, i)) in @(NLe, @(TIME_CAL, f), C2)) let C = @(MAX, C1, C2) in let P = \(i : Instr) let f = \(z : TMState) @(TMSEM, z, i) in @(NLe, @(TIME_CAL, f), C) in let q1 = @(TimeDetLem21, C1, C2, p1), q2 = @(TimeDetLem22, C1, C2, p2) in @(InstrInduct, P, q1, q2);

The proof of TimeDetThm2 is derived using ROTimeDetThm2, ROTimeDetThm2, and TimeDetLem2. def TimeDetThm2 = let p1 = ROTimeDetThm2, p2 = RMTimeDetThm2 in let C1 = @(FST, p1), q1 = @(SND, p1), C2 = @(FST, p2), q2 = @(SND, p2) in let C = @(MAX, C1, C2), q = @(TimeDetLem2, C1, C2, q1, q2) in ;

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

10.6.7

222

Proofs of RMTimeDetThm and RMTimeDetThm2

10.6.7.1 The Theorem RMTimeDetThm3 and Its Proof We may obtain the following theorem RMTimeDetThm3 from RMTimeDetThm using a Choice Axiom Choice Axm. dec RMTimeDetThm3 : ?(f : [RMInstr -> Nat]) !(i : RMInstr) @(TimeDet, @(MK_TMRM, i), @(f, i));

Choice Axm describes that for any proposition defined on A and B, the predicate !(x : A) ?(y : B) @(P, x, y) implies ?(f : [A -> B]) !(x : A) @(P, x, @(f, x)). dec Choice_Axm : !(A : Prop, B : Prop) !(P : [A -> B -> Prop]) [!(x : A) ?(y : B) @(P, x, y) -> ?(f : [A -> B]) !(x : A) @(P, x, @(f, x))];

Actually we can give a proof of Choice Axm. So Choice Axm is not an axiom in type-theoretical framework. def Choice_Axm = \(A : Prop, B : Prop) \(P : [A -> B -> Prop]) \(l : !(x : A) ?(y : B) @(P, x, y)) let f = \(x : A) @(FST, @(l, x)) in let p = \(x : A, g : @(P, x, @(f, x))) g in let q = \(x : A) @(p, x, @(SND, @(l, x))) in ;

We then will be able to give the proof of RMTimeDetThm3 using Choice Axm. def RMTimeDetThm3 = let P = \(i : RMInstr, C : Nat) @(TimeDet, @(MK_TMRM, i), C) in @(Choice_Axm, RMInstr, Nat, P, RMTimeDetThm);

However what we need is the theorem RMTimeDetThm2 indicating that there exists a constant C which is the boundary of all RM instructions. 10.6.7.2

Time Deterministic Theorem for RMOpcode

The time-deterministic theorems for RMOpcode are listed as follows: dec RMInstrTDetThm : let P = \(i : RMInstr)

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

223

?(C : Nat) @(TimeDet, @(MK_TMRM, i), C) in !(op : RMOpcode, r : Nat, d : Int, s : Nat) @(P, @(MK_RMINST, op, r, d, s)); dec RMInstrTDetThm2 : ?(C : Nat) !(op : RMOpcode, r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, op, r, d, s)), C);

10.6.7.3

Two Axioms

The following two axioms are very important axioms. • The RMInstTDetAxm says that for every RM opcode op, there exists a corresponding RM instruction. • The RMRegChoiceAxm is a choice axiom for RM instructions which says that for every RM opcode op and any particular registers rr and ss and distance number dd, if @(MK RMINST, op, rr, dd, ss) is deterministic then for every registers r and s and distance number d, @(MK RMINST, op, r, d, s) is deterministic. The first axiom is simple and intuitive. The acceptance of the second axiom means that for each instruction the complexity measurement will not depend on its register parameters. That is, if @(TimeDet, @(MK TMRM, @(MK RMINST, op, rr, dd, ss)), C) holds for the given parameters rr, dd and ss for a particular instruction with operation code op, then it will hold for any parameters r, d and s. So the constant C can be obtained by testing. dec RMInstTDetAxm : !(op : RMOpcode) ?(i : RMInstr, r : Nat, d : Int, s : Nat) @(Equal, RMInstr, i, @(MK_RMINST, op, r, d, s)); dec RMRegChoiceAxm : !(op : RMOpcode, rr : Nat, dd : Int, ss : Nat, C : Nat) [@(TimeDet, @(MK_TMRM, @(MK_RMINST, op, rr, dd, ss)), C) -> !(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, op, r, d, s)), C)];

10.6.7.4 Time Deterministic Theorem for LD Since LD is a basic RISC-instruction, there is no need to prove LDRMInstTDetThm. It is used as an assumption. dec LDRMInstTDetThm :

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

224

let P = \(i : RMInstr) ?(C : Nat) @(TimeDet, @(MK_TMRM, i), C) in !(r : Nat, d : Int, s : Nat) @(P, @(MK_RMINST, LD, r, d, s));

With RMInstTDetAxm and RMRegChoiceAxm we will be able to derive the proof of LDRMInstTDetThm2 from LDRMInstTDetThm. dec LDRMInstTDetThm2 : ?(C : Nat) !(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, LD, r, d, s)), C); def LDRMInstTDetThm2 = let p = @(RMInstTDetAxm, LD) in let rr = @(FST, @(SND, p)), dd = @(FST, @(SND, @(SND, p))), ss = @(FST, @(SND, @(SND, @(SND, p)))) in let q = @(LDRMInstTDetThm, rr, dd, ss) in let C = @(FST, q), u = @(SND, q) in let w = @(RMRegChoiceAxm, LD, rr, dd, ss, C, u) in ;

10.6.7.5

Time Deterministic Theorem for LDA

dec LDARMInstTDetThm : let P = \(i : RMInstr) ?(C : Nat) @(TimeDet, @(MK_TMRM, i), C) in !(r : Nat, d : Int, s : Nat) @(P, @(MK_RMINST, LDA, r, d, s)); dec LDARMInsTDetThm2 : ?(C : Nat) !(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, LDA, r, d, s)), C); def LDARMInsTDetThm2 = let p = @(RMInstTDetAxm, LDA) in let rr = @(FST, @(SND, p)), dd = @(FST, @(SND, @(SND, p))), ss = @(FST, @(SND, @(SND, @(SND, p)))) in let q = @(LDARMInstTDetThm, rr, dd, ss) in let C = @(FST, q), u = @(SND, q) in let w = @(RMRegChoiceAxm, LDA, rr, dd, ss, C, u) in

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

;

10.6.7.6

Time Deterministic Theorem for LDA

dec LDCRMInstTDetThm : let P = \(i : RMInstr) ?(C : Nat) @(TimeDet, @(MK_TMRM, i), C) in !(r : Nat, d : Int, s : Nat) @(P, @(MK_RMINST, LDC, r, d, s)); dec LDCRMInsTDetThm2 : ?(C : Nat) !(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, LDC, r, d, s)), C);

10.6.7.7

Time Deterministic Theorem for ST

dec STRMInstTDetThm : let P = \(i : RMInstr) ?(C : Nat) @(TimeDet, @(MK_TMRM, i), C) in !(r : Nat, d : Int, s : Nat) @(P, @(MK_RMINST, ST, r, d, s)); dec STRMInstTDetThm2 : ?(C : Nat) !(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, ST, r, d, s)), C);

10.6.7.8

Time Deterministic Theorem for JLT

dec JLTRMInstTDetThm : let P = \(i : RMInstr) ?(C : Nat) @(TimeDet, @(MK_TMRM, i), C) in !(r : Nat, d : Int, s : Nat) @(P, @(MK_RMINST, JLT, r, d, s)); dec JLTRMInsTDetThm2 : ?(C : Nat) !(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, JLT, r, d, s)), C);

225

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

10.6.7.9

Time Deterministic Theorem for JLE

dec JLERMInstTDetThm : let P = \(i : RMInstr) ?(C : Nat) @(TimeDet, @(MK_TMRM, i), C) in !(r : Nat, d : Int, s : Nat) @(P, @(MK_RMINST, JLE, r, d, s)); dec JLERMInsTDetThm2 : ?(C : Nat) !(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, JLE, r, d, s)), C);

10.6.7.10

Time Deterministic Theorem for JGT

dec JGTRMInstTDetThm : let P = \(i : RMInstr) ?(C : Nat) @(TimeDet, @(MK_TMRM, i), C) in !(r : Nat, d : Int, s : Nat) @(P, @(MK_RMINST, JGT, r, d, s)); dec JGTRMInsTDetThm2 : ?(C : Nat) !(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, JGT, r, d, s)), C);

10.6.7.11

Time Deterministic Theorem for JGE

dec JGERMInstTDetThm : let P = \(i : RMInstr) ?(C : Nat) @(TimeDet, @(MK_TMRM, i), C) in !(r : Nat, d : Int, s : Nat) @(P, @(MK_RMINST, JGE, r, d, s)); dec JGERMInsTDetThm2 : ?(C : Nat) !(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, JGE, r, d, s)), C);

10.6.7.12

Time Deterministic Theorem for JEQ

dec JEQRMInstTDetThm :

226

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

let P = \(i : RMInstr) ?(C : Nat) @(TimeDet, @(MK_TMRM, i), C) in !(r : Nat, d : Int, s : Nat) @(P, @(MK_RMINST, JEQ, r, d, s)); dec JEQRMInsTDetThm2 : ?(C : Nat) !(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, JEQ, r, d, s)), C);

10.6.7.13

Time Deterministic Theorem for JNE

dec JNERMInstTDetThm : let P = \(i : RMInstr) ?(C : Nat) @(TimeDet, @(MK_TMRM, i), C) in !(r : Nat, d : Int, s : Nat) @(P, @(MK_RMINST, JNE, r, d, s)); dec JNERMInsTDetThm2 : ?(C : Nat) !(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, JNE, r, d, s)), C);

10.6.7.14

Proof of RMInstrTDetThm

def RMInstrTDetThm = let P = \(i : RMInstr) ?(C : Nat) @(TimeDet, @(MK_TMRM, i), C) in @(RMOpcodeInduct, P, LDRMInstTDetThm, LDARMInstTDetThm, LDCRMInstTDetThm, STRMInstTDetThm, JLTRMInstTDetThm, JLERMInstTDetThm, JGTRMInstTDetThm, JGERMInstTDetThm, JEQRMInstTDetThm, JNERMInstTDetThm);

227

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

10.6.7.15

Proof of RMInstrTDetLem2

dec MAX10 : [Nat -> Nat -> Nat -> Nat -> Nat -> Nat -> Nat -> Nat -> Nat -> Nat -> Nat]; dec RMInstrTDetLem2 : !(C0 : Nat, C1 : Nat, C2 : Nat, C3 : Nat, C4 : Nat, C5 : Nat, C6 : Nat, C7 : Nat, C8 : Nat, C9 : Nat) [!(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, LD, r, d, s)), C0) -> !(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, LDA, r, d, s)), C1) -> !(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, LDC, r, d, s)), C2) -> !(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, ST, r, d, s)), C3) -> !(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, JLT, r, d, s)), C4) -> !(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, JLE, r, d, s)), C5) -> !(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, JGT, r, d, s)), C6) -> !(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, JGE, r, d, s)), C7) -> !(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, JEQ, r, d, s)), C8) -> !(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, JNE, r, d, s)), C9) -> let C = @(MAX10, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) in !(op : RMOpcode, r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, op, r, d, s)), C)]; dec RMInstrTDetLem20 : !(C0 : Nat, C1 : Nat, C2 : Nat, C3 : Nat, C4 : Nat, C5 : Nat, C6 : Nat, C7 : Nat, C8 : Nat, C9 : Nat) [!(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, LD, r, d, s)), C0) -> !(r : Nat, d : Int, s : Nat) let C = @(MAX10, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) in @(TimeDet, @(MK_TMRM, @(MK_RMINST, LD, r, d, s)), C)]; dec RMInstrTDetLem21 : !(C0 : Nat, C1 : Nat, C2 : Nat, C3 : Nat, C4 : Nat, C5 : Nat, C6 : Nat, C7 : Nat, C8 : Nat, C9 : Nat) [!(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, LDA, r, d, s)), C1) -> !(r : Nat, d : Int, s : Nat) let C = @(MAX10, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) in @(TimeDet, @(MK_TMRM, @(MK_RMINST, LDA, r, d, s)), C)]; dec RMInstrTDetLem22 :

228

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

!(C0 : Nat, C1 : Nat, C2 : Nat, C3 : Nat, C4 : Nat, C5 : Nat, C6 : Nat, C7 : Nat, C8 : Nat, C9 : Nat) [!(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, LDC, r, d, s)), C2) -> !(r : Nat, d : Int, s : Nat) let C = @(MAX10, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) in @(TimeDet, @(MK_TMRM, @(MK_RMINST, LDC, r, d, s)), C)]; dec RMInstrTDetLem23 : !(C0 : Nat, C1 : Nat, C2 : Nat, C3 : Nat, C4 : Nat, C5 : Nat, C6 : Nat, C7 : Nat, C8 : Nat, C9 : Nat) [!(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, ST, r, d, s)), C3) -> !(r : Nat, d : Int, s : Nat) let C = @(MAX10, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) in @(TimeDet, @(MK_TMRM, @(MK_RMINST, ST, r, d, s)), C)]; dec RMInstrTDetLem24 : !(C0 : Nat, C1 : Nat, C2 : Nat, C3 : Nat, C4 : Nat, C5 : Nat, C6 : Nat, C7 : Nat, C8 : Nat, C9 : Nat) [!(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, JLT, r, d, s)), C4) -> !(r : Nat, d : Int, s : Nat) let C = @(MAX10, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) in @(TimeDet, @(MK_TMRM, @(MK_RMINST, JLT, r, d, s)), C)]; dec RMInstrTDetLem25 : !(C0 : Nat, C1 : Nat, C2 : Nat, C3 : Nat, C4 : Nat, C5 : Nat, C6 : Nat, C7 : Nat, C8 : Nat, C9 : Nat) [!(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, JLE, r, d, s)), C5) -> !(r : Nat, d : Int, s : Nat) let C = @(MAX10, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) in @(TimeDet, @(MK_TMRM, @(MK_RMINST, JLE, r, d, s)), C)]; dec RMInstrTDetLem26 : !(C0 : Nat, C1 : Nat, C2 : Nat, C3 : Nat, C4 : Nat, C5 : Nat, C6 : Nat, C7 : Nat, C8 : Nat, C9 : Nat) [!(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, JGT, r, d, s)), C6) -> !(r : Nat, d : Int, s : Nat) let C = @(MAX10, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) in @(TimeDet, @(MK_TMRM, @(MK_RMINST, JGT, r, d, s)), C)]; dec RMInstrTDetLem27 : !(C0 : Nat, C1 : Nat, C2 : Nat, C3 : Nat, C4 : Nat, C5 : Nat, C6 : Nat, C7 : Nat, C8 : Nat, C9 : Nat) [!(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, JGE, r, d, s)), C7) -> !(r : Nat, d : Int, s : Nat) let C = @(MAX10, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) in @(TimeDet, @(MK_TMRM, @(MK_RMINST, JGE, r, d, s)), C)];

229

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

dec RMInstrTDetLem28 : !(C0 : Nat, C1 : Nat, C2 : Nat, C3 : Nat, C4 : Nat, C5 : Nat, C6 : Nat, C7 : Nat, C8 : Nat, C9 : Nat) [!(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, JEQ, r, d, s)), C8) -> !(r : Nat, d : Int, s : Nat) let C = @(MAX10, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) in @(TimeDet, @(MK_TMRM, @(MK_RMINST, JEQ, r, d, s)), C)]; dec RMInstrTDetLem29 : !(C0 : Nat, C1 : Nat, C2 : Nat, C3 : Nat, C4 : Nat, C5 : Nat, C6 : Nat, C7 : Nat, C8 : Nat, C9 : Nat) [!(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, JNE, r, d, s)), C9) -> !(r : Nat, d : Int, s : Nat) let C = @(MAX10, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) in @(TimeDet, @(MK_TMRM, @(MK_RMINST, JNE, r, d, s)), C)]; def RMInstrTDetLem2 = \(C0 : Nat, C1 : Nat, C2 : Nat, C3 : Nat, C4 : Nat, C5 : Nat, C6 : Nat, C7 : Nat, C8 : Nat, C9 : Nat) \(p0 : !(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, LD, r, d, s)), C0), p1 : !(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, LDA, r, d, s)), C1), p2 : !(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, LDC, r, d, s)), C2), p3 : !(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, ST, r, d, s)), C3), p4 : !(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, JLT, r, d, s)), C4), p5 : !(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, JLE, r, d, s)), C5), p6 : !(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, JGT, r, d, s)), C6), p7 : !(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, JGE, r, d, s)), C7), p8 : !(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, JEQ, r, d, s)), C8), p9 : !(r : Nat, d : Int, s : Nat) @(TimeDet, @(MK_TMRM, @(MK_RMINST, JNE, r, d, s)), C9)) let C = @(MAX10, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9) in let P = \(i : RMInstr) @(TimeDet, @(MK_TMRM, i), C) in let q0 = @(RMInstrTDetLem20, C0, C1, C2, C3, C4, C5, C6, C7, C8, q1 = @(RMInstrTDetLem21, C0, C1, C2, C3, C4, C5, C6, C7, C8, q2 = @(RMInstrTDetLem22, C0, C1, C2, C3, C4, C5, C6, C7, C8, q3 = @(RMInstrTDetLem23, C0, C1, C2, C3, C4, C5, C6, C7, C8, q4 = @(RMInstrTDetLem24, C0, C1, C2, C3, C4, C5, C6, C7, C8, q5 = @(RMInstrTDetLem25, C0, C1, C2, C3, C4, C5, C6, C7, C8, q6 = @(RMInstrTDetLem26, C0, C1, C2, C3, C4, C5, C6, C7, C8,

C9, C9, C9, C9, C9, C9, C9,

p0), p1), p2), p3), p4), p5), p6),

230

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

231

q7 = @(RMInstrTDetLem27, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, p7), q8 = @(RMInstrTDetLem28, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, p8), q9 = @(RMInstrTDetLem29, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, p9) in @(RMOpcodeInduct, P, q0, q1, q2, q3, q4, q5, q6, q7, q8, q9); def RMInstrTDetThm2 = let p0 = LDRMInstTDetThm2, p1 = LDARMInsTDetThm2, p2 = LDCRMInsTDetThm2, p3 = STRMInstTDetThm2, p4 = JLTRMInsTDetThm2, p5 = JLERMInsTDetThm2, p6 = JGTRMInsTDetThm2, p7 = JGERMInsTDetThm2, p8 = JEQRMInsTDetThm2, p9 = JNERMInsTDetThm2 in let C0 = @(FST, p0), q0 = @(SND, p0), C1 = @(FST, p1), q1 = @(SND, p1), C2 = @(FST, p2), q2 = @(SND, p2), C3 = @(FST, p3), q3 = @(SND, p3), C4 = @(FST, p4), q4 = @(SND, p4), C5 = @(FST, p5), q5 = @(SND, p5), C6 = @(FST, p6), q6 = @(SND, p6), C7 = @(FST, p7), q7 = @(SND, p7), C8 = @(FST, p8), q8 = @(SND, p8), C9 = @(FST, p9), q9 = @(SND, p9) in let C = @(MAX10, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9), q = @(RMInstrTDetLem2, C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, q0, q1, q2, q3, q4, q5, q6, q7, q8, q9) in ;

10.6.7.16 Proof of RMTimeDetThm The proof of RMTimeDetThm is conducted by induction rule RMInstrInduct and theorem RMInstrTDetThm. def RMTimeDetThm = let P = \(i : RMInstr) ?(C : Nat) @(TimeDet, @(MK_TMRM, i), C) in @(RMInstrInduct, P, RMInstrTDetThm);

10.6.7.17 Proof of RMTimeDetThm2 The proof of RMTimeDetThm2 is conducted by induction rule RMInstrInduct and theorem RMInstrTDetThm2.

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

232

def RMTimeDetThm2 = let p = RMInstrTDetThm2 in let C = @(FST, p), q = @(SND, p) in let P = \(i : RMInstr) @(TimeDet, @(MK_TMRM, i), C) in let w = @(RMInstrInduct, P, q) in ;

10.6.8

Proofs of ROTimeDetThm and ROTimeDetThm2

Similar to RMTimeDetThm and RMTimeDetThm2, ROTimeDetThm and Thm2 can be easily proved using induction rules on ROOpcode. In we will not give the details of the proofs for ROTimeDetThm and Thm2. Instead we will give the proof of the time-deterministic RO-instruction SCHEDULE.

ROTimeDetthis section, ROTimeDettheorem for

10.6.8.1 Theorem SCHROInstTDetThm The time-deterministic theorem for RO-instruction SCHEDULE is represented in terms of PowerEpsilon based on the semantic definition of SCHEDULE as follows: dec SCHROInstTDetThm : let P = \(i : ROInstr) ?(C : Nat) @(TimeDet, @(MK_TMRO, i), C) in !(r : Nat, s : Nat, t : Nat) @(P, @(MK_ROINST, SCHEDULE, r, s, t));

10.6.8.2

Time Deterministic Lemma for Identity Function

dec IdentFunTDetLem : let f = \(z : TMState) z in @(FunTimeDetCond, f); def IdentFunTDetLem = let f = \(z : TMState) z in let C = OO, p = IdentFunTDetAxm in ;

10.6.8.3

Proof of ScheduleBoolLem

dec ScheduleBoolLem :

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

233

let b = \(z : TMState) let rg = @(GET_TMST_TMREG, z) in @(IS_USE_MODE, @(TMREG_RETRIEVE, rg, MD_REG)) in @(BFunTimeDetCond, b); dec BTMRegFunTDetLem : let f = \(rg : TMReg) @(IS_USE_MODE, @(TMREG_RETRIEVE, rg, MD_REG)) in @(BTMRegFunTDetCond, f); def BTMRegFunTDetLem = let f1 = \(rg : TMReg) @(TMREG_RETRIEVE, rg, MD_REG), f2 = \(bw : Bit32Word) @(IS_USE_MODE, bw) in let p1 = @(TMRegRetrieveAxm, MD_REG), p2 = IsUseModeAxm in @(BWTMRegFCompThm, f1, f2, p1, p2); def ScheduleBoolLem = let f1 = \(z : TMState) @(GET_TMST_TMREG, z), f2 = \(rg : TMReg) @(IS_USE_MODE, @(TMREG_RETRIEVE, rg, MD_REG)) in let p1 = GetTMRegTDetAxm, p2 = BTMRegFunTDetLem in @(TMRegFCompThm, f1, f2, p1, p2);

10.6.8.4

Proof of ScheduleFunLem1

dec ScheduleFunLem1 : let f = \(z : TMState) @(ERR_TMSTATE, z) in @(FunTimeDetCond, f);

10.6.8.5

Proof of ScheduleFunLem2

dec ScheduleFunLem2 : let f = \(z : TMState) let z1 = @(SAVE_CONTEXT, z), z2 = @(SCHEDULE_VM, z1), z3 = @(SWITCH_CONTEXT, z2) in z3 in @(FunTimeDetCond, f);

To prove ScheduleFunLem2 we will, as it is defined, need the following three lemmas.

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

dec SaveContxTDetLem : @(FunTimeDetCond, SAVE_CONTEXT); dec SchedulVMTDetLem : @(FunTimeDetCond, SCHEDULE_VM); dec SwitContxTDetLem : @(FunTimeDetCond, SWITCH_CONTEXT);

10.6.8.6

Proof of SaveContxTDetLem

def SaveContxTDetLem = let f0 = \(z : TMState) @(GET_TMST_VMKMAN, z), f1 = \(mn : VMKManager) @(GET_VMKMAN_RUNVM, mn), f2 = \(old_vm_loc : VMKLocation, z : TMState) @(VMCB_GET, z, old_vm_loc), f3 = \(z : TMState) @(GET_TMST_TMREG, z), f4 = \(old_vm : VMCB, rg : TMReg) @(SetVMCBIntContxt, old_vm, rg), f5 = \(old_vm_loc : VMKLocation, new_vm : VMCB, z : TMState) @(VMCB_SET, z, old_vm_loc, new_vm) in let p0 = GetVMKManTDetAxm, p1 = GetVMK2RVTDetAxm, p2 = VMCBGetAxm, p3 = GetTMRegTDetAxm, p4 = SetVMCBIntCxAxm, p5 = VMCBSetAxm in @(ZComp6FunThm, f0, f1, f2, f3, f4, f5, p0, p1, p2, p3, p4, p5);

10.6.8.7

Proof of SwitContxTDetLem

def SwitContxTDetLem = let f1 = \(z : TMState) @(GET_TMST_VMKMAN, z), f2 = \(mn : VMKManager) @(GET_VMKMAN_RUNVM, mn), f3 = \(run_vm_loc : VMKLocation, z : TMState) @(VMCB_GET, z, run_vm_loc), f4 = \(run_vm : VMCB) @(GetVMCBMemoIndex, run_vm), f5 = \(run_vm : VMCB) @(GetVMCBIntContxt, run_vm), f6 = \(context : TMReg) @(TMREG_ASSIGN, context, MD_REG, USE_MODE), f7 = \(memoidx : Nat, nrg : TMReg) @(TMREG_ASSIGN, nrg, SG_REG, @(NAT2B32, memoidx)), f8 = \(z : TMState, rg : TMReg) @(SET_TMST_TMREG, z, rg) in

234

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

235

let p1 = GetVMKManTDetAxm, p2 = GetVMK2RVTDetAxm, p3 = VMCBGetAxm, p4 = GetVMCBMmIdxAxm, p5 = GetVMCBIntCxAxm, p6 = @(TMRegAssignAxm, MD_REG, USE_MODE), p7 = \(memoidx : Nat) @(TMRegAssignAxm, SG_REG, @(NAT2B32, memoidx)), p8 = SetTMRegTDetAxm in @(ZComp8FunThm, f1, f2, f3, f4, f5, f6, f7, f8, p1, p2, p3, p4, p5, p6, p7, p8);

10.6.8.8 Proof of SchedulVMTDetLem To prove SchedulVMTDetLem we will need the following two lemmas SchVMTimeDetLem1 and SchVMTimeDetLem2 dec SchVMTimeDetLem1 : let bf = \(z : TMState) let mn = @(GET_TMST_VMKMAN, z) in let old_vm_loc = @(GET_VMKMAN_RUNVM, mn), tts_vm_loc = @(GET_VMKMAN_TTSVM, mn), prq_vm_loc = @(GET_VMKMAN_PQUEVM, mn) in let new_vm_loc = @(GIF_THEN_ELSE, VMKLocation, @(EQ_VMKLOC, tts_vm_loc, NIL_VMKLOC), prq_vm_loc, tts_vm_loc) in @(NOT, @(EQ_VMKLOC, new_vm_loc, old_vm_loc)) in @(BFunTimeDetCond, bf); dec SchVMTimeDetLem2 : let f = \(z : TMState) let mn = @(GET_TMST_VMKMAN, z) in let old_vm_loc = @(GET_VMKMAN_RUNVM, mn), tts_vm_loc = @(GET_VMKMAN_TTSVM, mn), prq_vm_loc = @(GET_VMKMAN_PQUEVM, mn), ticks_numb = @(GET_VMKMAN_TICKCN, mn) in let new_vm_loc = @(GIF_THEN_ELSE, VMKLocation, @(EQ_VMKLOC, tts_vm_loc, NIL_VMKLOC), prq_vm_loc, tts_vm_loc) in let old_vm = @(VMCB_GET, z, old_vm_loc), new_vm = @(VMCB_GET, z, new_vm_loc) in let nmn = @(SET_VMKMAN_RUNVM, mn, new_vm_loc) in let nold_vm = @(SetVMCBLeaveTick, old_vm, OO) in let z0 = @(GIF_THEN_ELSE, TMState, @(IS_VMFIRSTRUN, @(GetVMCBStatus, new_vm)), @(SetVMVTickInt, new_vm_loc, ticks_numb, z), z), z1 = @(SET_TMST_VMKMAN, z0, nmn),

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

z2 = @(VMCB_SET, z1, old_vm_loc, nold_vm) in z2 in @(FunTimeDetCond, f);

10.6.8.9

Proof of SchVMTimeDetLem1

dec SchVMTDetLem11 : let f = \(tts_vm_loc : VMKLocation, prq_vm_loc : VMKLocation) @(GIF_THEN_ELSE, VMKLocation, @(EQ_VMKLOC, tts_vm_loc, NIL_VMKLOC), prq_vm_loc, tts_vm_loc) in @(N2FunTimeDetCond, f); dec SchVMTDetLem12 : let f = \(old_vm_loc : VMKLocation, new_vm_loc : VMKLocation) @(NOT, @(EQ_VMKLOC, new_vm_loc, old_vm_loc)) in @(NEqFunTDetCond, f); def SchVMTDetLem12 = let f1 = \(old_vm_loc : VMKLocation, new_vm_loc : VMKLocation) @(EQ_VMKLOC, new_vm_loc, old_vm_loc), f2 = \(b : Bool) @(NOT, b) in let p1 = NatEqAxm, p2 = BoolNotAxm in @(CompFunN2BThm, f1, f2, p1, p2); def SchVMTimeDetLem1 = let f1 = \(z : TMState) @(GET_TMST_VMKMAN, z), f2 = \(mn : VMKManager) @(GET_VMKMAN_RUNVM, mn), f3 = \(mn : VMKManager) @(GET_VMKMAN_TTSVM, mn), f4 = \(mn : VMKManager) @(GET_VMKMAN_PQUEVM, mn), f5 = \(tts_vm_loc : VMKLocation, prq_vm_loc : VMKLocation) @(GIF_THEN_ELSE, VMKLocation, @(EQ_VMKLOC, tts_vm_loc, NIL_VMKLOC), prq_vm_loc, tts_vm_loc), f6 = \(old_vm_loc : VMKLocation, new_vm_loc : VMKLocation) @(NOT, @(EQ_VMKLOC, new_vm_loc, old_vm_loc)) in let p1 = GetVMKManTDetAxm, p2 = GetVMK2RVTDetAxm, p3 = GetVMK2TTSTDetAxm, p4 = GetVMK2PRQTDetAxm,

236

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

p5 = SchVMTDetLem11, p6 = SchVMTDetLem12 in @(BComp6FunThm, f1, f2, f3, f4, f5, f6, p1, p2, p3, p4, p5, p6);

10.6.8.10

Proof of SchVMTimeDetLem2

10.6.8.11

Proof of SchVMTDetLem21

dec SchVMTDetLem21 : let f = \(z : TMState) let mn = @(GET_TMST_VMKMAN, z) in let old_vm_loc = @(GET_VMKMAN_RUNVM, mn), tts_vm_loc = @(GET_VMKMAN_TTSVM, mn), prq_vm_loc = @(GET_VMKMAN_PQUEVM, mn), ticks_numb = @(GET_VMKMAN_TICKCN, mn) in let new_vm_loc = @(GIF_THEN_ELSE, VMKLocation, @(EQ_VMKLOC, tts_vm_loc, NIL_VMKLOC), prq_vm_loc, tts_vm_loc) in let old_vm = @(VMCB_GET, z, old_vm_loc), new_vm = @(VMCB_GET, z, new_vm_loc) in @(GIF_THEN_ELSE, TMState, @(IS_VMFIRSTRUN, @(GetVMCBStatus, new_vm)), @(SetVMVTickInt, new_vm_loc, ticks_numb, z), z) in @(FunTimeDetCond, f); dec SchVMTDetLem221 : let f = \(z0 : TMState) let mn = @(GET_TMST_VMKMAN, z0) in let tts_vm_loc = @(GET_VMKMAN_TTSVM, mn), prq_vm_loc = @(GET_VMKMAN_PQUEVM, mn) in @(GIF_THEN_ELSE, VMKLocation, @(EQ_VMKLOC, tts_vm_loc, NIL_VMKLOC), prq_vm_loc, tts_vm_loc) in @(NFunTimeDetCond, f); dec SchVMTDetLem212 : let f = \(new_vm_loc : VMKLocation, z : TMState) let mn = @(GET_TMST_VMKMAN, z) in let ticks_numb = @(GET_VMKMAN_TICKCN, mn) in let new_vm = @(VMCB_GET, z, new_vm_loc) in @(GIF_THEN_ELSE, TMState, @(IS_VMFIRSTRUN, @(GetVMCBStatus, new_vm)), @(SetVMVTickInt, new_vm_loc, ticks_numb, z),

237

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

z) in !(loc : VMKLocation) @(FunTimeDetCond, @(f, loc)); dec SchVMTDetLem2120 : let f = \(new_vm_loc : VMKLocation, new_vm : VMCB, ticks_numb : Nat, z : TMState) @(GIF_THEN_ELSE, TMState, @(IS_VMFIRSTRUN, @(GetVMCBStatus, new_vm)), @(SetVMVTickInt, new_vm_loc, ticks_numb, z), z) in !(new_vm_loc : VMKLocation, new_vm : VMCB, ticks_numb : Nat) @(FunTimeDetCond, @(f, new_vm_loc, new_vm, ticks_numb)); dec BSchVMTDetLem212 : !(new_vm : VMCB) let f = \(z : TMState) @(IS_VMFIRSTRUN, @(GetVMCBStatus, new_vm)) in @(BFunTimeDetCond, f); def BSchVMTDetLem212 = let f1 = \(vm : VMCB) @(GetVMCBStatus, vm), f2 = \(status : VMStatus) @(IS_VMFIRSTRUN, status) in let p1 = GetVMCBStatusAxm, p2 = IsFirstRunAxm in @(CompFunN22Thm, f1, f2, p1, p2); dec SetVMVTickIntLem : !(loc : VMKLocation, ticks : Nat) let f = \(z : TMState) @(SetVMVTickInt, loc, ticks, z) in @(FunTimeDetCond, f); def SchVMTDetLem2120 = \(new_vm_loc : VMKLocation, new_vm : VMCB, ticks_numb : Nat) let bf = \(z : TMState) @(IS_VMFIRSTRUN, @(GetVMCBStatus, new_vm)), f1 = \(loc : VMKLocation, ticks : Nat, z : TMState) @(SetVMVTickInt, loc, ticks, z), f2 = \(z : TMState) z in let bp = BSchVMTDetLem212, p1 = @(SetVMVTickIntLem, new_vm_loc, ticks_numb), p2 = IdentFunTDetLem in @(CondFunThm, bf, @(f1, new_vm_loc, ticks_numb), f2, @(bp, new_vm), p1, p2); def SchVMTDetLem212 = let f1 = \(z : TMState) @(GET_TMST_VMKMAN, z), f2 = \(mn : VMKManager) @(GET_VMKMAN_TICKCN, mn), f3 = \(new_vm_loc : VMKLocation, z : TMState) @(VMCB_GET, z, new_vm_loc),

238

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

f4 = \(new_vm_loc : VMKLocation, new_vm : VMCB, ticks_numb : Nat, z : TMState) @(GIF_THEN_ELSE, TMState, @(IS_VMFIRSTRUN, @(GetVMCBStatus, new_vm)), @(SetVMVTickInt, new_vm_loc, ticks_numb, z), z) in let p1 = GetVMKManTDetAxm, p2 = GetVMK2TICTDetAxm, p3 = VMCBGetAxm, p4 = SchVMTDetLem2120 in @(CompFunN42Thm, f1, f2, f3, f4, p1, p2, p3, p4); def SchVMTDetLem21 = let f1 = \(z0 : TMState) let mn = @(GET_TMST_VMKMAN, z0) in let old_vm_loc = @(GET_VMKMAN_RUNVM, mn), tts_vm_loc = @(GET_VMKMAN_TTSVM, mn), prq_vm_loc = @(GET_VMKMAN_PQUEVM, mn) in @(GIF_THEN_ELSE, VMKLocation, @(EQ_VMKLOC, tts_vm_loc, NIL_VMKLOC), prq_vm_loc, tts_vm_loc), f2 = \(new_vm_loc : VMKLocation, z : TMState) let mn = @(GET_TMST_VMKMAN, z) in let ticks_numb = @(GET_VMKMAN_TICKCN, mn) in let new_vm = @(VMCB_GET, z, new_vm_loc) in @(GIF_THEN_ELSE, TMState, @(IS_VMFIRSTRUN, @(GetVMCBStatus, new_vm)), @(SetVMVTickInt, new_vm_loc, ticks_numb, z), z) in let p1 = SchVMTDetLem221, p2 = SchVMTDetLem212 in @(CompFunN20Thm, f1, f2, p1, p2);

10.6.8.12

Proof of SchVMTDetLem22

dec SchVMTDetLem22 : let f = \(z0 : TMState, z : TMState) let mn = @(GET_TMST_VMKMAN, z0) in let tts_vm_loc = @(GET_VMKMAN_TTSVM, mn), prq_vm_loc = @(GET_VMKMAN_PQUEVM, mn), ticks_numb = @(GET_VMKMAN_TICKCN, mn) in let new_vm_loc = @(GIF_THEN_ELSE, VMKLocation, @(EQ_VMKLOC, tts_vm_loc, NIL_VMKLOC), prq_vm_loc, tts_vm_loc) in let nmn = @(SET_VMKMAN_RUNVM, mn, new_vm_loc) in

239

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

@(SET_TMST_VMKMAN, z, nmn) in !(z0 : TMState) @(FunTimeDetCond, @(f, z0));

10.6.8.13

Proof of SchVMTDetLem221

dec SchVMTDetLem2210 : let f = \(tts_vm_loc : VMKLocation, prq_vm_loc : VMKLocation) @(GIF_THEN_ELSE, VMKLocation, @(EQ_VMKLOC, tts_vm_loc, NIL_VMKLOC), prq_vm_loc, tts_vm_loc) in @(N2FunTimeDetCond, f); def SchVMTDetLem221 = let f1 = \(z0 : TMState) @(GET_TMST_VMKMAN, z0), f2 = \(mn : VMKManager) @(GET_VMKMAN_TTSVM, mn), f3 = \(mn : VMKManager) @(GET_VMKMAN_PQUEVM, mn), f4 = \(tts_vm_loc : VMKLocation, prq_vm_loc : VMKLocation) @(GIF_THEN_ELSE, VMKLocation, @(EQ_VMKLOC, tts_vm_loc, NIL_VMKLOC), prq_vm_loc, tts_vm_loc) in let p1 = GetVMKManTDetAxm, p2 = GetVMK2TTSTDetAxm, p3 = GetVMK2PRQTDetAxm, p4 = SchVMTDetLem2210 in @(CompFunN41Thm, f1, f2, f3, f4, p1, p2, p3, p4);

10.6.8.14

Proof of SchVMTDetLem222

dec SchVMTDetLem222 : let f = \(new_vm_loc : VMKLocation, z0 : TMState, z : TMState) let mn = @(GET_TMST_VMKMAN, z0) in let nmn = @(SET_VMKMAN_RUNVM, mn, new_vm_loc) in @(SET_TMST_VMKMAN, z, nmn) in !(loc : VMKLocation, z0 : TMState) @(FunTimeDetCond, @(f, loc, z0)); def SchVMTDetLem222 = let f1 = \(z0 : TMState) @(GET_TMST_VMKMAN, z0), f2 = \(mn : VMKManager, new_vm_loc : VMKLocation)

240

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

@(SET_VMKMAN_RUNVM, mn, new_vm_loc), f3 = \(z : TMState, nmn : VMKManager) @(SET_TMST_VMKMAN, z, nmn) in let p1 = GetVMKManTDetAxm, p2 = SetVMK2RVTDetAxm, p3 = SetVMKManTDetAxm in @(MNComp31FunThm, f1, f2, f3, p1, p2, p3); def SchVMTDetLem22 = let f1 = \(z0 : TMState) let mn = @(GET_TMST_VMKMAN, z0) in let tts_vm_loc = @(GET_VMKMAN_TTSVM, mn), prq_vm_loc = @(GET_VMKMAN_PQUEVM, mn) in @(GIF_THEN_ELSE, VMKLocation, @(EQ_VMKLOC, tts_vm_loc, NIL_VMKLOC), prq_vm_loc, tts_vm_loc), f2 = \(new_vm_loc : VMKLocation, z0 : TMState, z : TMState) let mn = @(GET_TMST_VMKMAN, z0) in let nmn = @(SET_VMKMAN_RUNVM, mn, new_vm_loc) in @(SET_TMST_VMKMAN, z, nmn) in let p1 = SchVMTDetLem221, p2 = SchVMTDetLem222 in @(CompFunN21Thm, f1, f2, p1, p2);

10.6.8.15

Proof of SchVMTDetLem23

dec SchVMTDetLem23 : let f = \(z0 : TMState, z : TMState) let mn = @(GET_TMST_VMKMAN, z0) in let old_vm_loc = @(GET_VMKMAN_RUNVM, mn) in let old_vm = @(VMCB_GET, z0, old_vm_loc) in let nold_vm = @(SetVMCBLeaveTick, old_vm, OO) in @(VMCB_SET, z, old_vm_loc, nold_vm) in !(z0 : TMState) @(FunTimeDetCond, @(f, z0)); def SchVMTDetLem23 = let f1 = \(z0 : TMState) @(GET_TMST_VMKMAN, z0), f2 = \(mn : VMKManager) @(GET_VMKMAN_RUNVM, mn), f3 = \(old_vm_loc : VMKLocation, z0 : TMState) @(VMCB_GET, z0, old_vm_loc), f4 = \(old_vm : VMCB) @(SetVMCBLeaveTick, old_vm, OO), f5 = \(old_vm_loc : VMKLocation, nold_vm : VMCB, z : TMState) @(VMCB_SET, z, old_vm_loc, nold_vm) in let p1 = GetVMKManTDetAxm,

241

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

p2 = GetVMK2RVTDetAxm, p3 = VMCBGetAxm, p4 = @(SetVMCBLvTickAxm, OO), p5 = VMCBSetAxm in @(Comp5FunThm, f1, f2, f3, f4, f5, p1, p2, p3, p4, p5);

10.6.8.16

Proof of SchVMTDetLem2

def SchVMTimeDetLem2 = let f1 = \(z : TMState) let mn = @(GET_TMST_VMKMAN, z) in let old_vm_loc = @(GET_VMKMAN_RUNVM, mn), tts_vm_loc = @(GET_VMKMAN_TTSVM, mn), prq_vm_loc = @(GET_VMKMAN_PQUEVM, mn), ticks_numb = @(GET_VMKMAN_TICKCN, mn) in let new_vm_loc = @(GIF_THEN_ELSE, VMKLocation, @(EQ_VMKLOC, tts_vm_loc, NIL_VMKLOC), prq_vm_loc, tts_vm_loc) in let old_vm = @(VMCB_GET, z, old_vm_loc), new_vm = @(VMCB_GET, z, new_vm_loc) in let nmn = @(SET_VMKMAN_RUNVM, mn, new_vm_loc) in let nold_vm = @(SetVMCBLeaveTick, old_vm, OO) in @(GIF_THEN_ELSE, TMState, @(IS_VMFIRSTRUN, @(GetVMCBStatus, new_vm)), @(SetVMVTickInt, new_vm_loc, ticks_numb, z), z), f2 = \(z0 : TMState, z : TMState) let mn = @(GET_TMST_VMKMAN, z0) in let tts_vm_loc = @(GET_VMKMAN_TTSVM, mn), prq_vm_loc = @(GET_VMKMAN_PQUEVM, mn), ticks_numb = @(GET_VMKMAN_TICKCN, mn) in let new_vm_loc = @(GIF_THEN_ELSE, VMKLocation, @(EQ_VMKLOC, tts_vm_loc, NIL_VMKLOC), prq_vm_loc, tts_vm_loc) in let nmn = @(SET_VMKMAN_RUNVM, mn, new_vm_loc) in @(SET_TMST_VMKMAN, z, nmn), f3 = \(z0 : TMState, z : TMState) let mn = @(GET_TMST_VMKMAN, z0) in let old_vm_loc = @(GET_VMKMAN_RUNVM, mn) in let old_vm = @(VMCB_GET, z0, old_vm_loc) in let nold_vm = @(SetVMCBLeaveTick, old_vm, OO) in @(VMCB_SET, z, old_vm_loc, nold_vm) in let p1 = SchVMTDetLem21, p2 = SchVMTDetLem22, p3 = SchVMTDetLem23 in

242

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

243

@(Comp31FunThm, f1, f2, f3, p1, p2, p3);

10.6.8.17

Proof of SchedulVMTDetLem

def SchedulVMTDetLem = let bf = \(z : TMState) let mn = @(GET_TMST_VMKMAN, z) in let old_vm_loc = @(GET_VMKMAN_RUNVM, mn), tts_vm_loc = @(GET_VMKMAN_TTSVM, mn), prq_vm_loc = @(GET_VMKMAN_PQUEVM, mn) in let new_vm_loc = @(GIF_THEN_ELSE, VMKLocation, @(EQ_VMKLOC, tts_vm_loc, NIL_VMKLOC), prq_vm_loc, tts_vm_loc) in @(NOT, @(EQ_VMKLOC, new_vm_loc, old_vm_loc)), f1 = \(z : TMState) let mn = @(GET_TMST_VMKMAN, z) in let old_vm_loc = @(GET_VMKMAN_RUNVM, mn), tts_vm_loc = @(GET_VMKMAN_TTSVM, mn), prq_vm_loc = @(GET_VMKMAN_PQUEVM, mn), ticks_numb = @(GET_VMKMAN_TICKCN, mn) in let new_vm_loc = @(GIF_THEN_ELSE, VMKLocation, @(EQ_VMKLOC, tts_vm_loc, NIL_VMKLOC), prq_vm_loc, tts_vm_loc) in let old_vm = @(VMCB_GET, z, old_vm_loc), new_vm = @(VMCB_GET, z, new_vm_loc) in let nmn = @(SET_VMKMAN_RUNVM, mn, new_vm_loc) in let nold_vm = @(SetVMCBLeaveTick, old_vm, OO) in let z0 = @(GIF_THEN_ELSE, TMState, @(IS_VMFIRSTRUN, @(GetVMCBStatus, new_vm)), @(SetVMVTickInt, new_vm_loc, ticks_numb, z), z), z1 = @(SET_TMST_VMKMAN, z0, nmn), z2 = @(VMCB_SET, z1, old_vm_loc, nold_vm) in z2, f2 = \(z : TMState) z in let bp = SchVMTimeDetLem1, p1 = SchVMTimeDetLem2, p2 = IdentFunTDetLem in @(CondFunThm, bf, f1, f2, bp, p1, p2);

10.6.8.18 Proof of ScheduleFunLem2 ScheduleFunLem2 is proved using Comp3FunThm on SaveContxTDetLem, SchedulVMTDetLem, and SwitContxTDetLem.

CHAPTER 10. FORMAL DETERMINISTIC ANALYSIS OF SVMK

244

def ScheduleFunLem2 = @(Comp3FunThm, SAVE_CONTEXT, SCHEDULE_VM, SWITCH_CONTEXT, SaveContxTDetLem, SchedulVMTDetLem, SwitContxTDetLem);

10.6.8.19 Proof of SCHROInstTDetThm We finally reach the goal of proving the theorem SCHROInstTDetThm using the lemmas ScheduleBoolLem, ScheduleFunLem1 and ScheduleFunLem2 with the assistance of CondFunThm. def SCHROInstTDetThm = \(r : Nat, s : Nat, t : Nat) let bf = \(z : TMState) let rg = @(GET_TMST_TMREG, z) in @(IS_USE_MODE, @(TMREG_RETRIEVE, rg, MD_REG)), f1 = \(z : TMState) @(ERR_TMSTATE, z), f2 = \(z : TMState) let z1 = @(SAVE_CONTEXT, z), z2 = @(SCHEDULE_VM, z1), z3 = @(SWITCH_CONTEXT, z2) in z3 in let bp = ScheduleBoolLem, p1 = ScheduleFunLem1, p2 = ScheduleFunLem2 in @(CondFunThm, bf, f1, f2, bp, p1, p2);

The approach deployed here can be applied to all the kernel-related instructions defined in this report.

Part IV

Epilogue

245

Chapter 11

Related Works In [Kle08, Kle09, TKH05] Gerwin Klein has made a deep survey on current activities and status of formal verification for operating systems. The Table 11.1 is a list of the operating system verification projects in the past several decades. The Table 11.1 gives a condensed overview of the projects surveyed. The first two columns after the name of the project contain the highest and lowest levels of verification artifacts the project considers. They usually correspond to the terms Specification and Model of the verification. The next two columns detail what percentage of the specification artifacts in the project have been completed, and how much of the proofs are estimated to be discharged. The sixth column gives the main theorem proving tool used. The penultimate column contains one or two key phrases indicating the approach used, and the last column indicates when the project took place. Years in parentheses are estimated completion dates. • The first three projects in The Table 11.1, UCLA Secure Unix, PSOS, and KIT, concern early work in the 1970s and 1980s. While they pioneered the field and all finished successfully in their way, none of them produced a realistic OS kernel with full implementation proofs. • The next two projects in the table are recent, smaller-scale efforts that have made significant contributions. The first one, VFiasco, is a project at TU Dresden, Germany, and RU Nijmegen in the Netherlands. The second project, the verification of the Coyotos kernel, has unfortunately been cut short. • The last two projects are larger-scale efforts and have made substantial progress towards the goal of a realistic, fully verified OS kernel. At the time of writing, they are expected to complete their proofs in 2008. They differ in approach and main focus, but they also share a large portion of their verification technology. 246

CHAPTER 11. RELATED WORKS

Project

Highest Level

UCLA Security Unix PSOS

Security Model Application Level Isolated Tasks Does Not Crash Security Model Application Level Security Model

KIT VFiasco/ Rodin EROS/ Coyotos Verisoft L4.verified

247

Lowest Level

Specs

Proofs

Prover

Approach

Year

Pascal

90%

20%

XIVUS

Alphard

(?)-1980

Source Code Assembly

17 Layer 100%

0%

SPECIAL

HDM

1973-1983

100%

C++

70%

0%

BoyerMoore PVS

BitC

Security Model 100%

0%

ACL2(?)

75%

Isabelle

100%

70%

Isabelle

Interpreter Equivalence Semantic Compiler Language Based Fully Pervasive Performance Production Code

Gate Level C/ Assembly

(?)-1987 2001-2008 2004-(?) 2004(2008) 2005(2008)

Table 11.1: OS Verification Projects

The table does not include any currently commercially available OS kernels, because none have been formally verified to the degree discussed here. Three popular ones, Trusted Solaris, Windows NT, and SELinux (Red Hat Enterprise Linux 4.1) have been certified to Common Criteria EAL 4, but this level does not require any formal modeling and is not designed for systems deployed in potentially hostile situations. However, the security policies of SELinux have undergone formal analysis[ALP03]; in one instance using TAME[Arc06, Arc00, AHR00], which is based on the PVS prover[ORR+ 96], and in another instance by a different group using model checking[GHRS05]. The security framework is based on the Flask architecture[SSL+ 99] which was originally developed on the Fluke microkernel[FHL+ 96] and later ported by the NSA to Linux as the security architecture in SELinux. The two projects analyzed the security policies themselves, but did not aim at proofs establishing that the the SELinux kernel correctly implements them. Green Hill’s Integrity OS kernel has completed the EAL 6+ certification in November of 2008. EAL 6 does involve formal modeling, but only semi-formal treatment of the high-level design and below. Not much is publicly available about the certification effort at this time, but the + in EAL 6+ may mean that a formal information flow analysis on the C source code level being conducted. The theorem prover they were using is ACL2. Of the projects in Table 11.1, only the seL4 kernel[DEK+ 06] analyzed in L4.verified is targeted at the commercial market.

11.1

KIT

KIT is a small operating system kernel written for a uni-processor computer with a simple von Neumann architecture[Bev87]. KIT stands for kernel for isolated tasks, which is the main service that KIT provides. In addition, KIT provides access to asynchronous I/O devices, exception handling, and single-

CHAPTER 11. RELATED WORKS

248

word message passing. It does not provide shared memory or virtual memory in the modern sense. It also does not offer the dynamic creation of processes or communication channels, or services such as file systems. The implementation language is an artificial, but realistic assembler instruction set. With 620 lines of assembler source code and 300 lines of actual assembler instructions the kernel is extremely small and purposely very simple. It is several orders of magnitude smaller and less complex than modern microkernels. KIT is significant because it is the first kernel that fully deserves the attribute formally verified. Despite its simplicity, it provides a useful service, formally verified down to realistic assembly source code. Bevier is the first to demonstrate conclusively that the level of detail required in OS implementation verification is not an intrinsic problem for formal verification. The verification was conducted in the Boyer-Moore theorem prover[BM88], the predecessor of the ACL2 prover that was also used in the verification of the AAMP7 microprocessor. The syntax of the prover has been criticized as hard to read because of its parenthesized prefix form that is derived from the programming language LISP. In fact, the Boyer-Moore logic itself is very similar to pure LISP. The logic provides no explicit quantifiers like ∀ and ∃. One of the prover’s major advantages is that the logic is efficiently executable. The prover provides a high degree of automation for an interactive system. Very similar to UCLA Secure Unix and other refinement-based verifications, the proof of the KIT system shows correspondence between finite state machines. In this case, there are three such finite state machines: the abstract, operational specification, the ‘abstract kernel’, and the kernel running on hardware. • The kernel running on hardware is realized as an operational semantics of the assembler instructions: The states of the state machine are the hardware machine states, including its memory, registers, flags and program counter; the transitions describe the fetch-execute cycle of the machine. The restrictions of the Boyer-Moore logic make it necessary to reformulate it slightly to avoid an existential quantifier, but the content of the statement remains the same. • The medium level specification, i.e. the abstract kernel, defines a scheduling algorithm for a fixed number of tasks, implements the communication primitives (including the delay of tasks which block on a communication), and handles communication with asynchronous devices. • The abstract, top-level specification defines the communication transitions in which a task may engage, but says nothing about how tasks are scheduled. This abstract specification effectively provides a model of several communicating tasks running concurrently. The correspondence proof shows that the kernel correctly implements this abstraction on a single CPU.

CHAPTER 11. RELATED WORKS

249

There is no specific security model that KIT implements, but the top-level specification seems strong enough to at least imply data separation between processes. Bevier and Smith later also produced a formalization of the Mach microkernel[BS93a], [BS93b]. They did not proceed to implementations proofs, though. After KIT, more than a decade passed without any larger-scale, serious attempts at formally verifying the implementation of an operating system. UCLA Secure Unix, PSOS and KIT had shown that it was possible in principle, and had pioneered some of the techniques that could be employed, but the systems that were implemented were either unrealistically small like KIT, or were slow and/or incompletely verified like PSOS and UCLA Secure Unix. Formal verification on the required scale seemed prohibitively expensive, and machine support not yet sufficiently advanced.

11.2

Formal Models of Operating System Kernels in Z and Object-Z

In [Cra06, Cra07], Craig has made a effort on formal modeling of operating system kernels in Z and Object-Z. In his first book[Cra06], The formal models of three operating systems have been presented. All three kernels are intended for use on uni-processor systems.

11.2.1

A Simple Kernel

The first model is of a simple kernel of the kind often encountered in real-time and embedded systems. The system has no kernel interface and does not include such things as ISRs and device drivers. The user of this kernel is expected to provide these components on a per-application basis. This is common for such systems because the devices to which they are connected are not specified and are expected to vary among applications. The first kernel can be viewed as a kind of existence proof. It shows that it is possible to produce a formal model of an operating system kernel.

11.2.2

A Swapping Kernel

The second kernel is for a general-purpose system. The model includes a number of device drivers, in particular a clock process that is central to the processswapping mechanism. The kernel uses semaphores for synchronization and as the basic inter-process communication mechanism (here, shared memory). The kernel uses a time-based mechanism for multiplexing main store between processes; the kernel supports more processes than can be simultaneously maintained in main store. A storage-management subsystem is also provided to manage main store. It does so in a fairly rudimentary fashion, based upon

CHAPTER 11. RELATED WORKS

250

the allocation of relatively large chunks of store for each process. The framework contains the proofs of many kernel properties, and includes a proof of the correctness of the model for semaphores. The second kernel is of approximately the complexity of kernels such as those built by Digital Equipment for the excellent operating systems running its PDP11 series of minicomputers in the 1970s. It is of approximately the complexity of the kernel of Tannenbaum’s Minix [30] system (minus signals, file system and terminal interface).

11.2.3

Messages Passing in the Swapping Kernel

The third kernel is not presented in its entirety. It is a variation on the second one. The two differ in that the third uses message passing for IPC. The messagepassing primitives are modeled, as is a generic ISR based on the use of messages for the unblocking of drivers. All communication and synchronization in this kernel is based upon synchronous message exchange. The various device drivers and the process-swapping subsystem are outlined as message-passing processes. A kernel interface is also outlined. The interface implements system calls as messages and a library of system calls is presented. The chapter contains a number of proofs of properties of the message-passing mechanisms and also contains a proof that only one process can be in the kernel at any one time.

11.2.4

Virtual Storage

The final exercise is in the modeling of virtual storage. This was included because many systems today use virtual store for system and user processes. There are issues in the construction of virtual storage systems that are not covered in detail in standard textbooks (they must be confronted without much support from the literature). In a sense, it is necessary to have virtual store in order to construct it. Virtual storage affords a number of benefits including automatic storage management at the page level, management of large address spaces and support for more processes than will simultaneously fit into main store without having to resort to the all-or-nothing techniques exemplified by the swapping mechanisms in the previous kernels. Message passing is also assisted by virtual storage, as is device-independent I/O.

11.2.5

A Separation Kernel

In Craig’s second book[Cra07], the specification and refinement of a Separation Kernel is presented. This is a type of kernel that was specifically designed for cryptographic and other secure applications.

CHAPTER 11. RELATED WORKS

11.3

251

Abstract Interrupt Machine

In [FSDG08] a novel framework for certifying low-level programs involving both interrupts and preemptive threads is presented. A new abstract interrupt machine to capture “interrupt-aware” concurrency, and use simple ownershiptransfer semantics to reason about the interaction among interrupt handlers, context switching, and synchronization libraries is introduced. The work has made the following contributions: • This is perhaps the first program logic founded that can successfully certify the correctness of low-level programs involving both interrupts and concurrency. The idea is to use ownership-transfer semantics to model interrupts in both novel and general (since it also works in the concurrent setting). The logic supports modular verification: threads and handlers can be certified in the same way as to certify sequential code without worrying about possible interleaving. Soundness of the logic is formally proved in the COQ proof assistant. • Following separation logic’s local-reasoning idea, the program logic presented also enforces partitions of resources between different threads and between threads and interrupt handlers. These logical partitions at different program points essentially give an abstract formalization of the semantics of interrupts and the interaction between handlers and threads. • The AIM machine unifies both the preemptive and non-preemptive threading models, and is the first to successfully formalize concurrency with explicit interrupt handlers. In AIM, operations that manipulates thread queues are treated as primitives; These operations, together with the scheduler and context-switching code, are strictly sequential thus can be certified in a simpler logic. • Synchronization operations can be implemented as subroutines in AIM.

11.4

Idaho Partitioning Machine

The Idaho Partitioning Machine (IPM)[AFOM+ 02] is a simple machine model that supports execution of multiple independent partitions, providing security through data separation and controlled information flow. This model has been used to formally prove properties about the partitioning system; specifically, it has been used to prove that the memory partitions cannot interfere with each other unless they have been given specific permission to do so. The model is written in ACL2, a formal proof language that runs on top of Common Lisp. This language allows the processor model to be coded once; the code can then be used to both verify the correct operation of the model, and to formally “reason” about the behavior of the model.

CHAPTER 11. RELATED WORKS

252

The Idaho Partitioning Machine uses a stack-based architecture. The model implements a small set of instructions which are complete enough to execute non-trivial programs while avoiding unnecessarily complex features which do not contribute to the goal of modeling a partitioning machine. The feature of the IPM which distinguishes it from conventional processors is the IPM’s support for partitioning. In the IPM, a partition refers to a complete run-time environment for a process which would typically run on dedicated hardware. The IPM allows multiple partitions to co-exist on one processor by using hardware enforced time sharing and memory access control mechanisms which prevent partitions from affecting each others execution, with the exception of explicitly allowed interaction through shared memory segments. A correctly implemented partitioning mechanism, as demonstrated by the IPM, allows multiple partitions to execute with the guarantee that no action by one partition can affect the state of another partition, even in the event of a software failure in one or both partitions.

Chapter 12

Conclusions 12.1

Formal Verification of Compilers and Operating Systems: The Same and Differences

12.1.1

What You Want To Prove

In compiler verification, only one thing you want to prove - the correctness of translation from high-level programming language to machine language. In operating system verification, however, there might be too many things you want to prove. In most cases, it is unclear what is the meaning of correctness of an operating system. The correctness of an operating system may contain too many meaning.

12.1.2

The Complexity of Abstraction

In compiler verification, we need to define the abstract syntax and semantics of both high-level programming language and machine language, sometimes, we may also need a third language as the intermediate language. In operating system verification, however, you may need, in mixture, many different abstraction level. For instance, the system service APIs are given as a high-level language and the interruption handling mechanism has to be given in machine level description. There is almost no way to describe the semantics of interruption in high-level language. However, if you want to describe the semantics of system service APIs together with the interruption, you have to deal with the compiler.

253

CHAPTER 12. CONCLUSIONS

12.1.3

254

Termination and Nontermination Problem

Any piece of code in a given compiler is always terminated. It means that a compiler would be started with a source program, and execution would terminate with a target machine program. However, as we all know, that the execution of most of operating systems is not terminated. They intended to execute indefinitely.

Bibliography [AFOM+ 02] J. Alves-Foss, P. O’Connell, J. Marshall, M. Benke, B. Rinker, and C. Taylor. The Idaho Partitioning Machine: A Study in a MILS Hardware Partitioning Kernel. Technical report, Center for Secure and Dependable Systems (CSDS) at the University of Idaho, CSDS, University of Idaho, Moscow, ID, USA, November 2002. [AHR00]

M. Archer, C. L. Heitmeyer, and E. Riccobene. Using TAME to prove invariants of automata models: Two case studies. In FMSP 00: Proceedings of the 3rd Workshop on Formal Methods in Software Practice, New York, NY, USA, 2000. ACM.

[ALP03]

M. Archer, E. Leonard, and M Pradella. Analyzing SecurityEnhanced Linux Policy Specifications. In POLICY 03: Proceedings of the 4th IEEE International Workshop on Policies for Distributed Systems and Networks, Washington, DC, USA, 2003. IEEE Computer Society.

[Arc00]

M. Archer. TAME: Using PVS strategies for special-purpose theorem proving. Annals of Mathematics and Artificial Intelligence, 29(1-4), 2000.

[Arc06]

M. Archer. Basing a Modelling Environment on a General Purpose Theorem Prover. Technical Report Technical Report NRL/MR/5546-06-8952, NRL, Washington, DC, USA, 2006.

[Bev87]

W. R. Bevier. A Verified Operating System Kernel. PhD thesis, University of Texas, Austin, 1987. ftp:ftp.cs.utexas.edu/pub/boyer/diss/bevier.pdf.

[BM88]

R. S. Boyer and J. S. Moore. A Computational Logic Handbook. Academic Press, Boston, MA, USA, 1988.

[BS93a]

W. R. Bevier and L. Smith. A Mathematical Model of the Mach Kernel: Atomic Actions and Locks. Technical Report 89, Computational Logic, Inc., Austin, TX, USA, 1993. 255

BIBLIOGRAPHY

256

[BS93b]

W. R. Bevier and L. Smith. A Mathematical Model of the Mach Kernel: Entities and Relations. Technical Report 88, Computational Logic, Inc., Austin, TX, USA, 1993.

[Cea86]

R. L. Constable and et al. Implementing Mathematics with the Nuprl Proof Development System. Prentice-Hall Inc., Englewood Cliffs, New Jersey, 1986.

[CH88]

T. Coquand and G. Huet. The calculus of constructions. Information and Computation, 76(2/3), 1988.

[Cra06]

Iain D. Craig. Formal Models of Operating System Kernels. Springer-Verlag, London, England, 2006.

[Cra07]

Iain D. Craig. Formal Refinement for Operating System Kernels. Springer-Verlag, London, England, 2007.

[DEK+ 06]

P. Derrin, K. Elphinstone, G. Klein, D. Cock, and M. M. T. Chakravarty. Running the manual: An approach to high-assurance microkernel development. In Proceedings of the ACM SIGPLAN Haskell Workshop, Portland, OR, USA, 2006.

[FHL+ 96]

B. Ford, M. Hibler, J. Lepreau, P. Tullmann, G. Back, and S. Clawson. Microkernels meet recursive virtual machines. In Proceedings of the Second Symposium on Operating Systems Design and Implementation (OSDI96), Seattle, WA, USA, 1996.

[FSDG08]

Xinyu Feng, Zhong Shao, Yuan Dong, and Yu Guo. Certifying Low-Level Programs with Hardware Interrupts and Preemptive Threads. In Proceedings of 2008 ACM SIGPLAN Conference on Programming Language Design and Implementation (PLDI’08), Tucson, Arizona, June 2008.

[GHRS05]

J. D. Guttman, A. L. Herzog, J. D. Ramsdell, and C. W. Skorupka. Verifying information flow goals in security-enhanced Linux. Journal of Computer Security, 13(1), 2005.

[GMW79]

M. Gordon, R. Milner, and C. Wadsworth. Edinburgh LCF. LNCS 78. Springer-Verlag, 1979.

[Kle08]

Gerwin Klein. Operating System Verification - An Overview. Technical Report NRL-955, NICTA, Sydney, Australia, Jun 2008.

[Kle09]

Gerwin Klein. Operating System Verification - An Overview. S¯ adhan¯ a, 34(1):27–69, February 2009.

[ML84]

P. Martin-L¨of. Intuitionistic Type Theory. Studies in Proof Theory, Vol. 1. Bibliopolis, Naples, 1984.

BIBLIOGRAPHY

257

[ORR+ 96]

S. Owre, S. Rajan, J. Rushby, N. Shankar, and M. Srivas. PVS: Combining specification, proof checking, and model checking. In R. Alur and T. Henzinger, editors, Computer Aided Verification, volume 1102 of Lecture Notes in Computer Science. SpringerVerlag, 1996.

[SSL+ 99]

R. Spencer, S. Smalley, P. Loscocco, M. Hibler, D. Andersen, and J. Lepreau. The Flask security architecture: system support for diverse security policies. In SSYM99: Proceedings of the 8th conference on USENIX Security Symposium, Berkeley, CA, USA, 1999. USENIX Association.

[TKH05]

H. Tuch, G. Klein, and G. Heiser. OS Verification - Now! In Proceedings of the 10th Workshop on Hot Topics in Operating Systems, Santa Fe, NM, USA, 2005. USENIX.

[Zhu89]

M.-Y. Zhu. AUTOSTAR – a software development system. ACM SIGPLAN Notices, 24(3), March 1989.

[ZW91]

M.-Y. Zhu and C.-W. Wang. A higher-order lambda calculus: PowerEpsilon. Technical report, Beijing Institute of Systems Engineering, Beijing, 1991.

[ZW92]

M.-Y. Zhu and C.-W. Wang. Program derivation in PowerEpsilon. In Proceedings of COMPSAC’92, Chicago, September 1992.

[ZW93a]

M.-Y. Zhu and C.-W. Wang. Decision making as theorem proving. Chinese Journal of Systems Engineering and Electronics, 4(1), 1993.

[ZW93b]

M.-Y. Zhu and C.-W. Wang. Mechanical synthesis of a matching algorithm in PowerEpsilon. Chinese Journal of Electronics, 2(1), 1993.

Index Π-elimination, 29 Π-formula, 16 Π-introduction, 29 Π-type, 29 Σ-elimination, 30 Σ-formula, 16 Σ-introduction, 30 Σ-type, 30 λ-abstraction, 14, 16 λ-expression, 26, 28 λ-expressions, 27, 28 AUTOSTAR, 13 Ada, 15 Algol 60, 27 C-VMK, 12 LCF, 13 LISP, 27 Nuprl, 13 POP-2, 27 Pascal, 15, 27 PowerEpsilon, 13–18, 21, 27–29, 36– 38, 41, 42 Calculus of Constructions, 13 Constructive logic, 37 Constructive mathematics, 13 Constructive proofs, 21 Curry-Howard Interpretation, 38 Isomorphism, 39 Domain, 39, 41–43 Recursive, 41 Domain constructors, 43 Domain equation, 43

Domain equations, 41, 43 Domains, 39–43 Finite, 42 Standard, 42 Existantial quantifier, 14 Existential quantification, 30 Fixed-point operators, 14 Functional programming language Polymorphic Strong-typed, 13 Higher-order Function, 26 Functions, 26, 27 Language, 27 Induction, 21 List, 22 Induction rules, 13 Inductive defined types, 13 Mathematical induction, 21 Meta-language, 13 Meta-variable, 15 Meta-variables, 15, 16 Proof checker, 13 Proof checkers, 13 Recursion List, 22 Type theory, 13, 21 Constructive, 38

258

INDEX

259

of Martin-L¨of, 13 Type universe hierarchies, 13 Universal Universal Universal Universal

generalization, 29 qualifier predicate, 16 quantification, 29 quantifier, 14