Skip to content
This repository was archived by the owner on Feb 23, 2021. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
109 commits
Select commit Hold shift + click to select a range
22e5945
core-image-efi-initramfs: remove unneeded components for UMIP
ricardon Dec 5, 2016
4697ab2
live-vm-common: hack: bloat boot partition with a useless file
ricardon Dec 7, 2016
201ea39
meta-luv: add recipe for User-Mode Instruction Prevention
ricardon Dec 5, 2016
c09d0be
luv-yocto-efi-test: add kernel selftests for UMIP
ricardon Jan 24, 2017
4216c16
meta-luv: add recipe for virtual-8086 mode kernel selftests
ricardon Mar 2, 2017
c644594
umip: umip_test2: correct print size of expected values
ricardon Mar 24, 2017
8e1cc5d
umip: umip_test2: cast shorts to unsigned longs
ricardon Mar 24, 2017
a6a4a31
umip: remove unused variables
ricardon Mar 24, 2017
3840b9f
umip: make main functions return an int
ricardon Mar 24, 2017
a0ef85c
umip: umip_test: remove unneeded function get_mask
ricardon Mar 24, 2017
1d7a3e1
umip: umip_test: utilize %p instead of %lx to print pointers
ricardon Mar 24, 2017
ab58bad
umip: umip_ldt_16: Fix warning about implicit declaration of syscall
ricardon Mar 24, 2017
baae348
umip: umip_ldt_64: fix printing of uninitialized variable
ricardon Mar 24, 2017
5a9b218
umip: rework INIT_VAL macro
ricardon Mar 24, 2017
951513c
umip: umip_test_gen_*: utilize a custom to-hex function
ricardon Mar 24, 2017
f241a7b
umip: umip_ldt_*: remove mmap MAP_32BIT option
ricardon Mar 25, 2017
4d3aae8
umip: umip_ldt_*: do not run tests from main
ricardon Mar 25, 2017
378fadd
umip: normal_pf: relocate page fault tests to its own function
ricardon Mar 28, 2017
db9ff11
umip: normal_pf: add support for SIGILL signal
ricardon Mar 28, 2017
4f2286e
umip: normal_pf: add tests for the LOCK prefix
ricardon Mar 28, 2017
064542f
umip: normal_pf: add tests for SGDT/SIDT with registers as operands
ricardon Mar 28, 2017
2503a7c
umip: normal_pf: test the use of null segment selectors
ricardon Mar 29, 2017
05781d1
umip: normal_pf: add tests for effective address outside of segment l…
ricardon Mar 30, 2017
15b7b98
linux-yocto-efi-test: Update UMIP tests
ricardon May 2, 2017
1bdecbe
umip: update README to refer to more exceptions
ricardon May 27, 2017
b8e1b85
umip: rename norma_pf artifacts to a more generic name
ricardon May 27, 2017
4154ab3
luv-efi: do not build BITS
ricardon Aug 2, 2017
edf238a
umip: update definitions of test result to include count
ricardon Aug 2, 2017
a41e3ad
umip: umip_test: update test program to count test cases
ricardon Aug 2, 2017
adf5e88
umip: umip_test2: use a long type for test mask with register operands
ricardon Aug 2, 2017
45a1126
umip: umip_test2: Print the complete expected result of tests
ricardon Aug 2, 2017
227581a
umip: umip_test2: do not abort execution on failed test cases
ricardon Aug 2, 2017
da0d119
umip: umip_test2: count and print number of test cases
ricardon Aug 2, 2017
b8507c1
umip: correc typo when printing siginfo address
ricardon Aug 2, 2017
7b34d04
umip: umip_exceptions: remove unused code
ricardon Aug 2, 2017
b8fc35b
umip: umip_exceptions: count number of failed and passed test cases
ricardon Aug 2, 2017
acaf4ed
umip: umip_exceptions: do not abort tests on failure
ricardon Aug 2, 2017
0776cea
umip: umip_exceptions: add static qualifier where needed
ricardon Aug 2, 2017
6076f55
umip: umip_exception: remove unused return values from test functions
ricardon Aug 2, 2017
40c44d7
umip: umip_exceptions: save a couple of lines
ricardon Aug 2, 2017
4ccbd2b
umip: umip_exception: fix a typo
ricardon Aug 2, 2017
cde04de
umip: umip_exceptions: rename test_normal_pf as test_pf
ricardon Aug 2, 2017
b950322
umip: umip_exceptions: add message to describe the purpose of the tests
ricardon Aug 2, 2017
715ebd0
umip: umip_exceptions: add more tests for unmapped address page faults
ricardon Aug 2, 2017
832014b
umip: definitions: add macros to print test results
ricardon Aug 2, 2017
503bdee
umip: 16-bit LDT tests: update code generator to count test cases
ricardon Aug 2, 2017
5884194
umip: 16-bit LDT tests: count the number of tests
ricardon Aug 2, 2017
994219e
umip: 32-bit LDT tests: remove unused definitions of expected values
ricardon Aug 3, 2017
57016b5
umip: 32-bit LDT tests: update code generator to count test cases
ricardon Aug 3, 2017
7ea5ebb
umip: 32-bit LDT tests: count the number of tests
ricardon Aug 3, 2017
b1b697a
umip: 64-bit LDT tests: update code generator to count test cases
ricardon Aug 3, 2017
e97d2f8
umip: 64-bit LDT tests: count the number of tests
ricardon Aug 3, 2017
09b5141
umip: umip_ldt_64: Add a warning about segfault
ricardon Aug 3, 2017
dbf5e2c
umip: add utility library for common functionality
ricardon Aug 4, 2017
392feea
umip: use utility library to print test results
ricardon Aug 4, 2017
e3abfc7
umip: umip_test_defs: add a macro to initialize expected signals
ricardon Aug 4, 2017
616a343
umip: umip_utils: add a utility function to inspect received signals
ricardon Aug 4, 2017
a48cc24
umip: umip_test: inspect possible signals after running UMIP-protecte…
ricardon Aug 4, 2017
389c2fc
umip: umip_test: do not exit upon receiving a signal
ricardon Aug 4, 2017
070c13c
umip: umip_test2: allow each test case handle received signals
ricardon Aug 4, 2017
18e27cf
umip: umip_exceptions: use the NOP_SLED macro
ricardon Aug 5, 2017
6c29b70
umip: umip_exceptions: use existing signal inspection functions
ricardon Aug 5, 2017
3f290be
umip: umip_exceptions: correct increment of instruction pointer
ricardon Aug 5, 2017
b0f34d5
umip: unify signal-handling code
ricardon Aug 7, 2017
aea0f0b
umip: LDT tests: update test generators to optionally generate code f…
ricardon Aug 7, 2017
ac2e9c0
umip: Makefile: use CFLAGS when building
ricardon Aug 7, 2017
7033462
umip: umip_utils: build all programs using the new utility library
ricardon Aug 7, 2017
7a24f24
umip: build test programs for emulation of all UMIP-protected instruc…
ricardon Aug 7, 2017
ee7c8c2
umip: Makefile: add missing files when cleaning
ricardon Aug 7, 2017
51bb33b
umip: umip_test: rename as umip_test_basic
ricardon Aug 7, 2017
85e3307
umip: umip_test2: Rename as umip_test_opnds
ricardon Aug 7, 2017
9d8346e
umip: umip_utils: beautify print_results
ricardon Aug 7, 2017
d94f62b
umip: rewrite UMIP_README
ricardon Aug 7, 2017
4b79d1e
umip: update recipe for renamed source files
ricardon Aug 8, 2017
cb0324b
umip: LDT tests: move declaration of code and data segment memory to …
ricardon Aug 8, 2017
ab2aa4b
umip: Makefile: make emul_all targets depend on their minimal counter…
ricardon Aug 8, 2017
31e0960
umip: install the _emul_all variants
ricardon Aug 8, 2017
738a6e6
umip: umip_utils: improve signal handling
ricardon Aug 10, 2017
d0804b8
umip: umip_test_opnds: correct local variable access due to unbalance…
ricardon Aug 10, 2017
eb44f40
umip: umip_test_opnd: use a scratch register in memory tests
ricardon Aug 11, 2017
43385b3
umip: umip_test_opnds: correct local variable access due to unbalance…
ricardon Aug 11, 2017
91e516c
umip: umip_test_opnds: print test results with the correct size
ricardon Aug 11, 2017
9f7dbbc
umip: umip_test_opnds: print initialization value
ricardon Aug 12, 2017
a10095f
umip: umip_test_opnds: print correct expected value
ricardon Aug 12, 2017
a6f4804
umip: definitions: update expected return value of SMSW
ricardon Aug 14, 2017
4ae9b93
umip: use 64-bit variables for expected results
ricardon Aug 14, 2017
1fd36cc
umip: umip_test_basic: correct test result verification to 16-bit only
ricardon Aug 14, 2017
db81cfc
umip: umip_ldt_16: use labels for inline asm arguments
ricardon Aug 15, 2017
7e62263
umip: use -fno-omit-frame-pointer
ricardon Aug 15, 2017
707a0b5
umip: umip_exceptions: make page-fault tests check for SI_KERNEL code
ricardon Aug 16, 2017
336778d
umip: umip_exceptions: initialize signal number and code before test
ricardon Aug 16, 2017
82cfc22
umip: umip_test_opnds: use SIGSEGV/SI_KERNEL for str and sldt
ricardon Aug 16, 2017
46af992
umip: umip_utils: use exit_on_signal codes to determine test status
ricardon Aug 16, 2017
d86efbb
umip: umip_ldt_64: set exit on signal as passed test case
ricardon Aug 16, 2017
c68e564
umip: umip_*: add support for command line arguments
Aug 23, 2017
33ec321
umip_ldt_64: utilize ARCH_SET_FS/GS syscalls correctly
ricardon Oct 10, 2017
8ad4700
umip: umip_utils.c: Solve one compile warning "type of 'exp_signum' d…
Sep 15, 2017
25ee12c
umip: umip_exceptions.c: Solve one warning: should void test_addresse…
Sep 15, 2017
04cc0b3
umip_utils: add a cleanup function for exit on signal
ricardon Oct 10, 2017
578e7f0
umip_ldt_64: implement a cleanup function for the signal handler
ricardon Oct 10, 2017
840bb1e
umip: Makefile: add -m32 to compile 32bit and 16bit .o and program
Oct 11, 2017
66c8e15
umip: remove -m32 when building via bitake
ricardon Oct 20, 2017
999e5c5
umip_ldt_64: preserve %r[8-15] registers
ricardon Oct 20, 2017
c5c0973
umip_ldt_64: remove unneeded arguments in test prep code
ricardon Oct 20, 2017
2cb5c59
umip: README: Start a list of things to do.
ricardon Oct 20, 2017
db28046
umip: umip_ldt_16/32: Initialize segment memory correctly
ricardon Nov 9, 2017
b4fb29e
luv-efi: do not include BITS ramdisk when not building bits
ricardon Nov 17, 2017
2ea5803
umip: Add a tool to dump CPUID leaves
ricardon Jun 2, 2018
fbb0266
umip: umip_utils.c: Avoid umip infinite loop in some abnormal situation
Oct 19, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions meta-luv/classes/luv-efi.bbclass
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def extra_initrd(d):

