summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDoug Gilbert <dgilbert@us.ibm.com>2012-01-13 09:40:41 -0600
committerDouglas R. Gilbert <dgilbert@us.ibm.com>2012-01-19 14:47:50 -0600
commit11a2e07a97bb44005dfd8fe8bac690014b3e2a81 (patch)
tree3a8492a5476e540ced0cbb7cb21c8d16b0936f9f /src
parent67ab5c65b2caabff6147143a90ab5584573e24ae (diff)
downloadtalos-hostboot-11a2e07a97bb44005dfd8fe8bac690014b3e2a81.tar.gz
talos-hostboot-11a2e07a97bb44005dfd8fe8bac690014b3e2a81.zip
VFS add functions to find module by address and query if module is loaded
Change-Id: I471a2a773d42f11ab973f42ca701c8be5191d776 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/611 Tested-by: Jenkins Server Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com> Reviewed-by: Douglas R. Gilbert <dgilbert@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/include/sys/vfs.h15
-rw-r--r--src/include/usr/vfs/vfs.H14
-rw-r--r--src/sys/vfs/vfs_init.C24
-rw-r--r--src/usr/vfs/test/vfstest.H32
-rw-r--r--src/usr/vfs/vfsrp.C113
-rw-r--r--src/usr/vfs/vfsrp.H26
6 files changed, 206 insertions, 18 deletions
diff --git a/src/include/sys/vfs.h b/src/include/sys/vfs.h
index 155851398..3094a1707 100644
--- a/src/include/sys/vfs.h
+++ b/src/include/sys/vfs.h
@@ -69,8 +69,8 @@ enum VfsMessages
VFS_MSG_REGISTER_MSGQ, //!< Message to VFS_ROOT to register a message queue
VFS_MSG_RESOLVE_MSGQ, //!< Message to VFS_ROOT to find a message queue
VFS_MSG_EXEC, //!< Message to VFS_ROOT execute a module
- VFS_MSG_LOAD, //!< Message to VFS_MSG to load a module
- VFS_MSG_UNLOAD, //!< Message to VFS_MSG to unload a module
+ VFS_MSG_LOAD, //!< Message to vfsrp to load a module
+ VFS_MSG_UNLOAD, //!< Message to vfsrp to unload a module
};
struct VfsSystemModule
@@ -81,7 +81,7 @@ struct VfsSystemModule
void (*fini)(void*); //!< ptr to fini()
uint64_t * text; //!< ptr to text (code) section
uint64_t * data; //!< ptr to data section
- uint64_t byte_count; //!< no. of memory pages used
+ uint64_t byte_count; //!< no. of bytes in module
};
extern VfsSystemModule VFS_MODULES[VFS_MODULE_MAX];
@@ -102,6 +102,15 @@ extern uint64_t VFS_LAST_ADDRESS;
VfsSystemModule * vfs_find_module(VfsSystemModule * i_table, const char * i_name);
/**
+ * Find the VfsSystemModule for the given address
+ * @param[in] i_table The VFS module table to look in
+ * @param[in] i_vaddr The virtual address
+ * @return VrsSytemModule ptr for the module | NULL if not found
+ */
+VfsSystemModule * vfs_find_address(VfsSystemModule * i_table,
+ const void * i_vaddr);
+
+/**
* Get the module's start routine
* @param[in] i_module VfsSystemModule data for the module
* @return Function pointer of module's start or negative value on error.
diff --git a/src/include/usr/vfs/vfs.H b/src/include/usr/vfs/vfs.H
index c916eb8ce..f65bfd51c 100644
--- a/src/include/usr/vfs/vfs.H
+++ b/src/include/usr/vfs/vfs.H
@@ -83,6 +83,20 @@ namespace VFS
*/
errlHndl_t module_address(const char * i_name, const char *& o_address, size_t & o_size);
+ /**
+ * Get the module name associated with an address
+ * @param[in] i_vaddr, The virtual address
+ * @returns ptr to module name or NULL if not found
+ */
+ const char * module_find_name(const void * i_vaddr);
+
+ /**
+ * Query if module is loaded
+ * @param[in] module name
+ * @returns [true|false]
+ */
+ bool module_is_loaded(const char * i_name);
+
};
#endif
diff --git a/src/sys/vfs/vfs_init.C b/src/sys/vfs/vfs_init.C
index 91e09876f..e0cf844fa 100644
--- a/src/sys/vfs/vfs_init.C
+++ b/src/sys/vfs/vfs_init.C
@@ -119,4 +119,28 @@ VfsSystemModule * vfs_find_module(VfsSystemModule * i_table,
return ret;
}
+// ----------------------------------------------------------------------------
+
+VfsSystemModule * vfs_find_address(VfsSystemModule * i_table,
+ const void * i_vaddr)
+{
+ VfsSystemModule * module = i_table;
+ VfsSystemModule * ret = NULL;
+
+ const uint8_t * vaddr = reinterpret_cast<const uint8_t *>(i_vaddr);
+
+ while('\0' != module->module[0])
+ {
+ const uint8_t * first = reinterpret_cast<const uint8_t *>(module->text);
+ const uint8_t * last = first + module->byte_count;
+
+ if(vaddr >= first && vaddr < last)
+ {
+ ret = module;
+ break;
+ }
+ ++module;
+ }
+ return ret;
+}
diff --git a/src/usr/vfs/test/vfstest.H b/src/usr/vfs/test/vfstest.H
index 5e33a0b33..3f9644f27 100644
--- a/src/usr/vfs/test/vfstest.H
+++ b/src/usr/vfs/test/vfstest.H
@@ -71,6 +71,38 @@ class VfsTest: public CxxTest::TestSuite
TS_FAIL("module_unload failed");
}
}
+
+ void test_findModule(void)
+ {
+ size_t size = 0;
+ const char * addr = NULL;
+ const char * name = "testdata";
+
+ errlHndl_t err = VFS::module_address(name , addr, size);
+ if (err)
+ {
+ TS_FAIL("module_address failed");
+ ERRORLOG::errlCommit(err,VFS_COMP_ID);
+ }
+
+ name = VFS::module_find_name(addr);
+ TS_TRACE("VFS module @ %p is %s",addr,name);
+
+ if(strcmp(name,"testdata") != 0)
+ {
+ TS_FAIL("VFS find module by address failed!");
+ }
+
+ if(VFS::module_is_loaded(name))
+ {
+ TS_TRACE("VFS module %s is loaded",name);
+ TS_FAIL("VFS module should NOT be loaded");
+ }
+ else
+ {
+ TS_TRACE("VFS module %s is not loaded",name);
+ }
+ }
};
diff --git a/src/usr/vfs/vfsrp.C b/src/usr/vfs/vfsrp.C
index e060c7b80..be9364965 100644
--- a/src/usr/vfs/vfsrp.C
+++ b/src/usr/vfs/vfsrp.C
@@ -263,33 +263,56 @@ void VfsRp::_load_unload(msg_t * i_msg)
{
int rc = 0;
+ // don't want the possibility of a function called in this module
+ // until it's completely loaded and inited, so hold
+ // off any query or other operation.
+ mutex_lock(&iv_mutex);
+
+ ModuleList_t::iterator mod_itr =
+ std::find(iv_loaded.begin(),iv_loaded.end(),module);
+
if(i_msg->type == VFS_MSG_LOAD)
{
- rc = vfs_module_perms(module);
-
- if(!rc)
+ if(mod_itr == iv_loaded.end()) // make sure it's not already loaded
{
- if(module->init)
+ // Set mem access parms
+ rc = vfs_module_perms(module);
+ if(!rc)
{
- (module->init)(NULL);
+ iv_loaded.push_back(module);
+
+ if(module->init)
+ {
+ (module->init)(NULL);
+ }
+
}
}
}
else // unload
{
- if(module->fini)
+ if(mod_itr != iv_loaded.end()) // Loaded
{
- (module->fini)(NULL);
- }
+ iv_loaded.erase(mod_itr);
- rc = mm_set_permission(module->text,
- ALIGN_PAGE(module->byte_count),
- NO_ACCESS);
+ if(module->fini)
+ {
+ (module->fini)(NULL);
+ }
+
+ rc = mm_set_permission(module->text,
+ ALIGN_PAGE(module->byte_count),
+ NO_ACCESS);
- rc = mm_remove_pages(RELEASE,
- module->text,
- ALIGN_PAGE(module->byte_count));
+ rc = mm_remove_pages(RELEASE,
+ module->text,
+ ALIGN_PAGE(module->byte_count));
+ }
+ // else module was not loaded
}
+
+ mutex_unlock(&iv_mutex);
+
if(rc)
{
/*@ errorlog tag
@@ -399,6 +422,57 @@ const VfsSystemModule * VfsRp::get_vfs_info(const char * i_name) const
// ----------------------------------------------------------------------------
+const char * VfsRp::get_name_from_address(const void * i_vaddr) const
+{
+ const char * result = NULL;
+
+ VfsSystemModule * module = vfs_find_address
+ ((VfsSystemModule *)(iv_pnor_vaddr + VFS_EXTENDED_MODULE_TABLE_OFFSET),
+ i_vaddr);
+
+ if(!module) // look in the base modules
+ {
+ module = vfs_find_address(VFS_MODULES,i_vaddr);
+ }
+ if(module)
+ {
+ result = module->module;
+ }
+ return result;
+}
+
+// ----------------------------------------------------------------------------
+
+bool VfsRp::is_module_loaded(const char * i_name)
+{
+ bool result = false;
+ const VfsSystemModule * module = get_vfs_info(i_name);
+ if(module)
+ {
+ mutex_lock(&iv_mutex);
+ ModuleList_t::const_iterator i =
+ std::find(iv_loaded.begin(),iv_loaded.end(),module);
+ if(i != iv_loaded.end())
+ {
+ result = true;
+ }
+ mutex_unlock(&iv_mutex);
+ }
+ if(!result) // look in the base
+ {
+ module = vfs_find_module(VFS_MODULES,i_name);
+ if(module)
+ {
+ // all base modules are always loaded
+ result = true;
+ }
+ }
+
+ return result;
+}
+
+// ----------------------------------------------------------------------------
+
void VfsRp::get_test_modules(std::vector<const char *> & o_list) const
{
o_list.clear();
@@ -518,3 +592,14 @@ errlHndl_t VFS::module_address(const char * i_name, const char *& o_address, siz
return err;
}
+const char * VFS::module_find_name(const void * i_vaddr)
+{
+ return Singleton<VfsRp>::instance().get_name_from_address(i_vaddr);
+}
+
+bool VFS::module_is_loaded(const char * i_name)
+{
+ return Singleton<VfsRp>::instance().is_module_loaded(i_name);
+}
+
+
diff --git a/src/usr/vfs/vfsrp.H b/src/usr/vfs/vfsrp.H
index c5a74c91f..8492f559d 100644
--- a/src/usr/vfs/vfsrp.H
+++ b/src/usr/vfs/vfsrp.H
@@ -27,6 +27,8 @@
#include <builtins.h>
#include <errl/errltypes.H>
#include <sys/msg.h>
+#include <vector>
+#include <sys/sync.h>
struct msg_t;
@@ -68,11 +70,28 @@ namespace VFS
*/
const VfsSystemModule * get_vfs_info(const char * i_name) const;
+ /**
+ * Get the module name that contains the given address
+ * @param[in] i_vaddr The virtual address
+ * @return ptr to the module name or NULL if it's not found
+ */
+ const char * get_name_from_address(const void * i_vaddr) const;
+
+ /**
+ * Query if a module is loaded
+ * @param[in] i_name The module name
+ * @return [true|false]
+ */
+ bool is_module_loaded(const char * i_name);
+
protected:
/**
* Ctor
*/
- VfsRp() : iv_msgQ(NULL), iv_pnor_vaddr(0) {}
+ VfsRp() : iv_msgQ(NULL), iv_pnor_vaddr(0)
+ {
+ mutex_init(&iv_mutex);
+ }
/**
* Dtor
@@ -127,6 +146,11 @@ namespace VFS
msg_q_t iv_msgQ; //!< message queue
uint64_t iv_pnor_vaddr; //!< virtual address of ext image in PFNOR
+
+ typedef std::vector<VfsSystemModule *> ModuleList_t;
+
+ mutex_t iv_mutex; //!< lock for iv_loaded
+ ModuleList_t iv_loaded; //!< Loaded modules
};
}; // VFS namepsace
OpenPOWER on IntegriCloud