pc/wifi: prevent calling driver from pthread

Querying the RFKILL state led to execution of the Lx_kit::scheduler by
the pthread running the wpa_supplicant. As this may not happen the
RFKILL state is now solely managed by the driver and only the cached
state is read by the supplicant.

Fixes #4537.
This commit is contained in:
Josef Söntgen 2022-06-23 15:53:48 +02:00 committed by Christian Helmuth
parent 9d417ee2f5
commit 9393c0136c
5 changed files with 31 additions and 12 deletions

View File

@ -21,6 +21,5 @@ namespace Wifi {
} }
bool wifi_get_rfkill(void); bool wifi_get_rfkill(void);
void wifi_set_rfkill(bool);
#endif /* _WIFI__RFKILL_H_ */ #endif /* _WIFI__RFKILL_H_ */

View File

@ -62,6 +62,9 @@
/* declare manually as it is a internal hack^Winterface */ /* declare manually as it is a internal hack^Winterface */
extern void wifi_kick_socketcall(); extern void wifi_kick_socketcall();
extern bool _wifi_get_rfkill(void);
extern bool _wifi_set_rfkill(bool);
namespace Wifi { namespace Wifi {
struct Frontend; struct Frontend;
@ -343,7 +346,7 @@ struct Wifi::Frontend
void _handle_rfkill() void _handle_rfkill()
{ {
_rfkilled = wifi_get_rfkill(); _rfkilled = _wifi_get_rfkill();
/* re-enable scan timer */ /* re-enable scan timer */
if (!_rfkilled) { if (!_rfkilled) {
@ -407,7 +410,7 @@ struct Wifi::Frontend
*/ */
if (config.has_attribute("rfkill")) { if (config.has_attribute("rfkill")) {
bool const blocked = config.attribute_value("rfkill", false); bool const blocked = config.attribute_value("rfkill", false);
wifi_set_rfkill(blocked); _wifi_set_rfkill(blocked);
/* /*
* In case we get blocked set rfkilled immediately to prevent * In case we get blocked set rfkilled immediately to prevent

View File

@ -547,6 +547,10 @@ struct task_struct *rfkill_task_struct_ptr;
int lx_emul_rfkill_get_any(void) int lx_emul_rfkill_get_any(void)
{ {
/*
* Since this function may also be called from non EPs
* _do not_ execute _any_ kernel code.
*/
return _rfkill_state.rfkilled; return _rfkill_state.rfkilled;
} }

View File

@ -205,16 +205,24 @@ struct netdev_event_notification
}; };
/* needed for RFKILL state update */
extern struct task_struct *rfkill_task_struct_ptr;
static int uplink_netdev_event(struct notifier_block *this, static int uplink_netdev_event(struct notifier_block *this,
unsigned long event, void *ptr) unsigned long event, void *ptr)
{ {
/* /*
* For now we ignore what kind of event occurred and simply * For now we ignore what kind of event occurred and simply
* unblock the uplink task. * unblock the uplink and rfkill task.
*/ */
if (uplink_task_struct_ptr) if (uplink_task_struct_ptr)
lx_emul_task_unblock(uplink_task_struct_ptr); lx_emul_task_unblock(uplink_task_struct_ptr);
if (rfkill_task_struct_ptr)
lx_emul_task_unblock(rfkill_task_struct_ptr);
return NOTIFY_DONE; return NOTIFY_DONE;
} }

View File

@ -36,19 +36,18 @@ extern "C" void lx_emul_rfkill_switch_all(int blocked);
static Genode::Signal_context_capability _rfkill_sigh_cap; static Genode::Signal_context_capability _rfkill_sigh_cap;
bool wifi_get_rfkill(void)
bool _wifi_get_rfkill(void)
{ {
if (!rfkill_task_struct_ptr) /*
return false; * It is safe to call this from non EP threads as we
* only query a variable.
lx_emul_task_unblock(rfkill_task_struct_ptr); */
Lx_kit::env().scheduler.schedule();
return lx_emul_rfkill_get_any(); return lx_emul_rfkill_get_any();
} }
void wifi_set_rfkill(bool blocked) void _wifi_set_rfkill(bool blocked)
{ {
if (!rfkill_task_struct_ptr) if (!rfkill_task_struct_ptr)
return; return;
@ -71,6 +70,12 @@ void wifi_set_rfkill(bool blocked)
} }
bool wifi_get_rfkill(void)
{
return _wifi_get_rfkill();
}
extern "C" unsigned int wifi_ifindex(void) extern "C" unsigned int wifi_ifindex(void)
{ {
/* TODO replace with actual qyery */ /* TODO replace with actual qyery */