target = d.getVar('TARGET_ARCH', True)
if re.search('86', target):
return '/boot/bitsrd'
return ''
else:
return ''

Expand Down Expand Up @@ -85,9 +85,10 @@ efi_populate() {
install -m 0644 ${DEPLOY_DIR_IMAGE}/${EFI_LOADER_IMAGE} ${DEST}${EFIDIR}
fi

if echo "${TARGET_ARCH}" | grep -q "i.86" || [ "${TARGET_ARCH}" = "x86_64" ]; then
efi_populate_bits ${DEST}
fi
# TODO: only populate bits if present in features
#if echo "${TARGET_ARCH}" | grep -q "i.86" || [ "${TARGET_ARCH}" = "x86_64" ]; then
# efi_populate_bits ${DEST}
#fi

# Install splash and grub.cfg files into EFI directory.
install -m 0644 ${GRUBCFG} ${DEST}${EFIDIR}
Expand Down
19 changes: 9 additions & 10 deletions meta-luv/recipes-core/images/core-image-efi-initramfs.bb
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,18 @@ DESCRIPTION = "Small image capable of booting a device and running the suite of
EFI tests."

IMAGE_INSTALL = "\
base-files base-passwd netbase udev systemd luv-test-manager \
luv-test-crash luv-test-netconsole luv-test keymaps \
kernel-image fwts bash coreutils gawk grep util-linux-agetty \
util-linux-mount util-linux-umount kmod sed tar net-tools \
shadow util-linux procps efivarfs-test \
plymouth plymouth-set-default-theme kernel-efi-warnings linux-firmware kexec \
base-files base-passwd udev systemd \
keymaps \
kernel-image bash coreutils grep util-linux-agetty \
util-linux-mount util-linux-umount kmod \
shadow util-linux procps \
plymouth plymouth-set-default-theme \
"

X86_ADDITIONS = "chipsec python-codecs python-subprocess vmcore-dmesg bits \
kernel-modules telemetrics"
X86_ADDITIONS = ""

IMAGE_INSTALL_append_qemux86 = "${X86_ADDITIONS}"
IMAGE_INSTALL_append_qemux86-64 = "${X86_ADDITIONS} ndctl"
IMAGE_INSTALL_append_qemux86 = "${X86_ADDITIONS} vm86-test umip-tests"
IMAGE_INSTALL_append_qemux86-64 = "${X86_ADDITIONS} umip-tests lib32-umip-tests"

export IMAGE_BASENAME = "core-image-efi-initramfs"

Expand Down
339 changes: 339 additions & 0 deletions meta-luv/recipes-core/umip/files/COPYING

Large diffs are not rendered by default.

92 changes: 92 additions & 0 deletions meta-luv/recipes-core/umip/files/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
cpuid: CFLAGS += -fno-omit-frame-pointer
cpuid:
$(CC) $(CFLAGS) -o umip_cpuid cpuid.c

x86_64_minimal: CFLAGS += -fno-omit-frame-pointer
x86_64_minimal:
$(CC) $(CFLAGS) -c umip_utils.c -o umip_utils_64.o

$(CC) $(CFLAGS) -o umip_test_opnds_64 umip_utils_64.o umip_test_opnds.c
$(CC) $(CFLAGS) -o umip_test_basic_64 umip_utils_64.o umip_test_basic.c
$(CC) $(CFLAGS) -o umip_exceptions_64 umip_utils_64.o umip_exceptions.c

python umip_test_gen_64.py
$(CC) $(CFLAGS) -c test_umip_ldt_64.c
$(CC) $(CFLAGS) -c umip_ldt_64.c
$(CC) $(CFLAGS) -o umip_ldt_64 test_umip_ldt_64.o umip_ldt_64.o umip_utils_64.o

x86_64_emul_all: CFLAGS += -DEMULATE_ALL -fno-omit-frame-pointer
x86_64_emul_all: x86_64_minimal
$(CC) $(CFLAGS) -c umip_utils.c -o umip_utils_64.o

$(CC) $(CFLAGS) -o umip_test_opnds_64_emul_all umip_utils_64.o umip_test_opnds.c
$(CC) $(CFLAGS) -o umip_test_basic_64_emul_all umip_utils_64.o umip_test_basic.c
$(CC) $(CFLAGS) -o umip_exceptions_64_emul_all umip_utils_64.o umip_exceptions.c

python umip_test_gen_64.py --emulate-all
$(CC) $(CFLAGS) -c test_umip_ldt_64.c
$(CC) $(CFLAGS) -c umip_ldt_64.c
$(CC) $(CFLAGS) -o umip_ldt_64_emul_all test_umip_ldt_64.o umip_ldt_64.o umip_utils_64.o

x86_64: x86_64_minimal x86_64_emul_all cpuid

i686_minimal: CFLAGS += -fno-omit-frame-pointer -m32
i686_minimal:
$(CC) $(CFLAGS) -c umip_utils.c -o umip_utils_32.o

$(CC) $(CFLAGS) -o umip_test_opnds_32 umip_utils_32.o umip_test_opnds.c
$(CC) $(CFLAGS) -o umip_test_basic_32 umip_utils_32.o umip_test_basic.c
$(CC) $(CFLAGS) -o umip_exceptions_32 umip_utils_32.o umip_exceptions.c

python umip_test_gen_32.py
$(CC) $(CFLAGS) -c test_umip_ldt_32.c
$(CC) $(CFLAGS) -c umip_ldt_32.c
$(CC) $(CFLAGS) -o umip_ldt_32 test_umip_ldt_32.o umip_ldt_32.o umip_utils_32.o

python umip_test_gen_16.py
$(CC) $(CFLAGS) -c test_umip_ldt_16.c
$(CC) $(CFLAGS) -c umip_ldt_16.c
$(CC) $(CFLAGS) -o umip_ldt_16 test_umip_ldt_16.o umip_ldt_16.o umip_utils_32.o

i686_emul_all: CFLAGS += -DEMULATE_ALL -fno-omit-frame-pointer -m32
i686_emul_all: i686_minimal
$(CC) $(CFLAGS) -c umip_utils.c -o umip_utils_32.o

$(CC) $(CFLAGS) -o umip_test_opnds_32_emul_all umip_utils_32.o umip_test_opnds.c
$(CC) $(CFLAGS) -o umip_test_basic_32_emul_all umip_utils_32.o umip_test_basic.c
$(CC) $(CFLAGS) -o umip_exceptions_32_emul_all umip_utils_32.o umip_exceptions.c

python umip_test_gen_32.py --emulate-all
$(CC) $(CFLAGS) -c test_umip_ldt_32.c
$(CC) $(CFLAGS) -c umip_ldt_32.c
$(CC) $(CFLAGS) -o umip_ldt_32_emul_all test_umip_ldt_32.o umip_ldt_32.o umip_utils_32.o

python umip_test_gen_16.py --emulate-all
$(CC) $(CFLAGS) -c test_umip_ldt_16.c
$(CC) $(CFLAGS) -c umip_ldt_16.c
$(CC) $(CFLAGS) -o umip_ldt_16_emul_all test_umip_ldt_16.o umip_ldt_16.o umip_utils_32.o

i686: i686_minimal i686_emul_all cpuid
i586: i686

.PHONY: clean
clean:
rm -f *.o
rm -f umip_test_basic_64
rm -f umip_test_basic_64_emul_all
rm -f umip_test_basic_32
rm -f umip_test_basic_32_emul_all
rm -f umip_test_opnds_64
rm -f umip_test_opnds_64_emul_all
rm -f umip_test_opnds_32
rm -f umip_test_opnds_32_emul_all
rm -f umip_exceptions_64
rm -f umip_exceptions_64_emul_all
rm -f umip_exceptions_32
rm -f umip_exceptions_32_emul_all
rm -f umip_ldt_64
rm -f umip_ldt_64_emul_all
rm -f umip_ldt_32
rm -f umip_ldt_32_emul_all
rm -f umip_ldt_16
rm -f umip_ldt_16_emul_all
192 changes: 192 additions & 0 deletions meta-luv/recipes-core/umip/files/UMIP_README
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
A QUICK GUIDE FOR UMIP TESTING

Contents

I. For the impatient
II. What is UMIP and how is supported in the Linux kernel?
III. Testing UMIP
a) Overview
b) Testing full emulation
c) Testing 64-bit processes
d) Testing 32-bit processes
e) Testing output format
f) The test programs
g) Things to do

