[PATCH 0/5] replace magic numbers in GDT descriptors

From: Vegard Nossum
Date: Tue Dec 19 2023 - 10:13:09 EST


Linus suggested replacing the magic numbers in the GDT descriptors
using preprocessor macros [1].

[1] https://lore.kernel.org/all/CAHk-=wib5XLebuEra7y2YH96wxdk=8vJnA8XoVq0FExpzVvN=Q@xxxxxxxxxxxxxx/

For patch 3 ("x86: replace magic numbers in GDT descriptors, part 2") I've
verified it to the best of my abilities on 32-bit and 64-bit by ensuring
that the object files are bitwise identical before and after applying the
patch and ensuring that all the object files were rebuilt on at least one
of the two configs:

32-bit:
arch/x86/boot/pm.o -- no change
arch/x86/kernel/apm_32.o -- no change
arch/x86/kernel/cpu/common.o -- no change
arch/x86/kernel/head64.o -- not built for 32
arch/x86/kernel/setup_percpu.o -- no change
arch/x86/platform/pvh/head.o -- not built for 32
arch/x86/realmode/rm/reboot.o -- no change
drivers/firmware/efi/libstub/x86-5lvl.o -- not built for 32
drivers/pnp/pnpbios/bioscalls.o -- no change

64-bit:
arch/x86/boot/pm.o -- no change
arch/x86/kernel/apm_32.o -- not built for 64
arch/x86/kernel/cpu/common.o -- no change
arch/x86/kernel/head64.o -- no change
arch/x86/kernel/setup_percpu.o -- no change
arch/x86/platform/pvh/head.o -- no change
arch/x86/realmode/rm/reboot.o -- no change
drivers/firmware/efi/libstub/x86-5lvl.o -- no change
drivers/pnp/pnpbios/bioscalls.o -- not built for 64

Patches 2+3 can be squashed to a single commit, but I've submitted them
separately because it makes verifying correctness easier.

I've done basic boot testing on both 32-bit and 64-bit with all of the
patches.

Vegard Nossum (5):
x86: provide new infrastructure for GDT descriptors
x86: replace magic numbers in GDT descriptors, part 1
x86: replace magic numbers in GDT descriptors, part 2
x86: always set A (accessed) flag in GDT descriptors
x86: add DB flag to 32-bit percpu GDT entry

arch/x86/boot/pm.c | 7 +--
arch/x86/include/asm/desc_defs.h | 68 ++++++++++++++++++++++---
arch/x86/kernel/apm_32.c | 2 +-
arch/x86/kernel/cpu/common.c | 50 ++++++++----------
arch/x86/kernel/head64.c | 6 +--
arch/x86/kernel/setup_percpu.c | 4 +-
arch/x86/platform/pvh/head.S | 7 +--
arch/x86/realmode/rm/reboot.S | 3 +-
drivers/firmware/efi/libstub/x86-5lvl.c | 4 +-
drivers/pnp/pnpbios/bioscalls.c | 2 +-
10 files changed, 100 insertions(+), 53 deletions(-)

--
2.34.1

This is the script I used for verifying no binary changes (pass rev of
patch 3 to build as the only argumnet):

#! /bin/bash

set -e
set -u

rev=$(git rev-parse $1)

# get the paths that changed
paths="$(git diff --name-only $rev^- | grep '\.[cS]$' | sed 's/\.[cS]$/.o/')"

build() {
id=$1

# build without patch and save result as <path>.pre-<id>
git checkout -d $rev^
rm -f $paths
make -j128
for p in $paths
do
if [ -e $p ]
then
mv -f $p $p.pre-$id
fi
done

# build with patch and save result as <path>.post-<id>
git checkout -d $rev
rm -f $paths
make -j128
for p in $paths
do
if [ -e $p ]
then
mv -f $p $p.post-$id
fi
done
}

# build i386
make defconfig
scripts/config --disable 64BIT
scripts/config --disable MODULES
# for arch/x86/kernel/apm_32.o
scripts/config --enable APM
# for drivers/pnp/pnpbios/bioscalls.o
scripts/config --enable ISA --enable PNP --enable PNPBIOS
make olddefconfig
build 32

# build x86_64
make defconfig
scripts/config --disable MODULES
# for arch/x86/platform/pvh/head.o
scripts/config --enable XEN --enable XEN_PVHVM --enable PVH
make olddefconfig
build 64

echo
echo results:
echo

for id in 32 64
do
echo $id:

for p in $paths
do
if [ -e $p.pre-$id ] && [ -e $p.post-$id ]
then
if cmp -s $p.pre-$id $p.post-$id
then
echo $p -- no change
else
echo $p -- differences:
diff -U3 <(objdump -dr $p.pre-$id | tail -n +3) <(objdump -dr $p.post-$id | tail -n +3) || true
fi
else
echo $p -- not built for $id
fi
done

echo
done