On 08/08/2017 04:58 PM, Andrew Cooper wrote:
> On 08/08/17 15:47, Sergej Proskurin wrote:
>> Hi Julien,
>>> The patch belows solve my problem:
>>> diff --git a/xen/arch/arm/guest_walk.c b/xen/arch/arm/guest_walk.c
>>> index b258248322..6ca994e438 100644
>>> --- a/xen/arch/arm/guest_walk.c
>>> +++ b/xen/arch/arm/guest_walk.c
>>> @@ -112,7 +112,7 @@ static int guest_walk_sd(const struct vcpu *v,
>>> * level translation table does not need to be page aligned.
>>> mask = GENMASK(19, 12);
>>> - paddr = (pte.walk.base << 10) | ((gva & mask) >> 10);
>>> + paddr = ((paddr_t)pte.walk.base << 10) | ((gva & mask) >> 10);
>>> /* Access the guest's memory to read only one PTE. */
>>> ret = access_guest_memory_by_ipa(d, paddr, &pte,
>>> sizeof(short_desc_t), false);
>>> This is because pte.walk.base is encoded on unsigned int:22 bits. A shift
>>> by 10 will not
>>> fit an integer, and my compiler seems to promote it to "signed long long".
>>> Hence the bogus
>> Thats quite an interesting phenomenon :) I have just played around with
>> this and it does indeed appear that the value is casted to a signed
>> result! What I don't yet understand is the following: An unsigned int
>> with the length of 22 bit should actually exactly fit an integer after a
>> left shift of 10 (or do I miss s.th.?).
> C type promotion ftw!
> All integral types smaller than int are promoted to int before any
> operations on them. This includes things like unsigned char/short etc.
> Then, the type is promoted to match that of the other operand, which
> might be a wider type (e.g. long) or an unsigned version of the same type.
Thanks Andrew, I did not know that!
Xen-devel mailing list