AMD amd64 architecture User Manual

Page of 336
76
General-Purpose Programming
AMD64 Technology
24592—Rev. 3.15—November 2009
3.6.1 Feature Detection in a Virtualized Environment
Software writers must assume that their software may be executed as a guest in a virtualized
environment. A virtualized guest may be migrated between processors of differing capabilities, so the
CPUID indication of a feature's presence must be respected. Operating systems, user programs and
libraries must all ensure that the CPUID instruction indicates a feature is present before using that
feature. The hypervisor is responsible for ensuring consistent CPUID values across the system.
For example, an OS, program, or library typically detects a feature during initialization and then
configures code paths or internal copies of feature indications based on the detection of that feature,
with the feature detection occurring once per initialization. In this case, the feature must be detected by
use of the CPUID instruction rather than by ignoring CPUID and testing for the presence of that
feature.
To ensure guest migration between processors across multiple generations of processors, while
allowing for features to be deprecated in future generations of processors, it is imperative that software
check the CPUID bit once per program or library initialization before using instructions that are
indicated by a CPUID bit; otherwise inconsistent behavior may result.
3.7
Control Transfers
3.7.1 Overview
From the application-program’s viewpoint, program-control flow is sequential—that is, instructions
are addressed and executed sequentially—except when a branch instruction (a call, return, jump,
interrupt, or return from interrupt) is encountered, in which case program flow changes to the branch
instruction’s target address. Branches are used to iterate through loops and move through conditional
program logic. Branches cause a new instruction pointer to be loaded into the rIP register, and
sometimes cause the CS register to point to a different code segment. The CS:rIP values can be
specified as part of a branch instruction, or they can be read from a register or memory.
Branches can also be used to transfer control to another program or procedure running at a different
privilege level. In such cases, the processor automatically checks the source program and target
program privileges to ensure that the transfer is allowed before loading CS:rIP with the new values.
3.7.2 Privilege Levels
The processor’s protected modes include legacy protected mode and long mode (both compatibility
mode and 64-bit mode). In all protected modes and virtual x86 mode, privilege levels are used to
isolate and protect programs and data from each other. The privilege levels are designated with a
numerical value from 0 to 3, with 0 being the most privileged and 3 being the least privileged. Privilege
0 is normally reserved for critical system-software components that require direct access to, and
control over, all processor and system resources. Privilege 3 is used by application software. The
intermediate privilege levels (1 and 2) are used, for example, by device drivers and library routines that
access and control a limited set of processor and system resources.