[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v6 2/8] vpci: Refactor REGISTER_VPCI_INIT
On 25.06.2025 11:27, Chen, Jiqian wrote: > On 2025/6/25 16:36, Jan Beulich wrote: >> On 25.06.2025 08:51, Chen, Jiqian wrote: >>> On 2025/6/24 18:08, Jan Beulich wrote: >>>> On 24.06.2025 11:29, Chen, Jiqian wrote: >>>>> On 2025/6/24 16:05, Jan Beulich wrote: >>>>>> On 24.06.2025 10:02, Chen, Jiqian wrote: >>>>>>> On 2025/6/20 14:38, Jan Beulich wrote: >>>>>>>> On 19.06.2025 08:39, Chen, Jiqian wrote: >>>>>>>>> On 2025/6/18 22:05, Jan Beulich wrote: >>>>>>>>>> On 12.06.2025 11:29, Jiqian Chen wrote: >>>>>>>>>>> @@ -29,9 +30,22 @@ typedef int vpci_register_init_t(struct pci_dev >>>>>>>>>>> *dev); >>>>>>>>>>> */ >>>>>>>>>>> #define VPCI_MAX_VIRT_DEV (PCI_SLOT(~0) + 1) >>>>>>>>>>> >>>>>>>>>>> -#define REGISTER_VPCI_INIT(x, p) \ >>>>>>>>>>> - static vpci_register_init_t *const x##_entry \ >>>>>>>>>>> - __used_section(".data.vpci." p) = (x) >>>>>>>>>>> +#define REGISTER_VPCI_CAPABILITY(cap, finit, fclean, ext) \ >>>>>>>>>>> + static const vpci_capability_t finit##_t = { \ >>>>>>>>>>> + .id = (cap), \ >>>>>>>>>>> + .init = (finit), \ >>>>>>>>>>> + .cleanup = (fclean), \ >>>>>>>>>>> + .is_ext = (ext), \ >>>>>>>>>>> + }; \ >>>>>>>>>>> + static const vpci_capability_t *const finit##_entry \ >>>>>>>>>>> + __used_section(".data.rel.ro.vpci") = &finit##_t >>>>>>>>>> >>>>>>>>>> Could you remind me why the extra level of indirection is necessary >>>>>>>>>> here? >>>>>>>>>> That is, why can't .data.rel.ro.vpci be an array of >>>>>>>>>> vpci_capability_t? >>>>>>>>> You mean I should change to be: >>>>>>>>> #define REGISTER_VPCI_CAPABILITY(cap, finit, fclean, ext) \ >>>>>>>>> static const vpci_capability_t finit##_t \ >>>>>>>>> __used_section(".data.rel.ro.vpci") = { \ >>>>>>>>> .id = (cap), \ >>>>>>>>> .init = (finit), \ >>>>>>>>> .cleanup = (fclean), \ >>>>>>>>> .is_ext = (ext), \ >>>>>>>>> } >>>>>>>>> >>>>>>>>> Right? >>>>>>>> >>>>>>>> Yes, subject to the earlier comments on the identifier choice. >>>>>>> Got it. >>>>>>> One more question, if change to be that, then how should I modify the >>>>>>> definition of VPCI_ARRAY? >>>>>>> Is POINTER_ALIGN still right? >>>>>> >>>>>> Yes. The struct doesn't require bigger alignment afaics. (In fact in >>>>>> principle >>>>>> no alignment should need specifying there, except that this would require >>>>>> keeping the section separate in the final image. Which I don't think we >>>>>> want.) >>>>>> >>>>>>> Since I encountered errors that the values of __start_vpci_array are >>>>>>> not right when I use them in vpci_init_capabilities(). >>>>>> >>>>>> Details please. >>>>> After changing __start_vpci_array to be vpci_capability_t array, codes >>>>> will be (maybe I modified wrong somewhere): >>>>> >>>>> diff --git a/xen/drivers/vpci/vpci.c b/xen/drivers/vpci/vpci.c >>>>> index c51bbb8abb19..9f2f438b4fdd 100644 >>>>> --- a/xen/drivers/vpci/vpci.c >>>>> +++ b/xen/drivers/vpci/vpci.c >>>>> @@ -36,8 +36,8 @@ struct vpci_register { >>>>> }; >>>>> >>>>> #ifdef __XEN__ >>>>> -extern const vpci_capability_t *const __start_vpci_array[]; >>>>> -extern const vpci_capability_t *const __end_vpci_array[]; >>>>> +extern vpci_capability_t __start_vpci_array[]; >>>>> +extern vpci_capability_t __end_vpci_array[]; >>>> >>>> Just fyi: You lost const here. >>>> >>>>> @@ -255,7 +255,7 @@ static int vpci_init_capabilities(struct pci_dev >>>>> *pdev) >>>>> { >>>>> for ( unsigned int i = 0; i < NUM_VPCI_INIT; i++ ) >>>>> { >>>>> - const vpci_capability_t *capability = __start_vpci_array[i]; >>>>> + const vpci_capability_t *capability = &__start_vpci_array[i]; >>>>> const unsigned int cap = capability->id; >>>>> const bool is_ext = capability->is_ext; >>>>> int rc; >>>>> diff --git a/xen/include/xen/vpci.h b/xen/include/xen/vpci.h >>>>> index f4ec1c25922d..77750dd4131a 100644 >>>>> --- a/xen/include/xen/vpci.h >>>>> +++ b/xen/include/xen/vpci.h >>>>> @@ -31,14 +31,13 @@ typedef struct { >>>>> #define VPCI_MAX_VIRT_DEV (PCI_SLOT(~0) + 1) >>>>> >>>>> #define REGISTER_VPCI_CAPABILITY(cap, finit, fclean, ext) \ >>>>> - static const vpci_capability_t finit##_t = { \ >>>>> + static vpci_capability_t finit##_entry \ >>>>> + __used_section(".data.rel.ro.vpci") = { \ >>>>> .id = (cap), \ >>>>> .init = (finit), \ >>>>> .cleanup = (fclean), \ >>>>> .is_ext = (ext), \ >>>>> - }; \ >>>>> - static const vpci_capability_t *const finit##_entry \ >>>>> - __used_section(".data.rel.ro.vpci") = &finit##_t >>>>> + } >>>>> >>>>> #define REGISTER_VPCI_CAP(cap, finit, fclean) \ >>>>> REGISTER_VPCI_CAPABILITY(cap, finit, fclean, false) >>>>> >>>>> I print the value of NUM_VPCI_INIT, it is a strange number >>>>> (6148914691236517209). >>>> >>>> What are the addresses of the two symbols __start_vpci_array and >>>> __end_vpci_array? >>> __end_vpci_array is 0xffff82d0404251b8 >>> __start_vpci_array is 0xffff82d040425160 >>> NUM_VPCI_INIT is 0x5555555555555559 >>> sizeof(vpci_capability_t) is 0x18 >> >> Oh, of course - there's a psABI peculiarity that you run into here: >> Aggregates >> larger than 8 bytes are required to have 16-byte alignment. Hence while >> sizeof() == 0x18 and __alignof() == 8, the section contributions still are >> accompanied by ".align 16", and thus respective padding is inserted by >> assembler and linker. IOW you end up with two 32-byte entries and a trailing >> 24-byte one. The easiest (and least problematic going forward) approach to >> deal with that is probably going to be to add __aligned(16) to the struct >> decl. (Whether to limit this to just x86 I'm not sure: While other psABI-s >> may >> be different in this regard, we may want to be on the safe side.) > Thanks for you detailed explanation. > If I understand correctly, I need to change the definition of > vpci_capability_t to be: > > typedef struct { > unsigned int id; > bool is_ext; > int (* init)(const struct pci_dev *pdev); > int (* cleanup)(const struct pci_dev *pdev); > } > #ifdef CONFIG_X86 > __aligned(16) > #endif > vpci_capability_t; You'll need to check whether this has the intended effect. There are yet more peculiarities when it comes to attributes on structs, typedefs, and the combination of the two. I wonder though: Do we really need a typedef here? Going with just struct vcpi_capability would eliminate concerns over those peculiarities. Also, as said - you will need to check whether other architectures are different from x86-64 in this regard. We better wouldn't leave a trap here, for them to fall into when they enable vPCI support. I.e. my recommendation would be that if in doubt, we put the __aligned() there unconditionally. Jan
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |