- lib_eq_t *eq = NULL;
- int rc;
- int i;
-
- /* NB we are passed an allocated, but uninitialised/active md.
- * if we return success, caller may lib_md_unlink() it.
- * otherwise caller may only lib_md_free() it.
- */
-
- if (!PtlHandleIsEqual (*eqh, PTL_EQ_NONE)) {
- eq = ptl_handle2eq(eqh, nal);
- if (eq == NULL)
- return PTL_EQ_INVALID;
- }
-
- /* Must check this _before_ allocation. Also, note that non-iov
- * MDs must set md_niov to 0. */
- LASSERT((md->options & (PTL_MD_IOVEC | PTL_MD_KIOV)) == 0 ||
- md->niov <= PTL_MD_MAX_IOV);
-
- /* This implementation doesn't know how to create START events or
- * disable END events. Best to LASSERT our caller is compliant so
- * we find out quickly... */
- LASSERT (PtlHandleIsEqual (*eqh, PTL_EQ_NONE) ||
- ((md->options & PTL_MD_EVENT_START_DISABLE) != 0 &&
- (md->options & PTL_MD_EVENT_END_DISABLE) == 0));
-
- if ((md->options & PTL_MD_MAX_SIZE) != 0 && /* max size used */
- (md->max_size < 0 || md->max_size > md->length)) // illegal max_size
- return PTL_MD_INVALID;
-
- new->me = NULL;
- new->start = md->start;
- new->length = md->length;
- new->offset = 0;
- new->max_size = md->max_size;
- new->options = md->options;
- new->user_ptr = md->user_ptr;
- new->eq = eq;
- new->threshold = md->threshold;
- new->pending = 0;
- new->md_flags = (unlink == PTL_UNLINK) ? PTL_MD_FLAG_AUTO_UNLINK : 0;
-
- if ((md->options & PTL_MD_IOVEC) != 0) {
- int total_length = 0;
-
- if ((md->options & PTL_MD_KIOV) != 0) /* Can't specify both */
- return PTL_MD_INVALID;
-
- new->md_niov = md->niov;
-
- if (nal->cb_read (nal, private, new->md_iov.iov, md->start,
- md->niov * sizeof (new->md_iov.iov[0])))
- return PTL_SEGV;
-
- for (i = 0; i < new->md_niov; i++) {
- /* We take the base address on trust */
- if (new->md_iov.iov[i].iov_len <= 0) /* invalid length */
- return PTL_VAL_FAILED;
-
- total_length += new->md_iov.iov[i].iov_len;
- }
-
- if (md->length > total_length)
- return PTL_IOV_TOO_SMALL;
-
- if (nal->cb_map != NULL) {
- rc = nal->cb_map (nal, new->md_niov, new->md_iov.iov,
- &new->md_addrkey);
- if (rc != PTL_OK)
- return (rc);
- }
- } else if ((md->options & PTL_MD_KIOV) != 0) {
-#ifndef __KERNEL__
- return PTL_MD_INVALID;
+ if (is_vmalloc_addr((void *)vaddr))
+ return vmalloc_to_page((void *)vaddr);
+
+#ifdef CONFIG_HIGHMEM
+
+#ifdef HAVE_KMAP_TO_PAGE
+ /*
+ * This ifdef is added to handle the kernel versions
+ * which have kmap_to_page() function exported. If so,
+ * we should use it. Otherwise, remain with the legacy check.
+ */
+ return kmap_to_page((void *)vaddr);