============================================================
I. For the impatient

If all you have is 10 seconds, all you need to know is this:

Assuming you have a 64-bit distro install, here is what you need to do:

1. If in Ubuntu:
$ sudo apt-get install ia32-libs
If in other distros, not sure; a similar package
2. $ make x86_64
3. $ CFLAGS=-m32 make i586
4. $ umip_test_basic_64
5. $ umip_test_basic_32
6. $ umip_test_opnds_64
7. $ umip_test_opnds_32
8. $ umip_exceptions_64
9. $ umip_exceptions_32
10. $ umip_ldt_64
11. $ umip_ldt_32
12. $ umip_ldt_16

For each of the steps 4 through 12, look for this output

RESULTS: passed[X], failed[0], errors[0].

You should have 0 failures and 0 errors.

You are done.

============================================================
II. What is UMIP and how is supported in the Linux kernel?

User-mode Instruction Prevention, UMIP is a feature present in new Intel
processors that prevents the execution of the instructions SGDT, SIDT, SLDT,
SMSW and STR while running in CLP>0. In such a case, a general protection fault
exception is issued.

Functionality has been put in the kernel to trap this general protection fault
exception. When this happens, the kernel provides to the caller dummy values
as the result for these instructions. However, emulation is not done in every
case. It is done only for 32-bit processes and only for the instructions SGDT,
SIDT and SMSW. For 64-bit processes no emulation is provideded. The instructions
STR and SLDT are not emulated in any case.

