From: Jack Lange Date: Thu, 26 May 2011 21:48:52 +0000 (-0500) Subject: added safety checks to cpuid field registration X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=aaaaaaac22479d0f92f4249d06221e830e8c8f4d;p=palacios.git added safety checks to cpuid field registration --- diff --git a/palacios/src/palacios/vmm_cpuid.c b/palacios/src/palacios/vmm_cpuid.c index ce7c244..ca7ef86 100644 --- a/palacios/src/palacios/vmm_cpuid.c +++ b/palacios/src/palacios/vmm_cpuid.c @@ -135,20 +135,27 @@ static int mask_hook(struct guest_info * core, uint32_t cpuid, v3_cpuid(cpuid, eax, ebx, ecx, edx); *eax &= ~(mask->rax_mask); - *eax |= mask->rax; + *eax |= (mask->rax & mask->rax_mask); *ebx &= ~(mask->rbx_mask); - *ebx |= mask->rbx; + *ebx |= (mask->rbx & mask->rbx_mask); *ecx &= ~(mask->rcx_mask); - *ecx |= mask->rcx; + *ecx |= (mask->rcx & mask->rcx_mask); *edx &= ~(mask->rdx_mask); - *edx |= mask->rdx; + *edx |= (mask->rdx & mask->rdx_mask); return 0; } + + +/* This function allows you to reserve a set of bits in a given cpuid value + * For each cpuid return register you specify which bits you want to reserve in the mask. + * The value of those bits is set in the reg param. + * The values of the reserved bits are returned to the guest, when it reads the cpuid + */ int v3_cpuid_add_fields(struct v3_vm_info * vm, uint32_t cpuid, uint32_t rax_mask, uint32_t rax, uint32_t rbx_mask, uint32_t rbx, @@ -156,6 +163,14 @@ int v3_cpuid_add_fields(struct v3_vm_info * vm, uint32_t cpuid, uint32_t rdx_mask, uint32_t rdx) { struct v3_cpuid_hook * hook = get_cpuid_hook(vm, cpuid); + + if ((~rax_mask & rax) || (~rbx_mask & rbx) || + (~rcx_mask & rcx) || (~rdx_mask & rdx)) { + PrintError("Invalid cpuid reg value (mask overrun)\n"); + return -1; + } + + if (hook == NULL) { struct masked_cpuid * mask = V3_Malloc(sizeof(struct masked_cpuid)); memset(mask, 0, sizeof(struct masked_cpuid)); @@ -192,12 +207,6 @@ int v3_cpuid_add_fields(struct v3_vm_info * vm, uint32_t cpuid, return -1; } - if ((~rax_mask & rax) || (~rbx_mask & rbx) || - (~rcx_mask & rcx) || (~rdx_mask & rdx)) { - PrintError("Invalid cpuid reg value (mask overrun)\n"); - return -1; - } - mask->rax_mask |= rax_mask; mask->rbx_mask |= rbx_mask; mask->rcx_mask |= rcx_mask;