From b4283c91215a851a73be25415fea7f8156799e59 Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Fri, 5 Jul 2013 11:44:55 +0200 Subject: [PATCH] seoul: use utcb guard Forgetting to restore the old utcb content results in hard to debug bugs. Save only the amount of word items which are actually on the UTCB. Issue #806 --- ports/src/vancouver/disk.cc | 6 ++-- ports/src/vancouver/utcb_guard.h | 55 ++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 ports/src/vancouver/utcb_guard.h diff --git a/ports/src/vancouver/disk.cc b/ports/src/vancouver/disk.cc index b6ae300a4..46a4e81bb 100644 --- a/ports/src/vancouver/disk.cc +++ b/ports/src/vancouver/disk.cc @@ -28,6 +28,7 @@ /* local includes */ #include +#include static Genode::Native_utcb utcb_backup; @@ -67,7 +68,7 @@ void Vancouver_disk::entry() bool Vancouver_disk::receive(MessageDisk &msg) { - utcb_backup = *Genode::Thread_base::myself()->utcb(); + Utcb_guard guard(utcb_backup); if (msg.disknr >= MAX_DISKS) Logging::panic("You configured more disks than supported.\n"); @@ -125,7 +126,6 @@ bool Vancouver_disk::receive(MessageDisk &msg) MessageDiskCommit ro(msg.disknr, msg.usertag, MessageDisk::DISK_STATUS_DEVICE); _motherboard()->bus_diskcommit.send(ro); - *Genode::Thread_base::myself()->utcb() = utcb_backup; return true; } @@ -207,10 +207,8 @@ bool Vancouver_disk::receive(MessageDisk &msg) default: Logging::printf("Got MessageDisk type %x\n", msg.type); - *Genode::Thread_base::myself()->utcb() = utcb_backup; return false; } - *Genode::Thread_base::myself()->utcb() = utcb_backup; return true; } diff --git a/ports/src/vancouver/utcb_guard.h b/ports/src/vancouver/utcb_guard.h new file mode 100644 index 000000000..4986cf6af --- /dev/null +++ b/ports/src/vancouver/utcb_guard.h @@ -0,0 +1,55 @@ +/* + * \brief Guard to save a utcb and restore it during Guard desctruction + * \author Alexander Boettcher + * \date 2013-07-05 + */ + +/* + * Copyright (C) 2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _SEOUL_UTCB_GUARD_H_ +#define _SEOUL_UTCB_GUARD_H_ + +#include +#include + +class Utcb_guard { + + private: + Genode::Native_utcb &_backup_utcb; + + public: + + Utcb_guard(Genode::Native_utcb &backup_utcb) + : _backup_utcb(backup_utcb) + { + using namespace Genode; + + Nova::Utcb *utcb = + reinterpret_cast(Thread_base::myself()->utcb()); + + unsigned header_len = (char *)utcb->msg - (char *)utcb; + unsigned len = header_len + utcb->msg_words() * sizeof(Nova::mword_t); + Genode::memcpy(&_backup_utcb, utcb, len); + + if (utcb->msg_items()) + PWRN("Error: msg items on UTCB are not saved and restored !!!"); + } + + ~Utcb_guard() + { + using namespace Genode; + + Nova::Utcb *utcb = reinterpret_cast(&_backup_utcb); + + unsigned header_len = (char *)utcb->msg - (char *)utcb; + unsigned len = header_len + utcb->msg_words() * sizeof(Nova::mword_t); + Genode::memcpy(Thread_base::myself()->utcb(), utcb, len); + } +}; + +#endif /* _SEOUL_UTCB_GUARD_H_ */