However, the Linux kernel can be patched to provide emulation in all cases.

============================================================
III. Testing UMIP

a) == Overview ===

I have written several programs to test the behavior described above. Each
program can be built for 32-bit and 64-bit processes. The makefile builds both
versions and adds _32 or _64 suffixes to the executable test programs.

b) == Achieving emulation for everything

Also, each program can be built to test emulation for all the instructions in
both 64 and 32-bits and for all the instructions. The makefile achieves this by
adding -DEMULATE_ALL to the CFLAGS; the python scripts that generate code are
run with the option --emulate-all. Test programs built with this configuration
are added the suffix _emul_all.

Hence, the naming convention for the test programs is:

test_program_32/64_[emul_all]

c) == Testing 64-bit processes

The makefile can the test programs for all these configurations.

To build the 64-bit test programs you can do

$ make x86_64

This will build the programs umip_test_basic, umip_test_opnds, umip_exceptions,
and umip_ldt_64; see section III.a) for the relevant naming convention.

In its default version, these programs will verify a general protection fault
is seen when executing the UMIP-protected instructions. In the _emul_all
version, programs will verify that emulation is successful and no exceptions are
generated in the process (please see the umip_exceptions special case below).

Both the default and _emul_all versions are built with the aforementioned
command.

d) == Testing 32-bit processes

