diff options
| author | MJ Pooladkhay <mj@pooladkhay.com> | 2025-12-22 17:42:07 +0000 |
|---|---|---|
| committer | Sean Christopherson <seanjc@google.com> | 2026-01-08 12:00:56 -0800 |
| commit | 7fe9f5366bd5d7ee3cfd9f66868a4410d6e4792d (patch) | |
| tree | f89bde66a18d6e0e5f59e69b2ca54592a35f87f9 /tools/testing/selftests/kvm/include | |
| parent | 0b28194c4c8e3a6c2552bfa6451f71b1879dd61f (diff) | |
KVM: selftests: Fix sign extension bug in get_desc64_base()
The function get_desc64_base() performs a series of bitwise left shifts on
fields of various sizes. More specifically, when performing '<< 24' on
'desc->base2' (which is a u8), 'base2' is promoted to a signed integer
before shifting.
In a scenario where base2 >= 0x80, the shift places a 1 into bit 31,
causing the 32-bit intermediate value to become negative. When this
result is cast to uint64_t or ORed into the return value, sign extension
occurs, corrupting the upper 32 bits of the address (base3).
Example:
Given:
base0 = 0x5000
base1 = 0xd6
base2 = 0xf8
base3 = 0xfffffe7c
Expected return: 0xfffffe7cf8d65000
Actual return: 0xfffffffff8d65000
Fix this by explicitly casting the fields to 'uint64_t' before shifting
to prevent sign extension.
Signed-off-by: MJ Pooladkhay <mj@pooladkhay.com>
Link: https://patch.msgid.link/20251222174207.107331-1-mj@pooladkhay.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
Diffstat (limited to 'tools/testing/selftests/kvm/include')
| -rw-r--r-- | tools/testing/selftests/kvm/include/x86/processor.h | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/tools/testing/selftests/kvm/include/x86/processor.h b/tools/testing/selftests/kvm/include/x86/processor.h index 57d62a425109..26a91bb73c93 100644 --- a/tools/testing/selftests/kvm/include/x86/processor.h +++ b/tools/testing/selftests/kvm/include/x86/processor.h @@ -436,8 +436,10 @@ struct kvm_x86_state { static inline uint64_t get_desc64_base(const struct desc64 *desc) { - return ((uint64_t)desc->base3 << 32) | - (desc->base0 | ((desc->base1) << 16) | ((desc->base2) << 24)); + return (uint64_t)desc->base3 << 32 | + (uint64_t)desc->base2 << 24 | + (uint64_t)desc->base1 << 16 | + (uint64_t)desc->base0; } static inline uint64_t rdtsc(void) |
