[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 06/13] libx86: Introduce a helper to serialise a cpuid_policy object
>>> On 03.07.18 at 22:55, <andrew.cooper3@xxxxxxxxxx> wrote: > --- a/xen/common/libx86/cpuid.c > +++ b/xen/common/libx86/cpuid.c > @@ -34,6 +34,100 @@ const uint32_t *x86_cpuid_lookup_deep_deps(uint32_t > feature) > } > > /* > + * Copy a single cpuid_leaf into a provided xen_cpuid_leaf_t buffer, > + * performing boundary checking against the buffer size. > + */ > +static int copy_leaf_to_buffer(uint32_t leaf, uint32_t subleaf, > + const struct cpuid_leaf *data, > + cpuid_leaf_buffer_t leaves, > + uint32_t *curr_entry, const uint32_t > nr_entries) > +{ > + const xen_cpuid_leaf_t val = { > + leaf, subleaf, data->a, data->b, data->c, data->d, > + }; > + > + if ( *curr_entry == nr_entries ) > + return -ENOBUFS; > + > + if ( copy_to_buffer_offset(leaves, *curr_entry, &val, 1) ) > + return -EFAULT; > + > + ++*curr_entry; Following on from what Wei has said - you don't mean to have a way here then to indicate to a higher up caller how many slots would have been needed? > +int x86_cpuid_copy_to_buffer(const struct cpuid_policy *p, > + cpuid_leaf_buffer_t leaves, > + uint32_t *nr_entries_p) > +{ > + const uint32_t nr_entries = *nr_entries_p; > + uint32_t curr_entry = 0, leaf, subleaf; > + > +#define COPY_LEAF(l, s, data) \ > + ({ int ret; \ > + if ( (ret = copy_leaf_to_buffer( \ > + l, s, data, leaves, &curr_entry, nr_entries)) ) \ > + return ret; \ > + }) > + > + /* Basic leaves. */ > + for ( leaf = 0; leaf <= MIN(p->basic.max_leaf, > + ARRAY_SIZE(p->basic.raw) - 1); ++leaf ) > + { > + switch ( leaf ) > + { > + case 0x4: > + for ( subleaf = 0; subleaf < ARRAY_SIZE(p->cache.raw); ++subleaf > ) > + COPY_LEAF(leaf, subleaf, &p->cache.raw[subleaf]); > + break; > + > + case 0x7: > + for ( subleaf = 0; > + subleaf <= MIN(p->feat.max_subleaf, > + ARRAY_SIZE(p->feat.raw) - 1); ++subleaf ) > + COPY_LEAF(leaf, subleaf, &p->feat.raw[subleaf]); > + break; > + > + case 0xb: > + for ( subleaf = 0; subleaf < ARRAY_SIZE(p->topo.raw); ++subleaf ) > + COPY_LEAF(leaf, subleaf, &p->topo.raw[subleaf]); > + break; > + > + case 0xd: > + for ( subleaf = 0; subleaf < ARRAY_SIZE(p->xstate.raw); > ++subleaf ) > + COPY_LEAF(leaf, subleaf, &p->xstate.raw[subleaf]); > + break; > + > + default: > + COPY_LEAF(leaf, XEN_CPUID_NO_SUBLEAF, &p->basic.raw[leaf]); > + break; > + } > + } > + > + COPY_LEAF(0x40000000, XEN_CPUID_NO_SUBLEAF, > + &(struct cpuid_leaf){ p->hv_limit }); > + COPY_LEAF(0x40000100, XEN_CPUID_NO_SUBLEAF, > + &(struct cpuid_leaf){ p->hv2_limit }); Is it a good idea to produce wrong (zero) EBX, ECX, and EDX values here? > @@ -27,6 +33,17 @@ static inline bool test_bit(unsigned int bit, const void > *vaddr) > return addr[bit / 8] & (1u << (bit % 8)); > } > > +/* memcpy(), but with copy_to_guest_offset()'s API */ > +#define copy_to_buffer_offset(dst, index, src, nr) ({ \ > + const typeof(*(dst)) *s = (src); \ > + unsigned int i; \ > + \ > + for ( i = 0; i < (nr); i++ ) \ > + (dst)[(index) + i] = s[i]; \ > + \ > + 0; \ > +}) Should you try to avoid multiple evaluation of macro arguments here? Jan _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |