@@ -1940,7 +1940,7 @@ static inline void setup_vmalloc_vm(struct vm_struct *vm,
1940
1940
{
1941
1941
vm -> flags = flags ;
1942
1942
vm -> addr = (void * )va -> va_start ;
1943
- vm -> size = va_size (va );
1943
+ vm -> size = vm -> requested_size = va_size (va );
1944
1944
vm -> caller = caller ;
1945
1945
va -> vm = vm ;
1946
1946
}
@@ -3133,6 +3133,7 @@ struct vm_struct *__get_vm_area_node(unsigned long size,
3133
3133
3134
3134
area -> flags = flags ;
3135
3135
area -> caller = caller ;
3136
+ area -> requested_size = requested_size ;
3136
3137
3137
3138
va = alloc_vmap_area (size , align , start , end , node , gfp_mask , 0 , area );
3138
3139
if (IS_ERR (va )) {
@@ -4067,6 +4068,8 @@ EXPORT_SYMBOL(vzalloc_node_noprof);
4067
4068
*/
4068
4069
void * vrealloc_noprof (const void * p , size_t size , gfp_t flags )
4069
4070
{
4071
+ struct vm_struct * vm = NULL ;
4072
+ size_t alloced_size = 0 ;
4070
4073
size_t old_size = 0 ;
4071
4074
void * n ;
4072
4075
@@ -4076,30 +4079,44 @@ void *vrealloc_noprof(const void *p, size_t size, gfp_t flags)
4076
4079
}
4077
4080
4078
4081
if (p ) {
4079
- struct vm_struct * vm ;
4080
-
4081
4082
vm = find_vm_area (p );
4082
4083
if (unlikely (!vm )) {
4083
4084
WARN (1 , "Trying to vrealloc() nonexistent vm area (%p)\n" , p );
4084
4085
return NULL ;
4085
4086
}
4086
4087
4087
- old_size = get_vm_area_size (vm );
4088
+ alloced_size = get_vm_area_size (vm );
4089
+ old_size = vm -> requested_size ;
4090
+ if (WARN (alloced_size < old_size ,
4091
+ "vrealloc() has mismatched area vs requested sizes (%p)\n" , p ))
4092
+ return NULL ;
4088
4093
}
4089
4094
4090
4095
/*
4091
4096
* TODO: Shrink the vm_area, i.e. unmap and free unused pages. What
4092
4097
* would be a good heuristic for when to shrink the vm_area?
4093
4098
*/
4094
4099
if (size <= old_size ) {
4095
- /* Zero out spare memory. */
4096
- if (want_init_on_alloc ( flags ))
4100
+ /* Zero out "freed" memory. */
4101
+ if (want_init_on_free ( ))
4097
4102
memset ((void * )p + size , 0 , old_size - size );
4103
+ vm -> requested_size = size ;
4098
4104
kasan_poison_vmalloc (p + size , old_size - size );
4099
- kasan_unpoison_vmalloc (p , size , KASAN_VMALLOC_PROT_NORMAL );
4100
4105
return (void * )p ;
4101
4106
}
4102
4107
4108
+ /*
4109
+ * We already have the bytes available in the allocation; use them.
4110
+ */
4111
+ if (size <= alloced_size ) {
4112
+ kasan_unpoison_vmalloc (p + old_size , size - old_size ,
4113
+ KASAN_VMALLOC_PROT_NORMAL );
4114
+ /* Zero out "alloced" memory. */
4115
+ if (want_init_on_alloc (flags ))
4116
+ memset ((void * )p + old_size , 0 , size - old_size );
4117
+ vm -> requested_size = size ;
4118
+ }
4119
+
4103
4120
/* TODO: Grow the vm_area, i.e. allocate and map additional pages. */
4104
4121
n = __vmalloc_noprof (size , flags );
4105
4122
if (!n )
0 commit comments