Hi,

> > > /* read chunk of given fw_cfg blob (caller responsible for sanity-check) 
> > > */
> > > static inline void fw_cfg_read_blob(uint16_t select,
> > >                                void *buf, loff_t pos, size_t count)
> > > {
> > >   mutex_lock(&fw_cfg_dev_lock);
> > >   outw(select, FW_CFG_PORT_CTL);
> > >   while (pos-- > 0)
> > >           inb(FW_CFG_PORT_DATA);
> > >   insb(FW_CFG_PORT_DATA, buf, count);
> > >   mutex_unlock(&fw_cfg_dev_lock);
> > > }
> > 
> > How slow is this?
> 
> Well, I think each outw() and inb() will result in a vmexit, with
> userspace handling emulation, so much slower comparatively than
> inserting into a list (hence mutex here, vs. spinlock there).

There are a few tricks to speed up things, not sure this really matters
here as we don't transfer big stuff like kernel or initrd here.

Trick one (for x86) is that you can use string prefixes (i.e. load ecx
register with count, then use "rep insb").

Trick two (for arm) is that you can read eight instead of one byte per
instruction.

Both reduce the number of vmexits.

But speaking of kernel+initrd:  You eventually might want add them to
the filesystem too.

cheers,
  Gerd



Reply via email to