In a 64-bit distro, you will need to install the 32-bit compatibility libraries.
In Ubuntu, this is done with:

$ sudo apt-get install ia32-libs

In other distros, a similar procedure can be followed.

Then, the 32-bit test programs can be built as:

$ CFLAGS=-m32 make i586

This will build the programs umip_test_basic, umip_test_opnds, umip_exceptions,
umip_ldt_32, and umip_ldt_16; see section III.a) for the relevant naming
convention.

In its default version, these programs will verify that emulation is successful
for the instructions SGDT, SIDT and SMSW. They will also verify that a general
proctection fault is seen for the instructions SLDT and STR.

Both the default and _emul_all versions are built with the aforementioned
commans.

e) == The testing output format

Test programs use the following output format

[info] To print information about a test case.
[pass] To inform that a test case passed.
[FAIL] To inform that a test case failed.

RESULTS: passed[X], failed[Y], error[Z]

Ideally, you should see all test case passed. This means that you should see
0 failures and 0 errors.

f) The test programs

Refer to section III.a) for the naming convention.

* umip_est_basic. Use umip_test for a very basic test that exercises the
instructions smsw, str, sidt, sldt and sgdt from protected mode using the
global descriptortable.

* umip_test_opnds. Use umip_test_opnds for a collection of tests that
exercises the instructions str, sldt and smsw for register and memory
operands. For registers, operand sizes are of 16 and 32 bits. Memory operands
are always 16-bits long. Addresses in these tests are computed using only the
ModRM byte. Also, these tests use the normal __USER_DS segment with a base
address of zero.

