usb_session: align USB packet allocation correctly

To prevent caching side-effects of USB DMA memory taken from the packet stream
all allocations of USB packets need to be on separated cachelines at least.

Fix genodelabs/genode#4655
This commit is contained in:
Stefan Kalkowski 2022-11-02 11:17:51 +01:00 committed by Christian Helmuth
parent b03059b933
commit 3082950e74
7 changed files with 24 additions and 10 deletions

View File

@ -105,7 +105,7 @@ struct Driver
private:
Usb::Session_client & _usb;
Usb::Packet_descriptor _packet { _usb.source()->alloc_packet(0) };
Usb::Packet_descriptor _packet { _usb.alloc_packet(0) };
completion _comp;
public:

View File

@ -103,7 +103,7 @@ struct Driver
private:
Usb::Session_client & _usb;
Usb::Packet_descriptor _packet { _usb.source()->alloc_packet(0) };
Usb::Packet_descriptor _packet { _usb.alloc_packet(0) };
completion _comp;
public:

View File

@ -26,7 +26,7 @@ class Urb : public Usb::Completion
Usb::Session_client & _usb;
urb & _urb;
Usb::Packet_descriptor _packet {
_usb.source()->alloc_packet(_urb.transfer_buffer_length) };
_usb.alloc_packet(_urb.transfer_buffer_length) };
bool _completed { false };
public:

View File

@ -80,7 +80,7 @@ struct Usb_device
raw_config_descriptor = (char*)malloc(config_descriptor.total_length);
Usb::Packet_descriptor p =
usb_connection->source()->alloc_packet(config_descriptor.total_length);
usb_connection->alloc_packet(config_descriptor.total_length);
p.type = Usb::Packet_descriptor::CTRL;
p.control.request = LIBUSB_REQUEST_GET_DESCRIPTOR;
@ -121,7 +121,7 @@ struct Usb_device
return false;
Usb::Packet_descriptor p =
usb_connection->source()->alloc_packet(0);
usb_connection->alloc_packet(0);
p.type = Usb::Packet_descriptor::ALT_SETTING;
p.interface.number = number;
@ -521,7 +521,7 @@ static int genode_submit_transfer(struct usbi_transfer * itransfer)
Usb::Packet_descriptor p;
try {
p = usb_device->usb_connection->source()->alloc_packet(setup->wLength);
p = usb_device->usb_connection->alloc_packet(setup->wLength);
} catch (Usb::Session::Tx::Source::Packet_alloc_failed) {
return LIBUSB_ERROR_BUSY;
}
@ -565,7 +565,7 @@ static int genode_submit_transfer(struct usbi_transfer * itransfer)
Usb::Packet_descriptor p;
try {
p = usb_device->usb_connection->source()->alloc_packet(transfer->length);
p = usb_device->usb_connection->alloc_packet(transfer->length);
} catch (Usb::Session::Tx::Source::Packet_alloc_failed) {
return LIBUSB_ERROR_BUSY;
}
@ -601,7 +601,7 @@ static int genode_submit_transfer(struct usbi_transfer * itransfer)
Usb::Packet_descriptor p;
try {
p = usb_device->usb_connection->source()->alloc_packet(total_length);
p = usb_device->usb_connection->alloc_packet(total_length);
} catch (Usb::Session::Tx::Source::Packet_alloc_failed) {
return LIBUSB_ERROR_BUSY;
}

View File

@ -534,7 +534,7 @@ struct Usb_host_device : List<Usb_host_device>::Element
throw Packet_alloc_failed();
}
Usb::Packet_descriptor packet = usb_raw.source()->alloc_packet(length);
Usb::Packet_descriptor packet = usb_raw.alloc_packet(length);
if (!completion) {
packet.completion = nullptr;

View File

@ -94,7 +94,7 @@ class Usb::Packet_handler
while (true) {
try {
Packet_descriptor p = _connection.source()->alloc_packet(size);
Packet_descriptor p = _connection.alloc_packet(size);
return p;
} catch (Usb::Session::Tx::Source::Packet_alloc_failed) {
/* block until some packets are freed */

View File

@ -52,6 +52,20 @@ class Usb::Session_client : public Genode::Rpc_client<Session>
sigh_state_change(state_change);
}
/*
* Helper utility to always allocate correctly aligned USB packets
*/
Packet_descriptor alloc_packet(Genode::size_t size)
{
/*
* At least on ARM the minimal alignment for distinct
* DMA-capable USB URBs shall meet a maximum cache-line
* size of 128 bytes
*/
enum { URB_PAYLOAD_MIN_ALIGN_LOG2 = 7 };
return source()->alloc_packet(size, URB_PAYLOAD_MIN_ALIGN_LOG2);
}
/***************************
** USB session interface **
***************************/