* umip_exceptions. Use umip_exceptions that the emulation code issues the
exceptions for each of the UMIP-instructions as described in the Intel
Software Development Manual. Priority of the exceptions should be that
mentioned in the Volume 3, Section 16.9 of the aforementioned manual. That is,
for instance, if the instructions can lead to a general protection fault
exception and an illegal operand exception, verify that the latter is seen.

* umip_ldt_64. Use umip_ldt_64 to verify all the possible 64-bit address
encodings in the UMIP-protected instructions. This includes all the ModRM,
and SiB displacement combinations. Furthermore, this test configures a Local
Descriptor Table whose segments have base addresses that are different from
the __USER_DS segment. Since this program runs in long mode, segmentation is
implemented using the FS and GS registers. The purpose of this test is to
verify that the emulation code is capable of succesfully computing linear
address out of the instruction operand and segment descriptor.

* umip_ldt_32. Use umip_ldt_32 to verify all the possible 32-bit address
encodings in the UMIP-protected instructions. This includes all the ModRM,
and SiB displacement combinations. Furthermore, this test configures a Local
Descriptor Table whose segments have base addresses that are different from
the __USER_DS segment. The purpose of this test is to verify that the
emulation code is capable of succesfully computing linear address out of the
instruction operand and segment descriptor.

* umip_ldt_16. Use umip_ldt_16 to verify all the possible 16-bit address
encodings in the UMIP-protected instructions. This includes all the ModRM and
displacement combinations. Furthermore, this test configure a Local Descriptor
Table with segments that have base addresses different than the __USER_DS
segment. Also, the code segment is configured for 16-bit addresses. The
purpose of this test is to verify that the emulation code is capable of
succesfully computing linear address out of the instruction operand and
segment descriptor.

g) Things to do

* In umip_ldt_64, test %rsp and %r12
* Add tests for address size override prefixes
* Add test to include more than one segment override prefix
57 changes: 57 additions & 0 deletions meta-luv/recipes-core/umip/files/cpuid.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#include <stdio.h>
#include <stdlib.h>

#define UMIP_MASK 0x4

void usage(void)
{
printf("Usage:\n");
printf("cpuid [eax] [ecx]\n");
printf("Example:\n");
printf("cpuid 0x4 0x0\n");
}

void print_umip(unsigned int ecx)
{
printf("CPU has UMIP? %s\n", ecx & UMIP_MASK ? "yes" : "no");
}

void get_cpuid_leaf(unsigned int eax, unsigned int ecx, unsigned int *new_eax,
unsigned int *new_ecx, unsigned *new_edx)
{
printf("Getting CPUID leaf for eax=0x%x ecx=0x%x\n", eax, ecx);

asm volatile("mov %3, %%eax\n"
"mov %4, %%ecx\n"
"cpuid\n"
"mov %%eax, %0\n"
"mov %%ecx, %1\n"
"mov %%edx, %2\n"
: "=m"(*new_eax), "=m"(*new_ecx), "=m"(*new_edx)
: "m"(eax), "m"(ecx)
: "eax", "ecx", "edx");
}

int main(int argc, char **argv)
{
unsigned int eax, ecx, edx;
unsigned int new_eax = 0xabababab, new_ecx = 0xcbcbcbcb;
unsigned int new_edx = 0xefefefef;

if (argc != 3) {
usage();
return 1;
}

eax = strtoul(argv[1], NULL, 0);
ecx = strtoul(argv[2], NULL, 0);

get_cpuid_leaf(eax, ecx, &new_eax, &new_ecx, &new_edx);

printf("CPUID Result:\n");
printf("eax = 0x%x\n", new_eax);
printf("ecx = 0x%x\n", new_ecx);
printf("edx = 0x%x\n", new_edx);

print_umip(new_ecx);
}
Loading